| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427 |
- // ArduinoJson - arduinojson.org
- // Copyright Benoit Blanchon 2014-2020
- // MIT License
- #pragma once
- #include <stddef.h>
- #include <stdint.h> // for uint8_t
- #include <ArduinoJson/Memory/MemoryPool.hpp>
- #include <ArduinoJson/Misc/Visitable.hpp>
- #include <ArduinoJson/Operators/VariantOperators.hpp>
- #include <ArduinoJson/Polyfills/type_traits.hpp>
- #include <ArduinoJson/Variant/VariantAs.hpp>
- #include <ArduinoJson/Variant/VariantFunctions.hpp>
- #include <ArduinoJson/Variant/VariantRef.hpp>
- namespace ARDUINOJSON_NAMESPACE {
- // Forward declarations.
- class ArrayRef;
- class ObjectRef;
- template <typename, typename>
- class MemberProxy;
- // Contains the methods shared by VariantRef and VariantConstRef
- template <typename TData>
- class VariantRefBase {
- public:
- // Tells wether the variant has the specified type.
- // Returns true if the variant has type type T, false otherwise.
- //
- // bool is<char>() const;
- // bool is<signed char>() const;
- // bool is<signed short>() const;
- // bool is<signed int>() const;
- // bool is<signed long>() const;
- // bool is<unsigned char>() const;
- // bool is<unsigned short>() const;
- // bool is<unsigned int>() const;
- // bool is<unsigned long>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_integral<T>::value, bool>::type is()
- const {
- return variantIsInteger<T>(_data);
- }
- //
- // bool is<double>() const;
- // bool is<float>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_floating_point<T>::value, bool>::type is()
- const {
- return variantIsFloat(_data);
- }
- //
- // bool is<bool>() const
- template <typename T>
- FORCE_INLINE typename enable_if<is_same<T, bool>::value, bool>::type is()
- const {
- return variantIsBoolean(_data);
- }
- //
- // bool is<const char*>() const;
- // bool is<char*>() const;
- // bool is<std::string>() const;
- // bool is<String>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_same<T, const char *>::value ||
- is_same<T, char *>::value ||
- IsWriteableString<T>::value,
- bool>::type
- is() const {
- return variantIsString(_data);
- }
- //
- // bool is<ArrayRef> const;
- // bool is<const ArrayRef> const;
- template <typename T>
- FORCE_INLINE typename enable_if<
- is_same<typename remove_const<T>::type, ArrayRef>::value, bool>::type
- is() const {
- return variantIsArray(_data);
- }
- //
- // bool is<ObjectRef> const;
- // bool is<const ObjectRef> const;
- template <typename T>
- FORCE_INLINE typename enable_if<
- is_same<typename remove_const<T>::type, ObjectRef>::value, bool>::type
- is() const {
- return variantIsObject(_data);
- }
- #if ARDUINOJSON_HAS_NULLPTR
- //
- // bool is<nullptr_t> const;
- template <typename T>
- FORCE_INLINE
- typename enable_if<is_same<T, decltype(nullptr)>::value, bool>::type
- is() const {
- return variantIsNull(_data);
- }
- #endif
- FORCE_INLINE bool isNull() const {
- return variantIsNull(_data);
- }
- FORCE_INLINE bool isUndefined() const {
- return !_data;
- }
- FORCE_INLINE size_t memoryUsage() const {
- return _data ? _data->memoryUsage() : 0;
- }
- FORCE_INLINE size_t nesting() const {
- return _data ? _data->nesting() : 0;
- }
- size_t size() const {
- return variantSize(_data);
- }
- protected:
- VariantRefBase(TData *data) : _data(data) {}
- TData *_data;
- };
- // A variant that can be a any value serializable to a JSON value.
- //
- // It can be set to:
- // - a boolean
- // - a char, short, int or a long (signed or unsigned)
- // - a string (const char*)
- // - a reference to a ArrayRef or ObjectRef
- class VariantRef : public VariantRefBase<VariantData>,
- public VariantOperators<VariantRef>,
- public Visitable {
- typedef VariantRefBase<VariantData> base_type;
- friend class VariantConstRef;
- public:
- // Intenal use only
- FORCE_INLINE VariantRef(MemoryPool *pool, VariantData *data)
- : base_type(data), _pool(pool) {}
- // Creates an uninitialized VariantRef
- FORCE_INLINE VariantRef() : base_type(0), _pool(0) {}
- FORCE_INLINE void clear() const {
- return variantSetNull(_data);
- }
- // set(bool value)
- FORCE_INLINE bool set(bool value) const {
- return variantSetBoolean(_data, value);
- }
- // set(double value);
- // set(float value);
- template <typename T>
- FORCE_INLINE bool set(
- T value,
- typename enable_if<is_floating_point<T>::value>::type * = 0) const {
- return variantSetFloat(_data, static_cast<Float>(value));
- }
- // set(char)
- // set(signed short)
- // set(signed int)
- // set(signed long)
- // set(signed char)
- template <typename T>
- FORCE_INLINE bool set(
- T value,
- typename enable_if<is_integral<T>::value && is_signed<T>::value>::type * =
- 0) const {
- return variantSetSignedInteger(_data, value);
- }
- // set(unsigned short)
- // set(unsigned int)
- // set(unsigned long)
- template <typename T>
- FORCE_INLINE bool set(
- T value, typename enable_if<is_integral<T>::value &&
- is_unsigned<T>::value>::type * = 0) const {
- return variantSetUnsignedInteger(_data, static_cast<UInt>(value));
- }
- // set(SerializedValue<const char *>)
- FORCE_INLINE bool set(SerializedValue<const char *> value) const {
- return variantSetLinkedRaw(_data, value);
- }
- // set(SerializedValue<std::string>)
- // set(SerializedValue<String>)
- // set(SerializedValue<const __FlashStringHelper*>)
- template <typename T>
- FORCE_INLINE bool set(
- SerializedValue<T> value,
- typename enable_if<!is_same<const char *, T>::value>::type * = 0) const {
- return variantSetOwnedRaw(_data, value, _pool);
- }
- // set(const std::string&)
- // set(const String&)
- template <typename T>
- FORCE_INLINE bool set(
- const T &value,
- typename enable_if<IsString<T>::value>::type * = 0) const {
- return variantSetOwnedString(_data, adaptString(value), _pool);
- }
- // set(char*)
- // set(const __FlashStringHelper*)
- template <typename T>
- FORCE_INLINE bool set(
- T *value, typename enable_if<IsString<T *>::value>::type * = 0) const {
- return variantSetOwnedString(_data, adaptString(value), _pool);
- }
- // set(const char*);
- FORCE_INLINE bool set(const char *value) const {
- return variantSetLinkedString(_data, value);
- }
- // set(VariantRef)
- // set(VariantConstRef)
- // set(ArrayRef)
- // set(ArrayConstRef)
- // set(ObjectRef)
- // set(ObjecConstRef)
- // set(const JsonDocument&)
- template <typename TVariant>
- typename enable_if<IsVisitable<TVariant>::value, bool>::type set(
- const TVariant &value) const;
- // Get the variant as the specified type.
- //
- // std::string as<std::string>() const;
- // String as<String>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<!is_same<T, ArrayRef>::value &&
- !is_same<T, ObjectRef>::value &&
- !is_same<T, VariantRef>::value,
- typename VariantAs<T>::type>::type
- as() const {
- return variantAs<T>(_data);
- }
- //
- // ArrayRef as<ArrayRef>() const;
- // const ArrayRef as<const ArrayRef>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_same<T, ArrayRef>::value, T>::type as()
- const;
- //
- // ObjectRef as<ObjectRef>() const;
- // const ObjectRef as<const ObjectRef>() const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_same<T, ObjectRef>::value, T>::type as()
- const;
- //
- // VariantRef as<VariantRef> const;
- template <typename T>
- FORCE_INLINE typename enable_if<is_same<T, VariantRef>::value, T>::type as()
- const {
- return *this;
- }
- template <typename Visitor>
- void accept(Visitor &visitor) const {
- variantAccept(_data, visitor);
- }
- FORCE_INLINE bool operator==(VariantRef lhs) const {
- return variantEquals(_data, lhs._data);
- }
- FORCE_INLINE bool operator!=(VariantRef lhs) const {
- return !variantEquals(_data, lhs._data);
- }
- // Change the type of the variant
- //
- // ArrayRef to<ArrayRef>()
- template <typename T>
- typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type to() const;
- //
- // ObjectRef to<ObjectRef>()
- template <typename T>
- typename enable_if<is_same<T, ObjectRef>::value, ObjectRef>::type to() const;
- //
- // ObjectRef to<VariantRef>()
- template <typename T>
- typename enable_if<is_same<T, VariantRef>::value, VariantRef>::type to()
- const;
- VariantRef addElement() const;
- FORCE_INLINE VariantRef getElement(size_t) const;
- FORCE_INLINE VariantRef getOrAddElement(size_t) const;
- // getMember(const char*) const
- // getMember(const __FlashStringHelper*) const
- template <typename TChar>
- FORCE_INLINE VariantRef getMember(TChar *) const;
- // getMember(const std::string&) const
- // getMember(const String&) const
- template <typename TString>
- FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
- getMember(const TString &) const;
- // getOrAddMember(char*) const
- // getOrAddMember(const char*) const
- // getOrAddMember(const __FlashStringHelper*) const
- template <typename TChar>
- FORCE_INLINE VariantRef getOrAddMember(TChar *) const;
- // getOrAddMember(const std::string&) const
- // getOrAddMember(const String&) const
- template <typename TString>
- FORCE_INLINE VariantRef getOrAddMember(const TString &) const;
- FORCE_INLINE void remove(size_t index) const {
- if (_data)
- _data->remove(index);
- }
- // remove(char*) const
- // remove(const char*) const
- // remove(const __FlashStringHelper*) const
- template <typename TChar>
- FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
- TChar *key) const {
- if (_data)
- _data->remove(adaptString(key));
- }
- // remove(const std::string&) const
- // remove(const String&) const
- template <typename TString>
- FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
- const TString &key) const {
- if (_data)
- _data->remove(adaptString(key));
- }
- private:
- MemoryPool *_pool;
- }; // namespace ARDUINOJSON_NAMESPACE
- class VariantConstRef : public VariantRefBase<const VariantData>,
- public VariantOperators<VariantConstRef>,
- public Visitable {
- typedef VariantRefBase<const VariantData> base_type;
- friend class VariantRef;
- public:
- VariantConstRef() : base_type(0) {}
- VariantConstRef(const VariantData *data) : base_type(data) {}
- VariantConstRef(VariantRef var) : base_type(var._data) {}
- template <typename Visitor>
- void accept(Visitor &visitor) const {
- variantAccept(_data, visitor);
- }
- // Get the variant as the specified type.
- //
- template <typename T>
- FORCE_INLINE typename VariantConstAs<T>::type as() const {
- return variantAs<typename VariantConstAs<T>::type>(_data);
- }
- FORCE_INLINE VariantConstRef getElement(size_t) const;
- FORCE_INLINE VariantConstRef operator[](size_t index) const {
- return getElement(index);
- }
- // getMember(const std::string&) const
- // getMember(const String&) const
- template <typename TString>
- FORCE_INLINE VariantConstRef getMember(const TString &key) const {
- return VariantConstRef(
- objectGetMember(variantAsObject(_data), adaptString(key)));
- }
- // getMember(char*) const
- // getMember(const char*) const
- // getMember(const __FlashStringHelper*) const
- template <typename TChar>
- FORCE_INLINE VariantConstRef getMember(TChar *key) const {
- const CollectionData *obj = variantAsObject(_data);
- return VariantConstRef(obj ? obj->getMember(adaptString(key)) : 0);
- }
- // operator[](const std::string&) const
- // operator[](const String&) const
- template <typename TString>
- FORCE_INLINE
- typename enable_if<IsString<TString>::value, VariantConstRef>::type
- operator[](const TString &key) const {
- return getMember(key);
- }
- // operator[](char*) const
- // operator[](const char*) const
- // operator[](const __FlashStringHelper*) const
- template <typename TChar>
- FORCE_INLINE
- typename enable_if<IsString<TChar *>::value, VariantConstRef>::type
- operator[](TChar *key) const {
- return getMember(key);
- }
- FORCE_INLINE bool operator==(VariantConstRef lhs) const {
- return variantEquals(_data, lhs._data);
- }
- FORCE_INLINE bool operator!=(VariantConstRef lhs) const {
- return !variantEquals(_data, lhs._data);
- }
- };
- } // namespace ARDUINOJSON_NAMESPACE
|