// ArduinoJson - arduinojson.org // Copyright Benoit Blanchon 2014-2020 // MIT License #pragma once #include #include // for uint8_t #include #include #include #include #include #include #include namespace ARDUINOJSON_NAMESPACE { // Forward declarations. class ArrayRef; class ObjectRef; template class MemberProxy; // Contains the methods shared by VariantRef and VariantConstRef template class VariantRefBase { public: // Tells wether the variant has the specified type. // Returns true if the variant has type type T, false otherwise. // // bool is() const; // bool is() const; // bool is() const; // bool is() const; // bool is() const; // bool is() const; // bool is() const; // bool is() const; // bool is() const; template FORCE_INLINE typename enable_if::value, bool>::type is() const { return variantIsInteger(_data); } // // bool is() const; // bool is() const; template FORCE_INLINE typename enable_if::value, bool>::type is() const { return variantIsFloat(_data); } // // bool is() const template FORCE_INLINE typename enable_if::value, bool>::type is() const { return variantIsBoolean(_data); } // // bool is() const; // bool is() const; // bool is() const; // bool is() const; template FORCE_INLINE typename enable_if::value || is_same::value || IsWriteableString::value, bool>::type is() const { return variantIsString(_data); } // // bool is const; // bool is const; template FORCE_INLINE typename enable_if< is_same::type, ArrayRef>::value, bool>::type is() const { return variantIsArray(_data); } // // bool is const; // bool is const; template FORCE_INLINE typename enable_if< is_same::type, ObjectRef>::value, bool>::type is() const { return variantIsObject(_data); } #if ARDUINOJSON_HAS_NULLPTR // // bool is const; template FORCE_INLINE typename enable_if::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, public VariantOperators, public Visitable { typedef VariantRefBase 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 FORCE_INLINE bool set( T value, typename enable_if::value>::type * = 0) const { return variantSetFloat(_data, static_cast(value)); } // set(char) // set(signed short) // set(signed int) // set(signed long) // set(signed char) template FORCE_INLINE bool set( T value, typename enable_if::value && is_signed::value>::type * = 0) const { return variantSetSignedInteger(_data, value); } // set(unsigned short) // set(unsigned int) // set(unsigned long) template FORCE_INLINE bool set( T value, typename enable_if::value && is_unsigned::value>::type * = 0) const { return variantSetUnsignedInteger(_data, static_cast(value)); } // set(SerializedValue) FORCE_INLINE bool set(SerializedValue value) const { return variantSetLinkedRaw(_data, value); } // set(SerializedValue) // set(SerializedValue) // set(SerializedValue) template FORCE_INLINE bool set( SerializedValue value, typename enable_if::value>::type * = 0) const { return variantSetOwnedRaw(_data, value, _pool); } // set(const std::string&) // set(const String&) template FORCE_INLINE bool set( const T &value, typename enable_if::value>::type * = 0) const { return variantSetOwnedString(_data, adaptString(value), _pool); } // set(char*) // set(const __FlashStringHelper*) template FORCE_INLINE bool set( T *value, typename enable_if::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 enable_if::value, bool>::type set( const TVariant &value) const; // Get the variant as the specified type. // // std::string as() const; // String as() const; template FORCE_INLINE typename enable_if::value && !is_same::value && !is_same::value, typename VariantAs::type>::type as() const { return variantAs(_data); } // // ArrayRef as() const; // const ArrayRef as() const; template FORCE_INLINE typename enable_if::value, T>::type as() const; // // ObjectRef as() const; // const ObjectRef as() const; template FORCE_INLINE typename enable_if::value, T>::type as() const; // // VariantRef as const; template FORCE_INLINE typename enable_if::value, T>::type as() const { return *this; } template 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() template typename enable_if::value, ArrayRef>::type to() const; // // ObjectRef to() template typename enable_if::value, ObjectRef>::type to() const; // // ObjectRef to() template typename enable_if::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 FORCE_INLINE VariantRef getMember(TChar *) const; // getMember(const std::string&) const // getMember(const String&) const template FORCE_INLINE typename enable_if::value, VariantRef>::type getMember(const TString &) const; // getOrAddMember(char*) const // getOrAddMember(const char*) const // getOrAddMember(const __FlashStringHelper*) const template FORCE_INLINE VariantRef getOrAddMember(TChar *) const; // getOrAddMember(const std::string&) const // getOrAddMember(const String&) const template 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 FORCE_INLINE typename enable_if::value>::type remove( TChar *key) const { if (_data) _data->remove(adaptString(key)); } // remove(const std::string&) const // remove(const String&) const template FORCE_INLINE typename enable_if::value>::type remove( const TString &key) const { if (_data) _data->remove(adaptString(key)); } private: MemoryPool *_pool; }; // namespace ARDUINOJSON_NAMESPACE class VariantConstRef : public VariantRefBase, public VariantOperators, public Visitable { typedef VariantRefBase 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 void accept(Visitor &visitor) const { variantAccept(_data, visitor); } // Get the variant as the specified type. // template FORCE_INLINE typename VariantConstAs::type as() const { return variantAs::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 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 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 FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](const TString &key) const { return getMember(key); } // operator[](char*) const // operator[](const char*) const // operator[](const __FlashStringHelper*) const template FORCE_INLINE typename enable_if::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