mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Add VariantAttorney
				
					
				
			This commit is contained in:
		| @@ -6,6 +6,7 @@ | ||||
|  | ||||
| #include <ArduinoJson/Array/ArrayFunctions.hpp> | ||||
| #include <ArduinoJson/Array/ArrayIterator.hpp> | ||||
| #include <ArduinoJson/Variant/VariantAttorney.hpp> | ||||
| #include <ArduinoJson/Variant/VariantData.hpp> | ||||
|  | ||||
| // Returns the size (in bytes) of an array with n elements. | ||||
| @@ -105,6 +106,8 @@ class ArrayRef : public ArrayRefBase<CollectionData>, | ||||
|                  public VariantOperators<ArrayRef> { | ||||
|   typedef ArrayRefBase<CollectionData> base_type; | ||||
|  | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   typedef ArrayIterator iterator; | ||||
|  | ||||
| @@ -168,6 +171,7 @@ class ArrayRef : public ArrayRefBase<CollectionData>, | ||||
|     _data->clear(); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   MemoryPool* getPool() const { | ||||
|     return _pool; | ||||
|   } | ||||
| @@ -185,7 +189,7 @@ class ArrayRef : public ArrayRefBase<CollectionData>, | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<ArrayConstRef> { | ||||
| struct Converter<ArrayConstRef> : private VariantAttorney { | ||||
|   static void toJson(VariantConstRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
| @@ -202,7 +206,7 @@ struct Converter<ArrayConstRef> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<ArrayRef> { | ||||
| struct Converter<ArrayRef> : private VariantAttorney { | ||||
|   static void toJson(VariantConstRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
|   | ||||
| @@ -22,6 +22,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >, | ||||
|                      public VariantTag { | ||||
|   typedef ElementProxy<TArray> this_type; | ||||
|  | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   FORCE_INLINE ElementProxy(TArray array, size_t index) | ||||
|       : _array(array), _index(index) {} | ||||
| @@ -160,17 +162,18 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >, | ||||
|     getUpstreamElement().remove(key); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   FORCE_INLINE MemoryPool* getPool() const { | ||||
|     return _array.getPool(); | ||||
|     return VariantAttorney::getPool(_array); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData* getData() const { | ||||
|     return variantGetElement(_array.getData(), _index); | ||||
|     return variantGetElement(VariantAttorney::getData(_array), _index); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData* getOrCreateData() const { | ||||
|     return variantGetOrAddElement(_array.getOrCreateData(), _index, | ||||
|                                   _array.getPool()); | ||||
|     return variantGetOrAddElement(VariantAttorney::getOrCreateData(_array), | ||||
|                                   _index, VariantAttorney::getPool(_array)); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   | ||||
| @@ -15,6 +15,8 @@ | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| class JsonDocument : public VariantOperators<const JsonDocument&> { | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   template <typename T> | ||||
|   T as() { | ||||
| @@ -268,7 +270,7 @@ class JsonDocument : public VariantOperators<const JsonDocument&> { | ||||
|   JsonDocument(const JsonDocument&); | ||||
|   JsonDocument& operator=(const JsonDocument&); | ||||
|  | ||||
|  public: | ||||
|  protected: | ||||
|   MemoryPool* getPool() { | ||||
|     return &_pool; | ||||
|   } | ||||
|   | ||||
| @@ -25,6 +25,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | ||||
|                     public VariantTag { | ||||
|   typedef MemberProxy<TObject, TStringRef> this_type; | ||||
|  | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   FORCE_INLINE MemberProxy(TObject variant, TStringRef key) | ||||
|       : _object(variant), _key(key) {} | ||||
| @@ -160,17 +162,19 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | ||||
|  | ||||
|   using ArrayShortcuts<MemberProxy<TObject, TStringRef> >::add; | ||||
|  | ||||
|  protected: | ||||
|   FORCE_INLINE MemoryPool *getPool() const { | ||||
|     return _object.getPool(); | ||||
|     return VariantAttorney::getPool(_object); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData *getData() const { | ||||
|     return variantGetMember(_object.getData(), adaptString(_key)); | ||||
|     return variantGetMember(VariantAttorney::getData(_object), | ||||
|                             adaptString(_key)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantData *getOrCreateData() const { | ||||
|     return variantGetOrAddMember(_object.getOrCreateData(), _key, | ||||
|                                  _object.getPool()); | ||||
|     return variantGetOrAddMember(VariantAttorney::getOrCreateData(_object), | ||||
|                                  _key, VariantAttorney::getPool(_object)); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   | ||||
| @@ -40,14 +40,16 @@ template <typename TObject> | ||||
| template <typename TString> | ||||
| inline typename enable_if<IsString<TString>::value, bool>::type | ||||
| ObjectShortcuts<TObject>::containsKey(const TString& key) const { | ||||
|   return variantGetMember(impl()->getData(), adaptString(key)) != 0; | ||||
|   return variantGetMember(VariantAttorney::getData(*impl()), | ||||
|                           adaptString(key)) != 0; | ||||
| } | ||||
|  | ||||
| template <typename TObject> | ||||
| template <typename TChar> | ||||
| inline typename enable_if<IsString<TChar*>::value, bool>::type | ||||
| ObjectShortcuts<TObject>::containsKey(TChar* key) const { | ||||
|   return variantGetMember(impl()->getData(), adaptString(key)) != 0; | ||||
|   return variantGetMember(VariantAttorney::getData(*impl()), | ||||
|                           adaptString(key)) != 0; | ||||
| } | ||||
|  | ||||
| template <typename TObject> | ||||
|   | ||||
| @@ -125,6 +125,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
|                   public VariantOperators<ObjectRef> { | ||||
|   typedef ObjectRefBase<CollectionData> base_type; | ||||
|  | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   typedef ObjectIterator iterator; | ||||
|  | ||||
| @@ -188,6 +190,7 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
|     objectRemove(_data, adaptString(key)); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   MemoryPool* getPool() const { | ||||
|     return _pool; | ||||
|   } | ||||
| @@ -205,7 +208,7 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<ObjectConstRef> { | ||||
| struct Converter<ObjectConstRef> : private VariantAttorney { | ||||
|   static void toJson(VariantConstRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
| @@ -222,7 +225,7 @@ struct Converter<ObjectConstRef> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<ObjectRef> { | ||||
| struct Converter<ObjectRef> : private VariantAttorney { | ||||
|   static void toJson(VariantConstRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
|   | ||||
| @@ -13,7 +13,7 @@ template <template <typename> class TSerializer> | ||||
| size_t measure(VariantConstRef source) { | ||||
|   DummyWriter dp; | ||||
|   TSerializer<DummyWriter> serializer(dp); | ||||
|   return variantAccept(getData(source), serializer); | ||||
|   return variantAccept(VariantAttorney::getData(source), serializer); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -12,7 +12,7 @@ namespace ARDUINOJSON_NAMESPACE { | ||||
| template <template <typename> class TSerializer, typename TWriter> | ||||
| size_t doSerialize(VariantConstRef source, TWriter writer) { | ||||
|   TSerializer<TWriter> serializer(writer); | ||||
|   return variantAccept(getData(source), serializer); | ||||
|   return variantAccept(VariantAttorney::getData(source), serializer); | ||||
| } | ||||
|  | ||||
| template <template <typename> class TSerializer, typename TDestination> | ||||
|   | ||||
| @@ -37,7 +37,8 @@ struct Converter { | ||||
| template <typename T> | ||||
| struct Converter< | ||||
|     T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value && | ||||
|                           !is_same<char, T>::value>::type> { | ||||
|                           !is_same<char, T>::value>::type> | ||||
|     : private VariantAttorney { | ||||
|   static void toJson(T src, VariantRef dst) { | ||||
|     VariantData* data = getData(dst); | ||||
|     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); | ||||
| @@ -58,7 +59,8 @@ struct Converter< | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct Converter<T, typename enable_if<is_enum<T>::value>::type> { | ||||
| struct Converter<T, typename enable_if<is_enum<T>::value>::type> | ||||
|     : private VariantAttorney { | ||||
|   static void toJson(T src, VariantRef dst) { | ||||
|     dst.set(static_cast<Integer>(src)); | ||||
|   } | ||||
| @@ -75,7 +77,7 @@ struct Converter<T, typename enable_if<is_enum<T>::value>::type> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<bool> { | ||||
| struct Converter<bool> : private VariantAttorney { | ||||
|   static void toJson(bool src, VariantRef dst) { | ||||
|     VariantData* data = getData(dst); | ||||
|     if (data) | ||||
| @@ -94,7 +96,8 @@ struct Converter<bool> { | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> { | ||||
| struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> | ||||
|     : private VariantAttorney { | ||||
|   static void toJson(T src, VariantRef dst) { | ||||
|     VariantData* data = getData(dst); | ||||
|     if (data) | ||||
| @@ -113,7 +116,7 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<const char*> { | ||||
| struct Converter<const char*> : private VariantAttorney { | ||||
|   static void toJson(const char* src, VariantRef dst) { | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst), | ||||
|                      getStringStoragePolicy(src)); | ||||
| @@ -131,7 +134,7 @@ struct Converter<const char*> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<String> { | ||||
| struct Converter<String> : private VariantAttorney { | ||||
|   static void toJson(String src, VariantRef dst) { | ||||
|     variantSetString(getData(dst), adaptString(src), getPool(dst), | ||||
|                      getStringStoragePolicy(src)); | ||||
| @@ -151,8 +154,8 @@ struct Converter<String> { | ||||
| template <typename T> | ||||
| inline typename enable_if<IsString<T>::value, bool>::type convertToJson( | ||||
|     const T& src, VariantRef dst) { | ||||
|   VariantData* data = getData(dst); | ||||
|   MemoryPool* pool = getPool(dst); | ||||
|   VariantData* data = VariantAttorney::getData(dst); | ||||
|   MemoryPool* pool = VariantAttorney::getPool(dst); | ||||
|   return variantSetString(data, adaptString(src), pool, | ||||
|                           getStringStoragePolicy(src)); | ||||
| } | ||||
| @@ -160,7 +163,7 @@ inline typename enable_if<IsString<T>::value, bool>::type convertToJson( | ||||
| template <> | ||||
| struct Converter<SerializedValue<const char*> > { | ||||
|   static void toJson(SerializedValue<const char*> src, VariantRef dst) { | ||||
|     VariantData* data = getData(dst); | ||||
|     VariantData* data = VariantAttorney::getData(dst); | ||||
|     if (data) | ||||
|       data->setLinkedRaw(src); | ||||
|   } | ||||
| @@ -171,7 +174,8 @@ struct Converter<SerializedValue<const char*> > { | ||||
| // SerializedValue<const __FlashStringHelper*> | ||||
| template <typename T> | ||||
| struct Converter<SerializedValue<T>, | ||||
|                  typename enable_if<!is_same<const char*, T>::value>::type> { | ||||
|                  typename enable_if<!is_same<const char*, T>::value>::type> | ||||
|     : private VariantAttorney { | ||||
|   static void toJson(SerializedValue<T> src, VariantRef dst) { | ||||
|     VariantData* data = getData(dst); | ||||
|     MemoryPool* pool = getPool(dst); | ||||
| @@ -183,7 +187,7 @@ struct Converter<SerializedValue<T>, | ||||
| #if ARDUINOJSON_HAS_NULLPTR | ||||
|  | ||||
| template <> | ||||
| struct Converter<decltype(nullptr)> { | ||||
| struct Converter<decltype(nullptr)> : private VariantAttorney { | ||||
|   static void toJson(decltype(nullptr), VariantRef dst) { | ||||
|     variantSetNull(getData(dst)); | ||||
|   } | ||||
| @@ -241,8 +245,8 @@ class MemoryPoolPrint : public Print { | ||||
| }; | ||||
|  | ||||
| inline void convertToJson(const ::Printable& src, VariantRef dst) { | ||||
|   MemoryPool* pool = getPool(dst); | ||||
|   VariantData* data = getData(dst); | ||||
|   MemoryPool* pool = VariantAttorney::getPool(dst); | ||||
|   VariantData* data = VariantAttorney::getData(dst); | ||||
|   if (!pool || !data) | ||||
|     return; | ||||
|   MemoryPoolPrint print(pool); | ||||
|   | ||||
							
								
								
									
										51
									
								
								src/ArduinoJson/Variant/VariantAttorney.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/ArduinoJson/Variant/VariantAttorney.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| // ArduinoJson - https://arduinojson.org | ||||
| // Copyright © 2014-2022, Benoit BLANCHON | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/attributes.hpp> | ||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||
| #include <ArduinoJson/Variant/VariantTo.hpp> | ||||
| #include "VariantRef.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| // Grants access to the internal variant API | ||||
| class VariantAttorney { | ||||
|   // Tells whether getData() returns a const pointer | ||||
|   template <typename TClient> | ||||
|   struct ResultOfGetData { | ||||
|    protected:  // <- to avoid GCC's "all member functions in class are private" | ||||
|     typedef char Yes[1]; | ||||
|     typedef char No[2]; | ||||
|  | ||||
|     static Yes &probe(const VariantData *); | ||||
|     static No &probe(VariantData *); | ||||
|  | ||||
|     static TClient &client; | ||||
|  | ||||
|    public: | ||||
|     typedef typename conditional<sizeof(probe(client.getData())) == sizeof(Yes), | ||||
|                                  const VariantData *, VariantData *>::type type; | ||||
|   }; | ||||
|  | ||||
|  public: | ||||
|   template <typename TClient> | ||||
|   FORCE_INLINE static MemoryPool *getPool(TClient &client) { | ||||
|     return client.getPool(); | ||||
|   } | ||||
|  | ||||
|   template <typename TClient> | ||||
|   FORCE_INLINE static typename ResultOfGetData<TClient>::type getData( | ||||
|       TClient &client) { | ||||
|     return client.getData(); | ||||
|   } | ||||
|  | ||||
|   template <typename TClient> | ||||
|   FORCE_INLINE static VariantData *getOrCreateData(TClient &client) { | ||||
|     return client.getOrCreateData(); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
| @@ -180,7 +180,8 @@ struct VariantComparer : ComparerBase { | ||||
|  private: | ||||
|   template <typename TComparer> | ||||
|   CompareResult accept(TComparer &comparer) { | ||||
|     CompareResult reversedResult = variantAccept(getData(rhs), comparer); | ||||
|     CompareResult reversedResult = | ||||
|         variantAccept(VariantAttorney::getData(rhs), comparer); | ||||
|     switch (reversedResult) { | ||||
|       case COMPARE_RESULT_GREATER: | ||||
|         return COMPARE_RESULT_LESS; | ||||
| @@ -203,7 +204,7 @@ struct Comparer< | ||||
| template <typename T> | ||||
| CompareResult compare(VariantConstRef lhs, const T &rhs) { | ||||
|   Comparer<T> comparer(rhs); | ||||
|   return variantAccept(getData(lhs), comparer); | ||||
|   return variantAccept(VariantAttorney::getData(lhs), comparer); | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||
| #include <ArduinoJson/Strings/StringAdapters.hpp> | ||||
| #include <ArduinoJson/Variant/Converter.hpp> | ||||
| #include <ArduinoJson/Variant/VariantAttorney.hpp> | ||||
| #include <ArduinoJson/Variant/VariantFunctions.hpp> | ||||
| #include <ArduinoJson/Variant/VariantOperators.hpp> | ||||
| #include <ArduinoJson/Variant/VariantRef.hpp> | ||||
| @@ -50,10 +51,6 @@ class VariantRefBase : public VariantTag { | ||||
|  protected: | ||||
|   VariantRefBase(TData *data) : _data(data) {} | ||||
|   TData *_data; | ||||
|  | ||||
|   friend TData *getData(const VariantRefBase &variant) { | ||||
|     return variant._data; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class VariantConstRef : public VariantRefBase<const VariantData>, | ||||
| @@ -61,6 +58,8 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | ||||
|                         public VariantShortcuts<VariantConstRef> { | ||||
|   typedef VariantRefBase<const VariantData> base_type; | ||||
|  | ||||
|   friend class VariantAttorney; | ||||
|  | ||||
|  public: | ||||
|   VariantConstRef() : base_type(0) {} | ||||
|   explicit VariantConstRef(const VariantData *data) : base_type(data) {} | ||||
| @@ -139,6 +138,7 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | ||||
|     return VariantConstRef(variantGetMember(_data, adaptString(key))); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   const VariantData *getData() const { | ||||
|     return _data; | ||||
|   } | ||||
| @@ -285,7 +285,7 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|   inline void shallowCopy(VariantConstRef target) { | ||||
|     if (!_data) | ||||
|       return; | ||||
|     const VariantData *targetData = target.getData(); | ||||
|     const VariantData *targetData = VariantAttorney::getData(target); | ||||
|     if (targetData) | ||||
|       *_data = *targetData; | ||||
|     else | ||||
| @@ -306,14 +306,10 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|  | ||||
|  private: | ||||
|   MemoryPool *_pool; | ||||
|  | ||||
|   friend MemoryPool *getPool(const VariantRef &variant) { | ||||
|     return variant._pool; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<VariantRef> { | ||||
| struct Converter<VariantRef> : private VariantAttorney { | ||||
|   static void toJson(VariantRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
| @@ -336,7 +332,7 @@ struct Converter<VariantRef> { | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct Converter<VariantConstRef> { | ||||
| struct Converter<VariantConstRef> : private VariantAttorney { | ||||
|   static void toJson(VariantConstRef src, VariantRef dst) { | ||||
|     variantCopyFrom(getData(dst), getData(src), getPool(dst)); | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user