Minh Nguyen / ArduinoJson
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ObjectRef.hpp Source File

ObjectRef.hpp

00001 // ArduinoJson - arduinojson.org
00002 // Copyright Benoit Blanchon 2014-2021
00003 // MIT License
00004 
00005 #pragma once
00006 
00007 #include <ArduinoJson/Object/ObjectFunctions.hpp>
00008 #include <ArduinoJson/Object/ObjectIterator.hpp>
00009 
00010 // Returns the size (in bytes) of an object with n elements.
00011 // Can be very handy to determine the size of a StaticMemoryPool.
00012 #define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
00013   ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
00014 
00015 namespace ARDUINOJSON_NAMESPACE {
00016 
00017 template <typename TData>
00018 class ObjectRefBase {
00019  public:
00020   operator VariantConstRef() const {
00021     const void* data = _data;  // prevent warning cast-align
00022     return VariantConstRef(reinterpret_cast<const VariantData*>(data));
00023   }
00024 
00025   template <typename TVisitor>
00026   typename TVisitor::result_type accept(TVisitor& visitor) const {
00027     return objectAccept(_data, visitor);
00028   }
00029 
00030   FORCE_INLINE bool isNull() const {
00031     return _data == 0;
00032   }
00033 
00034   FORCE_INLINE operator bool() const {
00035     return _data != 0;
00036   }
00037 
00038   FORCE_INLINE size_t memoryUsage() const {
00039     return _data ? _data->memoryUsage() : 0;
00040   }
00041 
00042   FORCE_INLINE size_t nesting() const {
00043     return _data ? _data->nesting() : 0;
00044   }
00045 
00046   FORCE_INLINE size_t size() const {
00047     return _data ? _data->size() : 0;
00048   }
00049 
00050  protected:
00051   ObjectRefBase(TData* data) : _data(data) {}
00052   TData* _data;
00053 };
00054 
00055 class ObjectConstRef : public ObjectRefBase<const CollectionData>,
00056                        public Visitable {
00057   friend class ObjectRef;
00058   typedef ObjectRefBase<const CollectionData> base_type;
00059 
00060  public:
00061   typedef ObjectConstIterator iterator;
00062 
00063   ObjectConstRef() : base_type(0) {}
00064   ObjectConstRef(const CollectionData* data) : base_type(data) {}
00065 
00066   FORCE_INLINE iterator begin() const {
00067     if (!_data)
00068       return iterator();
00069     return iterator(_data->head());
00070   }
00071 
00072   FORCE_INLINE iterator end() const {
00073     return iterator();
00074   }
00075 
00076   // containsKey(const std::string&) const
00077   // containsKey(const String&) const
00078   template <typename TString>
00079   FORCE_INLINE bool containsKey(const TString& key) const {
00080     return !getMember(key).isUndefined();
00081   }
00082 
00083   // containsKey(char*) const
00084   // containsKey(const char*) const
00085   // containsKey(const __FlashStringHelper*) const
00086   template <typename TChar>
00087   FORCE_INLINE bool containsKey(TChar* key) const {
00088     return !getMember(key).isUndefined();
00089   }
00090 
00091   // getMember(const std::string&) const
00092   // getMember(const String&) const
00093   template <typename TString>
00094   FORCE_INLINE VariantConstRef getMember(const TString& key) const {
00095     return get_impl(adaptString(key));
00096   }
00097 
00098   // getMember(char*) const
00099   // getMember(const char*) const
00100   // getMember(const __FlashStringHelper*) const
00101   template <typename TChar>
00102   FORCE_INLINE VariantConstRef getMember(TChar* key) const {
00103     return get_impl(adaptString(key));
00104   }
00105 
00106   // operator[](const std::string&) const
00107   // operator[](const String&) const
00108   template <typename TString>
00109   FORCE_INLINE
00110       typename enable_if<IsString<TString>::value, VariantConstRef>::type
00111       operator[](const TString& key) const {
00112     return get_impl(adaptString(key));
00113   }
00114 
00115   // operator[](char*) const
00116   // operator[](const char*) const
00117   // operator[](const __FlashStringHelper*) const
00118   template <typename TChar>
00119   FORCE_INLINE
00120       typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
00121       operator[](TChar* key) const {
00122     return get_impl(adaptString(key));
00123   }
00124 
00125   FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
00126     return objectEquals(_data, rhs._data);
00127   }
00128 
00129  private:
00130   template <typename TAdaptedString>
00131   FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
00132     return VariantConstRef(objectGetMember(_data, key));
00133   }
00134 };
00135 
00136 class ObjectRef : public ObjectRefBase<CollectionData>,
00137                   public ObjectShortcuts<ObjectRef>,
00138                   public Visitable {
00139   typedef ObjectRefBase<CollectionData> base_type;
00140 
00141  public:
00142   typedef ObjectIterator iterator;
00143 
00144   FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {}
00145   FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data)
00146       : base_type(data), _pool(buf) {}
00147 
00148   operator VariantRef() const {
00149     void* data = _data;  // prevent warning cast-align
00150     return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
00151   }
00152 
00153   operator ObjectConstRef() const {
00154     return ObjectConstRef(_data);
00155   }
00156 
00157   FORCE_INLINE iterator begin() const {
00158     if (!_data)
00159       return iterator();
00160     return iterator(_pool, _data->head());
00161   }
00162 
00163   FORCE_INLINE iterator end() const {
00164     return iterator();
00165   }
00166 
00167   void clear() const {
00168     if (!_data)
00169       return;
00170     _data->clear();
00171   }
00172 
00173   FORCE_INLINE bool set(ObjectConstRef src) {
00174     if (!_data || !src._data)
00175       return false;
00176     return _data->copyFrom(*src._data, _pool);
00177   }
00178 
00179   // getMember(const std::string&) const
00180   // getMember(const String&) const
00181   template <typename TString>
00182   FORCE_INLINE VariantRef getMember(const TString& key) const {
00183     return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
00184   }
00185 
00186   // getMember(char*) const
00187   // getMember(const char*) const
00188   // getMember(const __FlashStringHelper*) const
00189   template <typename TChar>
00190   FORCE_INLINE VariantRef getMember(TChar* key) const {
00191     return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
00192   }
00193 
00194   // getOrAddMember(const std::string&) const
00195   // getOrAddMember(const String&) const
00196   template <typename TString>
00197   FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
00198     return VariantRef(_pool,
00199                       objectGetOrAddMember(_data, adaptString(key), _pool));
00200   }
00201 
00202   // getOrAddMember(char*) const
00203   // getOrAddMember(const char*) const
00204   // getOrAddMember(const __FlashStringHelper*) const
00205   template <typename TChar>
00206   FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
00207     return VariantRef(_pool,
00208                       objectGetOrAddMember(_data, adaptString(key), _pool));
00209   }
00210 
00211   FORCE_INLINE bool operator==(ObjectRef rhs) const {
00212     return objectEquals(_data, rhs._data);
00213   }
00214 
00215   FORCE_INLINE void remove(iterator it) const {
00216     if (!_data)
00217       return;
00218     _data->removeSlot(it.internal());
00219   }
00220 
00221   // remove(const std::string&) const
00222   // remove(const String&) const
00223   template <typename TString>
00224   FORCE_INLINE void remove(const TString& key) const {
00225     objectRemove(_data, adaptString(key));
00226   }
00227 
00228   // remove(char*) const
00229   // remove(const char*) const
00230   // remove(const __FlashStringHelper*) const
00231   template <typename TChar>
00232   FORCE_INLINE void remove(TChar* key) const {
00233     objectRemove(_data, adaptString(key));
00234   }
00235 
00236  private:
00237   MemoryPool* _pool;
00238 };
00239 }  // namespace ARDUINOJSON_NAMESPACE