// ArduinoJson - https://arduinojson.org // Copyright Benoit Blanchon 2014-2021 // MIT License #pragma once #include #include // Returns the size (in bytes) of an object with n elements. // Can be very handy to determine the size of a StaticMemoryPool. #define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \ ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot)) namespace ARDUINOJSON_NAMESPACE { template class ObjectRefBase { public: operator VariantConstRef() const { const void* data = _data; // prevent warning cast-align return VariantConstRef(reinterpret_cast(data)); } template typename TVisitor::result_type accept(TVisitor& visitor) const { return objectAccept(_data, visitor); } FORCE_INLINE bool isNull() const { return _data == 0; } FORCE_INLINE operator bool() const { return _data != 0; } FORCE_INLINE size_t memoryUsage() const { return _data ? _data->memoryUsage() : 0; } FORCE_INLINE size_t nesting() const { return _data ? _data->nesting() : 0; } FORCE_INLINE size_t size() const { return _data ? _data->size() : 0; } protected: ObjectRefBase(TData* data) : _data(data) {} TData* _data; }; class ObjectConstRef : public ObjectRefBase, public Visitable { friend class ObjectRef; typedef ObjectRefBase base_type; public: typedef ObjectConstIterator iterator; ObjectConstRef() : base_type(0) {} ObjectConstRef(const CollectionData* data) : base_type(data) {} FORCE_INLINE iterator begin() const { if (!_data) return iterator(); return iterator(_data->head()); } FORCE_INLINE iterator end() const { return iterator(); } // containsKey(const std::string&) const // containsKey(const String&) const template FORCE_INLINE bool containsKey(const TString& key) const { return !getMember(key).isUndefined(); } // containsKey(char*) const // containsKey(const char*) const // containsKey(const __FlashStringHelper*) const template FORCE_INLINE bool containsKey(TChar* key) const { return !getMember(key).isUndefined(); } // getMember(const std::string&) const // getMember(const String&) const template FORCE_INLINE VariantConstRef getMember(const TString& key) const { return get_impl(adaptString(key)); } // getMember(char*) const // getMember(const char*) const // getMember(const __FlashStringHelper*) const template FORCE_INLINE VariantConstRef getMember(TChar* key) const { return get_impl(adaptString(key)); } // operator[](const std::string&) const // operator[](const String&) const template FORCE_INLINE typename enable_if::value, VariantConstRef>::type operator[](const TString& key) const { return get_impl(adaptString(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 get_impl(adaptString(key)); } FORCE_INLINE bool operator==(ObjectConstRef rhs) const { return objectEquals(_data, rhs._data); } private: template FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const { return VariantConstRef(objectGetMember(_data, key)); } }; class ObjectRef : public ObjectRefBase, public ObjectShortcuts, public Visitable { typedef ObjectRefBase base_type; public: typedef ObjectIterator iterator; FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {} FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data) : base_type(data), _pool(buf) {} operator VariantRef() const { void* data = _data; // prevent warning cast-align return VariantRef(_pool, reinterpret_cast(data)); } operator ObjectConstRef() const { return ObjectConstRef(_data); } FORCE_INLINE iterator begin() const { if (!_data) return iterator(); return iterator(_pool, _data->head()); } FORCE_INLINE iterator end() const { return iterator(); } void clear() const { if (!_data) return; _data->clear(); } FORCE_INLINE bool set(ObjectConstRef src) { if (!_data || !src._data) return false; return _data->copyFrom(*src._data, _pool); } // getMember(const std::string&) const // getMember(const String&) const template FORCE_INLINE VariantRef getMember(const TString& key) const { return VariantRef(_pool, objectGetMember(_data, adaptString(key))); } // getMember(char*) const // getMember(const char*) const // getMember(const __FlashStringHelper*) const template FORCE_INLINE VariantRef getMember(TChar* key) const { return VariantRef(_pool, objectGetMember(_data, adaptString(key))); } // getOrAddMember(const std::string&) const // getOrAddMember(const String&) const template FORCE_INLINE VariantRef getOrAddMember(const TString& key) const { return VariantRef(_pool, objectGetOrAddMember(_data, adaptString(key), _pool)); } // getOrAddMember(char*) const // getOrAddMember(const char*) const // getOrAddMember(const __FlashStringHelper*) const template FORCE_INLINE VariantRef getOrAddMember(TChar* key) const { return VariantRef(_pool, objectGetOrAddMember(_data, adaptString(key), _pool)); } FORCE_INLINE bool operator==(ObjectRef rhs) const { return objectEquals(_data, rhs._data); } FORCE_INLINE void remove(iterator it) const { if (!_data) return; _data->removeSlot(it.internal()); } // remove(const std::string&) const // remove(const String&) const template FORCE_INLINE void remove(const TString& key) const { objectRemove(_data, adaptString(key)); } // remove(char*) const // remove(const char*) const // remove(const __FlashStringHelper*) const template FORCE_INLINE void remove(TChar* key) const { objectRemove(_data, adaptString(key)); } private: MemoryPool* _pool; }; template <> struct Converter { static bool toJson(VariantConstRef src, VariantRef dst) { return variantCopyFrom(getData(dst), getData(src), getPool(dst)); } static ObjectConstRef fromJson(VariantConstRef src) { return ObjectConstRef(variantAsObject(getData(src))); } static bool checkJson(VariantConstRef src) { const VariantData* data = getData(src); return data && data->isObject(); } }; template <> struct Converter { static bool toJson(VariantConstRef src, VariantRef dst) { return variantCopyFrom(getData(dst), getData(src), getPool(dst)); } static ObjectRef fromJson(VariantRef src) { VariantData* data = getData(src); MemoryPool* pool = getPool(src); return ObjectRef(pool, data != 0 ? data->asObject() : 0); } static bool checkJson(VariantConstRef) { return false; } static bool checkJson(VariantRef src) { VariantData* data = getData(src); return data && data->isObject(); } }; } // namespace ARDUINOJSON_NAMESPACE