diff --git a/src/ArduinoJson/Array/JsonArrayConst.hpp b/src/ArduinoJson/Array/JsonArrayConst.hpp index e6f177f4..cbd87628 100644 --- a/src/ArduinoJson/Array/JsonArrayConst.hpp +++ b/src/ArduinoJson/Array/JsonArrayConst.hpp @@ -50,21 +50,7 @@ class JsonArrayConst : public detail::VariantOperators { if (!data_ || !rhs.data_) return false; - iterator it1 = begin(); - iterator it2 = rhs.begin(); - - for (;;) { - bool end1 = it1 == end(); - bool end2 = it2 == rhs.end(); - if (end1 && end2) - return true; - if (end1 || end2) - return false; - if (*it1 != *it2) - return false; - ++it1; - ++it2; - } + return arrayEquals(*data_, *rhs.data_); } // Returns the element at the specified index. diff --git a/src/ArduinoJson/Collection/CollectionData.hpp b/src/ArduinoJson/Collection/CollectionData.hpp index 1ba09b1c..91b05b00 100644 --- a/src/ArduinoJson/Collection/CollectionData.hpp +++ b/src/ArduinoJson/Collection/CollectionData.hpp @@ -52,4 +52,9 @@ inline VariantData* collectionToVariant(CollectionData* collection) { return reinterpret_cast(data); } +bool arrayEquals(const detail::CollectionData& lhs, + const detail::CollectionData& rhs); +bool objectEquals(const detail::CollectionData& lhs, + const detail::CollectionData& rhs); + ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index 12ee73d4..6752a297 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -6,6 +6,7 @@ #include #include +#include #include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE @@ -99,4 +100,33 @@ inline void CollectionData::movePointers(ptrdiff_t variantDistance) { slot->data()->movePointers(variantDistance); } +inline bool arrayEquals(const CollectionData& lhs, const CollectionData& rhs) { + auto a = lhs.head(); + auto b = rhs.head(); + + for (;;) { + if (!a && !b) // both ended + return true; + if (!a || !b) // one ended + return false; + if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL) + return false; + a = a->next(); + b = b->next(); + } +} + +inline bool objectEquals(const CollectionData& lhs, const CollectionData& rhs) { + size_t count = 0; + for (auto a = lhs.head(); a; a = a->next()) { + auto b = rhs.get(adaptString(a->key())); + if (!b) + return false; + if (compare(a->data(), b->data()) != COMPARE_RESULT_EQUAL) + return false; + count++; + } + return count == rhs.size(); +} + ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Object/JsonObjectConst.hpp b/src/ArduinoJson/Object/JsonObjectConst.hpp index 02da5a3c..1b0ae09d 100644 --- a/src/ArduinoJson/Object/JsonObjectConst.hpp +++ b/src/ArduinoJson/Object/JsonObjectConst.hpp @@ -114,13 +114,7 @@ class JsonObjectConst : public detail::VariantOperators { if (!data_ || !rhs.data_) return false; - size_t count = 0; - for (iterator it = begin(); it != end(); ++it) { - if (it->value() != rhs[it->key()]) - return false; - count++; - } - return count == rhs.size(); + return objectEquals(*data_, *rhs.data_); } private: diff --git a/src/ArduinoJson/Variant/VariantCompare.hpp b/src/ArduinoJson/Variant/VariantCompare.hpp index 8fcbd0cd..7911e48a 100644 --- a/src/ArduinoJson/Variant/VariantCompare.hpp +++ b/src/ArduinoJson/Variant/VariantCompare.hpp @@ -12,8 +12,6 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -class CollectionData; - struct ComparerBase : Visitor {}; template @@ -86,7 +84,7 @@ struct ArrayComparer : ComparerBase { explicit ArrayComparer(const CollectionData& rhs) : rhs_(&rhs) {} CompareResult visitArray(const CollectionData& lhs) { - if (JsonArrayConst(&lhs) == JsonArrayConst(rhs_)) + if (arrayEquals(lhs, *rhs_)) return COMPARE_RESULT_EQUAL; else return COMPARE_RESULT_DIFFER; @@ -99,7 +97,7 @@ struct ObjectComparer : ComparerBase { explicit ObjectComparer(const CollectionData& rhs) : rhs_(&rhs) {} CompareResult visitObject(const CollectionData& lhs) { - if (JsonObjectConst(&lhs) == JsonObjectConst(rhs_)) + if (objectEquals(lhs, *rhs_)) return COMPARE_RESULT_EQUAL; else return COMPARE_RESULT_DIFFER; @@ -204,4 +202,9 @@ CompareResult compare(ArduinoJson::JsonVariantConst lhs, const T& rhs) { return variantAccept(VariantAttorney::getData(lhs), comparer); } +inline CompareResult compare(const VariantData* lhs, const VariantData* rhs) { + VariantComparer comparer(rhs); + return variantAccept(lhs, comparer); +} + ARDUINOJSON_END_PRIVATE_NAMESPACE