mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added a return value to visitors
This commit is contained in:
		| @@ -12,12 +12,13 @@ inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) { | |||||||
|   return arr ? arr->addElement(pool) : 0; |   return arr ? arr->addElement(pool) : 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename Visitor> | template <typename TVisitor> | ||||||
| inline void arrayAccept(const CollectionData *arr, Visitor &visitor) { | inline typename TVisitor::result_type arrayAccept(const CollectionData *arr, | ||||||
|  |                                                   TVisitor &visitor) { | ||||||
|   if (arr) |   if (arr) | ||||||
|     visitor.visitArray(*arr); |     return visitor.visitArray(*arr); | ||||||
|   else |   else | ||||||
|     visitor.visitNull(); |     return visitor.visitNull(); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) { | inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) { | ||||||
|   | |||||||
| @@ -27,9 +27,9 @@ class ArrayRefBase { | |||||||
|     return VariantConstRef(reinterpret_cast<const VariantData*>(data)); |     return VariantConstRef(reinterpret_cast<const VariantData*>(data)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   FORCE_INLINE void accept(Visitor& visitor) const { |   FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const { | ||||||
|     arrayAccept(_data, visitor); |     return arrayAccept(_data, visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE bool isNull() const { |   FORCE_INLINE bool isNull() const { | ||||||
|   | |||||||
| @@ -98,8 +98,8 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >, | |||||||
|     return getOrAddUpstreamElement().set(value); |     return getOrAddUpstreamElement().set(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor& visitor) const { |   typename TVisitor::result_type accept(TVisitor& visitor) const { | ||||||
|     return getUpstreamElement().accept(visitor); |     return getUpstreamElement().accept(visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -65,40 +65,61 @@ inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) { | |||||||
| } | } | ||||||
|  |  | ||||||
| template <typename T> | template <typename T> | ||||||
| class ArrayCopier1D { | class ArrayCopier1D : public Visitor<size_t> { | ||||||
|  public: |  public: | ||||||
|   ArrayCopier1D(T* destination, size_t capacity) |   ArrayCopier1D(T* destination, size_t capacity) | ||||||
|       : _destination(destination), _capacity(capacity), _size(0) {} |       : _destination(destination), _capacity(capacity) {} | ||||||
|  |  | ||||||
|   void visitArray(const CollectionData& array) { |   size_t visitArray(const CollectionData& array) { | ||||||
|  |     size_t size = 0; | ||||||
|     VariantSlot* slot = array.head(); |     VariantSlot* slot = array.head(); | ||||||
|  |  | ||||||
|     while (slot != 0 && _size < _capacity) { |     while (slot != 0 && size < _capacity) { | ||||||
|       _destination[_size++] = variantAs<T>(slot->data()); |       _destination[size++] = variantAs<T>(slot->data()); | ||||||
|       slot = slot->next(); |       slot = slot->next(); | ||||||
|     } |     } | ||||||
|  |     return size; | ||||||
|   } |   } | ||||||
|   void visitObject(const CollectionData&) {} |  | ||||||
|   void visitFloat(Float) {} |  | ||||||
|   void visitString(const char*) {} |  | ||||||
|   void visitRawJson(const char*, size_t) {} |  | ||||||
|   void visitNegativeInteger(UInt) {} |  | ||||||
|   void visitPositiveInteger(UInt) {} |  | ||||||
|   void visitBoolean(bool) {} |  | ||||||
|   void visitNull() {} |  | ||||||
|  |  | ||||||
|   size_t result() const { |   size_t visitObject(const CollectionData&) { | ||||||
|     return _size; |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitFloat(Float) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitString(const char*) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitRawJson(const char*, size_t) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitNegativeInteger(UInt) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitPositiveInteger(UInt) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitBoolean(bool) { | ||||||
|  |     return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t visitNull() { | ||||||
|  |     return 0; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   T* _destination; |   T* _destination; | ||||||
|   size_t _capacity; |   size_t _capacity; | ||||||
|   size_t _size; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename T, size_t N1, size_t N2> | template <typename T, size_t N1, size_t N2> | ||||||
| class ArrayCopier2D { | class ArrayCopier2D : public Visitor<void> { | ||||||
|  public: |  public: | ||||||
|   ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {} |   ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {} | ||||||
|  |  | ||||||
| @@ -136,8 +157,8 @@ inline typename enable_if<!is_array<T>::value, size_t>::type copyArray( | |||||||
| template <typename TSource, typename T> | template <typename TSource, typename T> | ||||||
| inline size_t copyArray(const TSource& src, T* dst, size_t len) { | inline size_t copyArray(const TSource& src, T* dst, size_t len) { | ||||||
|   ArrayCopier1D<T> copier(dst, len); |   ArrayCopier1D<T> copier(dst, len); | ||||||
|   src.accept(copier); |  | ||||||
|   return copier.result(); |   return src.accept(copier); | ||||||
| } | } | ||||||
|  |  | ||||||
| // Copy a JsonArray to a 2D array | // Copy a JsonArray to a 2D array | ||||||
|   | |||||||
| @@ -15,8 +15,8 @@ namespace ARDUINOJSON_NAMESPACE { | |||||||
|  |  | ||||||
| class JsonDocument : public Visitable { | class JsonDocument : public Visitable { | ||||||
|  public: |  public: | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor& visitor) const { |   typename TVisitor::result_type accept(TVisitor& visitor) const { | ||||||
|     return getVariant().accept(visitor); |     return getVariant().accept(visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,11 +12,11 @@ | |||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename TWriter> | template <typename TWriter> | ||||||
| class JsonSerializer { | class JsonSerializer : public Visitor<size_t> { | ||||||
|  public: |  public: | ||||||
|   JsonSerializer(TWriter writer) : _formatter(writer) {} |   JsonSerializer(TWriter writer) : _formatter(writer) {} | ||||||
|  |  | ||||||
|   FORCE_INLINE void visitArray(const CollectionData &array) { |   FORCE_INLINE size_t visitArray(const CollectionData &array) { | ||||||
|     write('['); |     write('['); | ||||||
|  |  | ||||||
|     VariantSlot *slot = array.head(); |     VariantSlot *slot = array.head(); | ||||||
| @@ -32,9 +32,10 @@ class JsonSerializer { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     write(']'); |     write(']'); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitObject(const CollectionData &object) { |   size_t visitObject(const CollectionData &object) { | ||||||
|     write('{'); |     write('{'); | ||||||
|  |  | ||||||
|     VariantSlot *slot = object.head(); |     VariantSlot *slot = object.head(); | ||||||
| @@ -52,41 +53,49 @@ class JsonSerializer { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     write('}'); |     write('}'); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitFloat(Float value) { |   size_t visitFloat(Float value) { | ||||||
|     _formatter.writeFloat(value); |     _formatter.writeFloat(value); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitString(const char *value) { |   size_t visitString(const char *value) { | ||||||
|     _formatter.writeString(value); |     _formatter.writeString(value); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitRawJson(const char *data, size_t n) { |   size_t visitRawJson(const char *data, size_t n) { | ||||||
|     _formatter.writeRaw(data, n); |     _formatter.writeRaw(data, n); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNegativeInteger(UInt value) { |   size_t visitNegativeInteger(UInt value) { | ||||||
|     _formatter.writeNegativeInteger(value); |     _formatter.writeNegativeInteger(value); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitPositiveInteger(UInt value) { |   size_t visitPositiveInteger(UInt value) { | ||||||
|     _formatter.writePositiveInteger(value); |     _formatter.writePositiveInteger(value); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitBoolean(bool value) { |   size_t visitBoolean(bool value) { | ||||||
|     _formatter.writeBoolean(value); |     _formatter.writeBoolean(value); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNull() { |   size_t visitNull() { | ||||||
|     _formatter.writeRaw("null"); |     _formatter.writeRaw("null"); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|   size_t bytesWritten() const { |   size_t bytesWritten() const { | ||||||
|     return _formatter.bytesWritten(); |     return _formatter.bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  protected: |  | ||||||
|   void write(char c) { |   void write(char c) { | ||||||
|     _formatter.writeRaw(c); |     _formatter.writeRaw(c); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -18,44 +18,48 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> { | |||||||
|  public: |  public: | ||||||
|   PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} |   PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {} | ||||||
|  |  | ||||||
|   void visitArray(const CollectionData &array) { |   size_t visitArray(const CollectionData &array) { | ||||||
|     VariantSlot *slot = array.head(); |     VariantSlot *slot = array.head(); | ||||||
|     if (!slot) |     if (slot) { | ||||||
|       return base::write("[]"); |       base::write("[\r\n"); | ||||||
|  |       _nesting++; | ||||||
|  |       while (slot != 0) { | ||||||
|  |         indent(); | ||||||
|  |         slot->data()->accept(*this); | ||||||
|  |  | ||||||
|     base::write("[\r\n"); |         slot = slot->next(); | ||||||
|     _nesting++; |         base::write(slot ? ",\r\n" : "\r\n"); | ||||||
|     while (slot != 0) { |       } | ||||||
|  |       _nesting--; | ||||||
|       indent(); |       indent(); | ||||||
|       slot->data()->accept(*this); |       base::write("]"); | ||||||
|  |     } else { | ||||||
|       slot = slot->next(); |       base::write("[]"); | ||||||
|       base::write(slot ? ",\r\n" : "\r\n"); |  | ||||||
|     } |     } | ||||||
|     _nesting--; |     return this->bytesWritten(); | ||||||
|     indent(); |  | ||||||
|     base::write("]"); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitObject(const CollectionData &object) { |   size_t visitObject(const CollectionData &object) { | ||||||
|     VariantSlot *slot = object.head(); |     VariantSlot *slot = object.head(); | ||||||
|     if (!slot) |     if (slot) { | ||||||
|       return base::write("{}"); |       base::write("{\r\n"); | ||||||
|  |       _nesting++; | ||||||
|  |       while (slot != 0) { | ||||||
|  |         indent(); | ||||||
|  |         base::visitString(slot->key()); | ||||||
|  |         base::write(": "); | ||||||
|  |         slot->data()->accept(*this); | ||||||
|  |  | ||||||
|     base::write("{\r\n"); |         slot = slot->next(); | ||||||
|     _nesting++; |         base::write(slot ? ",\r\n" : "\r\n"); | ||||||
|     while (slot != 0) { |       } | ||||||
|  |       _nesting--; | ||||||
|       indent(); |       indent(); | ||||||
|       base::visitString(slot->key()); |       base::write("}"); | ||||||
|       base::write(": "); |     } else { | ||||||
|       slot->data()->accept(*this); |       base::write("{}"); | ||||||
|  |  | ||||||
|       slot = slot->next(); |  | ||||||
|       base::write(slot ? ",\r\n" : "\r\n"); |  | ||||||
|     } |     } | ||||||
|     _nesting--; |     return this->bytesWritten(); | ||||||
|     indent(); |  | ||||||
|     base::write("}"); |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   | |||||||
| @@ -12,17 +12,18 @@ | |||||||
| #include <ArduinoJson/Numbers/Integer.hpp> | #include <ArduinoJson/Numbers/Integer.hpp> | ||||||
| #include <ArduinoJson/Polyfills/assert.hpp> | #include <ArduinoJson/Polyfills/assert.hpp> | ||||||
| #include <ArduinoJson/Polyfills/attributes.hpp> | #include <ArduinoJson/Polyfills/attributes.hpp> | ||||||
|  | #include <ArduinoJson/Serialization/CountingDecorator.hpp> | ||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename TWriter> | template <typename TWriter> | ||||||
| class TextFormatter { | class TextFormatter { | ||||||
|  public: |  public: | ||||||
|   explicit TextFormatter(TWriter writer) : _writer(writer), _length(0) {} |   explicit TextFormatter(TWriter writer) : _writer(writer) {} | ||||||
|  |  | ||||||
|   // Returns the number of bytes sent to the TWriter implementation. |   // Returns the number of bytes sent to the TWriter implementation. | ||||||
|   size_t bytesWritten() const { |   size_t bytesWritten() const { | ||||||
|     return _length; |     return _writer.count(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeBoolean(bool value) { |   void writeBoolean(bool value) { | ||||||
| @@ -128,28 +129,28 @@ class TextFormatter { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeRaw(const char *s) { |   void writeRaw(const char *s) { | ||||||
|     _length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s)); |     _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeRaw(const char *s, size_t n) { |   void writeRaw(const char *s, size_t n) { | ||||||
|     _length += _writer.write(reinterpret_cast<const uint8_t *>(s), n); |     _writer.write(reinterpret_cast<const uint8_t *>(s), n); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeRaw(const char *begin, const char *end) { |   void writeRaw(const char *begin, const char *end) { | ||||||
|     _length += _writer.write(reinterpret_cast<const uint8_t *>(begin), |     _writer.write(reinterpret_cast<const uint8_t *>(begin), | ||||||
|                              static_cast<size_t>(end - begin)); |                   static_cast<size_t>(end - begin)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <size_t N> |   template <size_t N> | ||||||
|   void writeRaw(const char (&s)[N]) { |   void writeRaw(const char (&s)[N]) { | ||||||
|     _length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1); |     _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1); | ||||||
|   } |   } | ||||||
|   void writeRaw(char c) { |   void writeRaw(char c) { | ||||||
|     _length += _writer.write(static_cast<uint8_t>(c)); |     _writer.write(static_cast<uint8_t>(c)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  protected: |  protected: | ||||||
|   TWriter _writer; |   CountingDecorator<TWriter> _writer; | ||||||
|   size_t _length; |   size_t _length; | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   | |||||||
| @@ -8,6 +8,11 @@ | |||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
|  | template <typename TResult> | ||||||
|  | struct Visitor { | ||||||
|  |   typedef TResult result_type; | ||||||
|  | }; | ||||||
|  |  | ||||||
| struct Visitable { | struct Visitable { | ||||||
|   // template<Visitor> |   // template<Visitor> | ||||||
|   // void accept(Visitor&) const; |   // void accept(Visitor&) const; | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ | |||||||
| #include <ArduinoJson/MsgPack/endianess.hpp> | #include <ArduinoJson/MsgPack/endianess.hpp> | ||||||
| #include <ArduinoJson/Polyfills/assert.hpp> | #include <ArduinoJson/Polyfills/assert.hpp> | ||||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||||
|  | #include <ArduinoJson/Serialization/CountingDecorator.hpp> | ||||||
| #include <ArduinoJson/Serialization/measure.hpp> | #include <ArduinoJson/Serialization/measure.hpp> | ||||||
| #include <ArduinoJson/Serialization/serialize.hpp> | #include <ArduinoJson/Serialization/serialize.hpp> | ||||||
| #include <ArduinoJson/Variant/VariantData.hpp> | #include <ArduinoJson/Variant/VariantData.hpp> | ||||||
| @@ -14,19 +15,20 @@ | |||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename TWriter> | template <typename TWriter> | ||||||
| class MsgPackSerializer { | class MsgPackSerializer : public Visitor<size_t> { | ||||||
|  public: |  public: | ||||||
|   MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {} |   MsgPackSerializer(TWriter writer) : _writer(writer) {} | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) { |   typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) { | ||||||
|     writeByte(0xCA); |     writeByte(0xCA); | ||||||
|     writeInteger(value32); |     writeInteger(value32); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   ARDUINOJSON_NO_SANITIZE("float-cast-overflow") |   ARDUINOJSON_NO_SANITIZE("float-cast-overflow") | ||||||
|   typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) { |   typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) { | ||||||
|     float value32 = float(value64); |     float value32 = float(value64); | ||||||
|     if (value32 == value64) { |     if (value32 == value64) { | ||||||
|       writeByte(0xCA); |       writeByte(0xCA); | ||||||
| @@ -35,9 +37,10 @@ class MsgPackSerializer { | |||||||
|       writeByte(0xCB); |       writeByte(0xCB); | ||||||
|       writeInteger(value64); |       writeInteger(value64); | ||||||
|     } |     } | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitArray(const CollectionData& array) { |   size_t visitArray(const CollectionData& array) { | ||||||
|     size_t n = array.size(); |     size_t n = array.size(); | ||||||
|     if (n < 0x10) { |     if (n < 0x10) { | ||||||
|       writeByte(uint8_t(0x90 + array.size())); |       writeByte(uint8_t(0x90 + array.size())); | ||||||
| @@ -51,9 +54,10 @@ class MsgPackSerializer { | |||||||
|     for (VariantSlot* slot = array.head(); slot; slot = slot->next()) { |     for (VariantSlot* slot = array.head(); slot; slot = slot->next()) { | ||||||
|       slot->data()->accept(*this); |       slot->data()->accept(*this); | ||||||
|     } |     } | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitObject(const CollectionData& object) { |   size_t visitObject(const CollectionData& object) { | ||||||
|     size_t n = object.size(); |     size_t n = object.size(); | ||||||
|     if (n < 0x10) { |     if (n < 0x10) { | ||||||
|       writeByte(uint8_t(0x80 + n)); |       writeByte(uint8_t(0x80 + n)); | ||||||
| @@ -68,9 +72,10 @@ class MsgPackSerializer { | |||||||
|       visitString(slot->key()); |       visitString(slot->key()); | ||||||
|       slot->data()->accept(*this); |       slot->data()->accept(*this); | ||||||
|     } |     } | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitString(const char* value) { |   size_t visitString(const char* value) { | ||||||
|     ARDUINOJSON_ASSERT(value != NULL); |     ARDUINOJSON_ASSERT(value != NULL); | ||||||
|  |  | ||||||
|     size_t n = strlen(value); |     size_t n = strlen(value); | ||||||
| @@ -88,13 +93,15 @@ class MsgPackSerializer { | |||||||
|       writeInteger(uint32_t(n)); |       writeInteger(uint32_t(n)); | ||||||
|     } |     } | ||||||
|     writeBytes(reinterpret_cast<const uint8_t*>(value), n); |     writeBytes(reinterpret_cast<const uint8_t*>(value), n); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitRawJson(const char* data, size_t size) { |   size_t visitRawJson(const char* data, size_t size) { | ||||||
|     writeBytes(reinterpret_cast<const uint8_t*>(data), size); |     writeBytes(reinterpret_cast<const uint8_t*>(data), size); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNegativeInteger(UInt value) { |   size_t visitNegativeInteger(UInt value) { | ||||||
|     UInt negated = UInt(~value + 1); |     UInt negated = UInt(~value + 1); | ||||||
|     if (value <= 0x20) { |     if (value <= 0x20) { | ||||||
|       writeInteger(int8_t(negated)); |       writeInteger(int8_t(negated)); | ||||||
| @@ -114,9 +121,10 @@ class MsgPackSerializer { | |||||||
|       writeInteger(int64_t(negated)); |       writeInteger(int64_t(negated)); | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitPositiveInteger(UInt value) { |   size_t visitPositiveInteger(UInt value) { | ||||||
|     if (value <= 0x7F) { |     if (value <= 0x7F) { | ||||||
|       writeInteger(uint8_t(value)); |       writeInteger(uint8_t(value)); | ||||||
|     } else if (value <= 0xFF) { |     } else if (value <= 0xFF) { | ||||||
| @@ -141,27 +149,30 @@ class MsgPackSerializer { | |||||||
|       writeInteger(uint64_t(value)); |       writeInteger(uint64_t(value)); | ||||||
|     } |     } | ||||||
| #endif | #endif | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitBoolean(bool value) { |   size_t visitBoolean(bool value) { | ||||||
|     writeByte(value ? 0xC3 : 0xC2); |     writeByte(value ? 0xC3 : 0xC2); | ||||||
|  |     return bytesWritten(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNull() { |   size_t visitNull() { | ||||||
|     writeByte(0xC0); |     writeByte(0xC0); | ||||||
|   } |     return bytesWritten(); | ||||||
|  |  | ||||||
|   size_t bytesWritten() const { |  | ||||||
|     return _bytesWritten; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|  |   size_t bytesWritten() const { | ||||||
|  |     return _writer.count(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   void writeByte(uint8_t c) { |   void writeByte(uint8_t c) { | ||||||
|     _bytesWritten += _writer.write(c); |     _writer.write(c); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void writeBytes(const uint8_t* p, size_t n) { |   void writeBytes(const uint8_t* p, size_t n) { | ||||||
|     _bytesWritten += _writer.write(p, n); |     _writer.write(p, n); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
| @@ -170,8 +181,7 @@ class MsgPackSerializer { | |||||||
|     writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); |     writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   TWriter _writer; |   CountingDecorator<TWriter> _writer; | ||||||
|   size_t _bytesWritten; |  | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> | template <typename TSource, typename TDestination> | ||||||
|   | |||||||
| @@ -120,8 +120,8 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | |||||||
|     return getOrAddUpstreamMember().set(value); |     return getOrAddUpstreamMember().set(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor &visitor) const { |   typename TVisitor::result_type accept(TVisitor &visitor) const { | ||||||
|     return getUpstreamMember().accept(visitor); |     return getUpstreamMember().accept(visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,12 +8,13 @@ | |||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename Visitor> | template <typename TVisitor> | ||||||
| void objectAccept(const CollectionData *obj, Visitor &visitor) { | typename TVisitor::result_type objectAccept(const CollectionData *obj, | ||||||
|  |                                             TVisitor &visitor) { | ||||||
|   if (obj) |   if (obj) | ||||||
|     visitor.visitObject(*obj); |     return visitor.visitObject(*obj); | ||||||
|   else |   else | ||||||
|     visitor.visitNull(); |     return visitor.visitNull(); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) { | inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) { | ||||||
|   | |||||||
| @@ -22,9 +22,9 @@ class ObjectRefBase { | |||||||
|     return VariantConstRef(reinterpret_cast<const VariantData*>(data)); |     return VariantConstRef(reinterpret_cast<const VariantData*>(data)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   FORCE_INLINE void accept(Visitor& visitor) const { |   typename TVisitor::result_type accept(TVisitor& visitor) const { | ||||||
|     objectAccept(_data, visitor); |     return objectAccept(_data, visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   FORCE_INLINE bool isNull() const { |   FORCE_INLINE bool isNull() const { | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								src/ArduinoJson/Serialization/CountingDecorator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/ArduinoJson/Serialization/CountingDecorator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2020 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <ArduinoJson/Namespace.hpp> | ||||||
|  |  | ||||||
|  | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
|  | template <typename TWriter> | ||||||
|  | class CountingDecorator { | ||||||
|  |  public: | ||||||
|  |   explicit CountingDecorator(TWriter& writer) : _writer(writer), _count(0) {} | ||||||
|  |  | ||||||
|  |   void write(uint8_t c) { | ||||||
|  |     _count += _writer.write(c); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void write(const uint8_t* s, size_t n) { | ||||||
|  |     _count += _writer.write(s, n); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t count() const { | ||||||
|  |     return _count; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   TWriter _writer; | ||||||
|  |   size_t _count; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
| @@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource> | |||||||
| size_t measure(const TSource &source) { | size_t measure(const TSource &source) { | ||||||
|   DummyWriter dp; |   DummyWriter dp; | ||||||
|   TSerializer<DummyWriter> serializer(dp); |   TSerializer<DummyWriter> serializer(dp); | ||||||
|   source.accept(serializer); |   return source.accept(serializer); | ||||||
|   return serializer.bytesWritten(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| }  // namespace ARDUINOJSON_NAMESPACE | }  // namespace ARDUINOJSON_NAMESPACE | ||||||
|   | |||||||
| @@ -12,8 +12,7 @@ template <template <typename> class TSerializer, typename TSource, | |||||||
|           typename TWriter> |           typename TWriter> | ||||||
| size_t doSerialize(const TSource &source, TWriter writer) { | size_t doSerialize(const TSource &source, TWriter writer) { | ||||||
|   TSerializer<TWriter> serializer(writer); |   TSerializer<TWriter> serializer(writer); | ||||||
|   source.accept(serializer); |   return source.accept(serializer); | ||||||
|   return serializer.bytesWritten(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template <template <typename> class TSerializer, typename TSource, | template <template <typename> class TSerializer, typename TSource, | ||||||
|   | |||||||
| @@ -14,20 +14,34 @@ namespace ARDUINOJSON_NAMESPACE { | |||||||
|  |  | ||||||
| class CollectionData; | class CollectionData; | ||||||
|  |  | ||||||
| struct ComparerBase { | struct ComparerBase : Visitor<CompareResult> { | ||||||
|   CompareResult result; |   CompareResult visitArray(const CollectionData &) { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|   ComparerBase() : result(COMPARE_RESULT_DIFFER) {} |   } | ||||||
|  |   CompareResult visitBoolean(bool) { | ||||||
|   void visitArray(const CollectionData &) {} |     return COMPARE_RESULT_DIFFER; | ||||||
|   void visitBoolean(bool) {} |   } | ||||||
|   void visitFloat(Float) {} |   CompareResult visitFloat(Float) { | ||||||
|   void visitNegativeInteger(UInt) {} |     return COMPARE_RESULT_DIFFER; | ||||||
|   void visitNull() {} |   } | ||||||
|   void visitObject(const CollectionData &) {} |   CompareResult visitNegativeInteger(UInt) { | ||||||
|   void visitPositiveInteger(UInt) {} |     return COMPARE_RESULT_DIFFER; | ||||||
|   void visitRawJson(const char *, size_t) {} |   } | ||||||
|   void visitString(const char *) {} |   CompareResult visitNull() { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|  |   } | ||||||
|  |   CompareResult visitObject(const CollectionData &) { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|  |   } | ||||||
|  |   CompareResult visitPositiveInteger(UInt) { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|  |   } | ||||||
|  |   CompareResult visitRawJson(const char *, size_t) { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|  |   } | ||||||
|  |   CompareResult visitString(const char *) { | ||||||
|  |     return COMPARE_RESULT_DIFFER; | ||||||
|  |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename T, typename Enable = void> | template <typename T, typename Enable = void> | ||||||
| @@ -40,19 +54,21 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type> | |||||||
|  |  | ||||||
|   explicit Comparer(T value) : rhs(value) {} |   explicit Comparer(T value) : rhs(value) {} | ||||||
|  |  | ||||||
|   void visitString(const char *lhs) { |   CompareResult visitString(const char *lhs) { | ||||||
|     int i = adaptString(rhs).compare(lhs); |     int i = adaptString(rhs).compare(lhs); | ||||||
|     if (i < 0) |     if (i < 0) | ||||||
|       result = COMPARE_RESULT_GREATER; |       return COMPARE_RESULT_GREATER; | ||||||
|     else if (i > 0) |     else if (i > 0) | ||||||
|       result = COMPARE_RESULT_LESS; |       return COMPARE_RESULT_LESS; | ||||||
|     else |     else | ||||||
|       result = COMPARE_RESULT_EQUAL; |       return COMPARE_RESULT_EQUAL; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNull() { |   CompareResult visitNull() { | ||||||
|     if (adaptString(rhs).isNull()) |     if (adaptString(rhs).isNull()) | ||||||
|       result = COMPARE_RESULT_EQUAL; |       return COMPARE_RESULT_EQUAL; | ||||||
|  |     else | ||||||
|  |       return COMPARE_RESULT_DIFFER; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -64,26 +80,26 @@ struct Comparer<T, typename enable_if<is_integral<T>::value || | |||||||
|  |  | ||||||
|   explicit Comparer(T value) : rhs(value) {} |   explicit Comparer(T value) : rhs(value) {} | ||||||
|  |  | ||||||
|   void visitFloat(Float lhs) { |   CompareResult visitFloat(Float lhs) { | ||||||
|     result = arithmeticCompare(lhs, rhs); |     return arithmeticCompare(lhs, rhs); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNegativeInteger(UInt lhs) { |   CompareResult visitNegativeInteger(UInt lhs) { | ||||||
|     result = arithmeticCompareNegateLeft(lhs, rhs); |     return arithmeticCompareNegateLeft(lhs, rhs); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitPositiveInteger(UInt lhs) { |   CompareResult visitPositiveInteger(UInt lhs) { | ||||||
|     result = arithmeticCompare(lhs, rhs); |     return arithmeticCompare(lhs, rhs); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitBoolean(bool lhs) { |   CompareResult visitBoolean(bool lhs) { | ||||||
|     visitPositiveInteger(static_cast<UInt>(lhs)); |     return visitPositiveInteger(static_cast<UInt>(lhs)); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| struct NullComparer : ComparerBase { | struct NullComparer : ComparerBase { | ||||||
|   void visitNull() { |   CompareResult visitNull() { | ||||||
|     result = COMPARE_RESULT_EQUAL; |     return COMPARE_RESULT_EQUAL; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -99,9 +115,11 @@ struct ArrayComparer : ComparerBase { | |||||||
|  |  | ||||||
|   explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {} |   explicit ArrayComparer(const CollectionData &rhs) : _rhs(&rhs) {} | ||||||
|  |  | ||||||
|   void visitArray(const CollectionData &lhs) { |   CompareResult visitArray(const CollectionData &lhs) { | ||||||
|     if (lhs.equalsArray(*_rhs)) |     if (lhs.equalsArray(*_rhs)) | ||||||
|       result = COMPARE_RESULT_EQUAL; |       return COMPARE_RESULT_EQUAL; | ||||||
|  |     else | ||||||
|  |       return COMPARE_RESULT_DIFFER; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -110,20 +128,20 @@ struct NegativeIntegerComparer : ComparerBase { | |||||||
|  |  | ||||||
|   explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {} |   explicit NegativeIntegerComparer(UInt rhs) : _rhs(rhs) {} | ||||||
|  |  | ||||||
|   void visitFloat(Float lhs) { |   CompareResult visitFloat(Float lhs) { | ||||||
|     result = arithmeticCompareNegateRight(lhs, _rhs); |     return arithmeticCompareNegateRight(lhs, _rhs); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNegativeInteger(UInt lhs) { |   CompareResult visitNegativeInteger(UInt lhs) { | ||||||
|     result = arithmeticCompare(_rhs, lhs); |     return arithmeticCompare(_rhs, lhs); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitPositiveInteger(UInt) { |   CompareResult visitPositiveInteger(UInt) { | ||||||
|     result = COMPARE_RESULT_GREATER; |     return COMPARE_RESULT_GREATER; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitBoolean(bool) { |   CompareResult visitBoolean(bool) { | ||||||
|     result = COMPARE_RESULT_GREATER; |     return COMPARE_RESULT_GREATER; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -132,9 +150,11 @@ struct ObjectComparer : ComparerBase { | |||||||
|  |  | ||||||
|   explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {} |   explicit ObjectComparer(const CollectionData &rhs) : _rhs(&rhs) {} | ||||||
|  |  | ||||||
|   void visitObject(const CollectionData &lhs) { |   CompareResult visitObject(const CollectionData &lhs) { | ||||||
|     if (lhs.equalsObject(*_rhs)) |     if (lhs.equalsObject(*_rhs)) | ||||||
|       result = COMPARE_RESULT_EQUAL; |       return COMPARE_RESULT_EQUAL; | ||||||
|  |     else | ||||||
|  |       return COMPARE_RESULT_DIFFER; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -145,15 +165,15 @@ struct RawComparer : ComparerBase { | |||||||
|   explicit RawComparer(const char *rhsData, size_t rhsSize) |   explicit RawComparer(const char *rhsData, size_t rhsSize) | ||||||
|       : _rhsData(rhsData), _rhsSize(rhsSize) {} |       : _rhsData(rhsData), _rhsSize(rhsSize) {} | ||||||
|  |  | ||||||
|   void visitRawJson(const char *lhsData, size_t lhsSize) { |   CompareResult visitRawJson(const char *lhsData, size_t lhsSize) { | ||||||
|     size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize; |     size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize; | ||||||
|     int n = memcmp(lhsData, _rhsData, size); |     int n = memcmp(lhsData, _rhsData, size); | ||||||
|     if (n < 0) |     if (n < 0) | ||||||
|       result = COMPARE_RESULT_LESS; |       return COMPARE_RESULT_LESS; | ||||||
|     else if (n > 0) |     else if (n > 0) | ||||||
|       result = COMPARE_RESULT_GREATER; |       return COMPARE_RESULT_GREATER; | ||||||
|     else |     else | ||||||
|       result = COMPARE_RESULT_EQUAL; |       return COMPARE_RESULT_EQUAL; | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| @@ -164,65 +184,62 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type> | |||||||
|  |  | ||||||
|   explicit Comparer(T value) : rhs(value) {} |   explicit Comparer(T value) : rhs(value) {} | ||||||
|  |  | ||||||
|   void visitArray(const CollectionData &lhs) { |   CompareResult visitArray(const CollectionData &lhs) { | ||||||
|     ArrayComparer comparer(lhs); |     ArrayComparer comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitObject(const CollectionData &lhs) { |   CompareResult visitObject(const CollectionData &lhs) { | ||||||
|     ObjectComparer comparer(lhs); |     ObjectComparer comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitFloat(Float lhs) { |   CompareResult visitFloat(Float lhs) { | ||||||
|     Comparer<Float> comparer(lhs); |     Comparer<Float> comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitString(const char *lhs) { |   CompareResult visitString(const char *lhs) { | ||||||
|     Comparer<const char *> comparer(lhs); |     Comparer<const char *> comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitRawJson(const char *lhsData, size_t lhsSize) { |   CompareResult visitRawJson(const char *lhsData, size_t lhsSize) { | ||||||
|     RawComparer comparer(lhsData, lhsSize); |     RawComparer comparer(lhsData, lhsSize); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNegativeInteger(UInt lhs) { |   CompareResult visitNegativeInteger(UInt lhs) { | ||||||
|     NegativeIntegerComparer comparer(lhs); |     NegativeIntegerComparer comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitPositiveInteger(UInt lhs) { |   CompareResult visitPositiveInteger(UInt lhs) { | ||||||
|     Comparer<UInt> comparer(lhs); |     Comparer<UInt> comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitBoolean(bool lhs) { |   CompareResult visitBoolean(bool lhs) { | ||||||
|     Comparer<bool> comparer(lhs); |     Comparer<bool> comparer(lhs); | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void visitNull() { |   CompareResult visitNull() { | ||||||
|     NullComparer comparer; |     NullComparer comparer; | ||||||
|     accept(comparer); |     return accept(comparer); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  private: |  private: | ||||||
|   template <typename TComparer> |   template <typename TComparer> | ||||||
|   void accept(TComparer &comparer) { |   CompareResult accept(TComparer &comparer) { | ||||||
|     rhs.accept(comparer); |     CompareResult reversedResult = rhs.accept(comparer); | ||||||
|     switch (comparer.result) { |     switch (reversedResult) { | ||||||
|       case COMPARE_RESULT_GREATER: |       case COMPARE_RESULT_GREATER: | ||||||
|         result = COMPARE_RESULT_LESS; |         return COMPARE_RESULT_LESS; | ||||||
|         break; |  | ||||||
|       case COMPARE_RESULT_LESS: |       case COMPARE_RESULT_LESS: | ||||||
|         result = COMPARE_RESULT_GREATER; |         return COMPARE_RESULT_GREATER; | ||||||
|         break; |  | ||||||
|       default: |       default: | ||||||
|         result = comparer.result; |         return reversedResult; | ||||||
|         break; |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
| @@ -230,8 +247,7 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type> | |||||||
| template <typename T1, typename T2> | template <typename T1, typename T2> | ||||||
| CompareResult compare(const T1 &lhs, const T2 &rhs) { | CompareResult compare(const T1 &lhs, const T2 &rhs) { | ||||||
|   Comparer<T2> comparer(rhs); |   Comparer<T2> comparer(rhs); | ||||||
|   lhs.accept(comparer); |   return lhs.accept(comparer); | ||||||
|   return comparer.result; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| inline int variantCompare(const VariantData *a, const VariantData *b) { | inline int variantCompare(const VariantData *a, const VariantData *b) { | ||||||
|   | |||||||
| @@ -34,8 +34,8 @@ class VariantData { | |||||||
|   // - no virtual |   // - no virtual | ||||||
|   // - no inheritance |   // - no inheritance | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor &visitor) const { |   typename TVisitor::result_type accept(TVisitor &visitor) const { | ||||||
|     switch (type()) { |     switch (type()) { | ||||||
|       case VALUE_IS_FLOAT: |       case VALUE_IS_FLOAT: | ||||||
|         return visitor.visitFloat(_content.asFloat); |         return visitor.visitFloat(_content.asFloat); | ||||||
|   | |||||||
| @@ -9,12 +9,13 @@ | |||||||
|  |  | ||||||
| namespace ARDUINOJSON_NAMESPACE { | namespace ARDUINOJSON_NAMESPACE { | ||||||
|  |  | ||||||
| template <typename Visitor> | template <typename TVisitor> | ||||||
| inline void variantAccept(const VariantData *var, Visitor &visitor) { | inline typename TVisitor::result_type variantAccept(const VariantData *var, | ||||||
|  |                                                     TVisitor &visitor) { | ||||||
|   if (var != 0) |   if (var != 0) | ||||||
|     var->accept(visitor); |     return var->accept(visitor); | ||||||
|   else |   else | ||||||
|     visitor.visitNull(); |     return visitor.visitNull(); | ||||||
| } | } | ||||||
|  |  | ||||||
| inline const CollectionData *variantAsArray(const VariantData *var) { | inline const CollectionData *variantAsArray(const VariantData *var) { | ||||||
|   | |||||||
| @@ -261,9 +261,9 @@ class VariantRef : public VariantRefBase<VariantData>, | |||||||
|     return variantAs<T>(_data, _pool); |     return variantAs<T>(_data, _pool); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor &visitor) const { |   typename TVisitor::result_type accept(TVisitor &visitor) const { | ||||||
|     variantAccept(_data, visitor); |     return variantAccept(_data, visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Change the type of the variant |   // Change the type of the variant | ||||||
| @@ -347,9 +347,9 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | |||||||
|   VariantConstRef(const VariantData *data) : base_type(data) {} |   VariantConstRef(const VariantData *data) : base_type(data) {} | ||||||
|   VariantConstRef(VariantRef var) : base_type(var._data) {} |   VariantConstRef(VariantRef var) : base_type(var._data) {} | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename TVisitor> | ||||||
|   void accept(Visitor &visitor) const { |   typename TVisitor::result_type accept(TVisitor &visitor) const { | ||||||
|     variantAccept(_data, visitor); |     return variantAccept(_data, visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename T> |   template <typename T> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user