Kaynağa Gözat

Store adapted string in MemberProxy

Benoit Blanchon 1 yıl önce
ebeveyn
işleme
5e7653b36a

+ 8 - 11
extras/tests/JsonDocument/MemberProxy.cpp

@@ -14,12 +14,9 @@
 using ArduinoJson::detail::sizeofArray;
 using ArduinoJson::detail::sizeofObject;
 
-using MemberProxy =
-    ArduinoJson::detail::MemberProxy<JsonDocument&, const char*>;
-
 TEST_CASE("MemberProxy::add()") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("add(int)") {
     mp.add(42);
@@ -48,7 +45,7 @@ TEST_CASE("MemberProxy::add()") {
 
 TEST_CASE("MemberProxy::clear()") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("size goes back to zero") {
     mp.add(42);
@@ -139,7 +136,7 @@ TEST_CASE("MemberProxy::operator|()") {
 
 TEST_CASE("MemberProxy::remove()") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("remove(int)") {
     mp.add(1);
@@ -186,7 +183,7 @@ TEST_CASE("MemberProxy::remove()") {
 
 TEST_CASE("MemberProxy::set()") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("set(int)") {
     mp.set(42);
@@ -223,7 +220,7 @@ TEST_CASE("MemberProxy::set()") {
 
 TEST_CASE("MemberProxy::size()") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("returns 0") {
     REQUIRE(mp.size() == 0);
@@ -246,7 +243,7 @@ TEST_CASE("MemberProxy::size()") {
 
 TEST_CASE("MemberProxy::operator[]") {
   JsonDocument doc;
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   SECTION("set member") {
     mp["world"] = 42;
@@ -265,7 +262,7 @@ TEST_CASE("MemberProxy cast to JsonVariantConst") {
   JsonDocument doc;
   doc["hello"] = "world";
 
-  const MemberProxy mp = doc["hello"];
+  const auto mp = doc["hello"];
 
   JsonVariantConst var = mp;
 
@@ -276,7 +273,7 @@ TEST_CASE("MemberProxy cast to JsonVariant") {
   JsonDocument doc;
   doc["hello"] = "world";
 
-  MemberProxy mp = doc["hello"];
+  auto mp = doc["hello"];
 
   JsonVariant var = mp;
 

+ 8 - 6
src/ArduinoJson/Document/JsonDocument.hpp

@@ -186,19 +186,21 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   // Gets or sets a root object's member.
   // https://arduinojson.org/v7/api/jsondocument/subscript/
   template <typename TString>
-  detail::enable_if_t<detail::IsString<TString>::value,
-                      detail::MemberProxy<JsonDocument&, TString>>
+  detail::enable_if_t<
+      detail::IsString<TString>::value,
+      detail::MemberProxy<JsonDocument&, detail::AdaptedString<TString>>>
   operator[](const TString& key) {
-    return {*this, key};
+    return {*this, detail::adaptString(key)};
   }
 
   // Gets or sets a root object's member.
   // https://arduinojson.org/v7/api/jsondocument/subscript/
   template <typename TChar>
-  detail::enable_if_t<detail::IsString<TChar*>::value,
-                      detail::MemberProxy<JsonDocument&, TChar*>>
+  detail::enable_if_t<
+      detail::IsString<TChar*>::value,
+      detail::MemberProxy<JsonDocument&, detail::AdaptedString<TChar*>>>
   operator[](TChar* key) {
-    return {*this, key};
+    return {*this, detail::adaptString(key)};
   }
 
   // Gets a root object's member.

+ 12 - 12
src/ArduinoJson/Object/JsonObject.hpp

@@ -102,31 +102,31 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
   // Gets or sets the member with specified key.
   // https://arduinojson.org/v7/api/jsonobject/subscript/
   template <typename TString>
-  detail::enable_if_t<detail::IsString<TString>::value,
-                      detail::MemberProxy<JsonObject, TString>>
+  detail::enable_if_t<
+      detail::IsString<TString>::value,
+      detail::MemberProxy<JsonObject, detail::AdaptedString<TString>>>
   operator[](const TString& key) const {
-    return {*this, key};
+    return {*this, detail::adaptString(key)};
   }
 
   // Gets or sets the member with specified key.
   // https://arduinojson.org/v7/api/jsonobject/subscript/
   template <typename TChar>
-  detail::enable_if_t<detail::IsString<TChar*>::value,
-                      detail::MemberProxy<JsonObject, TChar*>>
+  detail::enable_if_t<
+      detail::IsString<TChar*>::value,
+      detail::MemberProxy<JsonObject, detail::AdaptedString<TChar*>>>
   operator[](TChar* key) const {
-    return {*this, key};
+    return {*this, detail::adaptString(key)};
   }
 
   // Gets or sets the member with specified key.
   // https://arduinojson.org/v7/api/jsonobject/subscript/
   template <typename TVariant>
-  detail::enable_if_t<detail::IsVariant<TVariant>::value,
-                      detail::MemberProxy<JsonObject, JsonString>>
+  detail::enable_if_t<
+      detail::IsVariant<TVariant>::value,
+      detail::MemberProxy<JsonObject, detail::AdaptedString<JsonString>>>
   operator[](const TVariant& key) const {
-    if (key.template is<JsonString>())
-      return {*this, key.template as<JsonString>()};
-    else
-      return {*this, nullptr};
+    return {*this, detail::adaptString(key.template as<JsonString>())};
   }
 
   // Removes the member at the specified iterator.

+ 7 - 7
src/ArduinoJson/Object/MemberProxy.hpp

@@ -10,14 +10,14 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
 
 // A proxy class to get or set a member of an object.
 // https://arduinojson.org/v7/api/jsonobject/subscript/
-template <typename TUpstream, typename TStringRef>
+template <typename TUpstream, typename AdaptedString>
 class MemberProxy
-    : public VariantRefBase<MemberProxy<TUpstream, TStringRef>>,
-      public VariantOperators<MemberProxy<TUpstream, TStringRef>> {
+    : public VariantRefBase<MemberProxy<TUpstream, AdaptedString>>,
+      public VariantOperators<MemberProxy<TUpstream, AdaptedString>> {
   friend class VariantAttorney;
 
  public:
-  MemberProxy(TUpstream upstream, TStringRef key)
+  MemberProxy(TUpstream upstream, AdaptedString key)
       : upstream_(upstream), key_(key) {}
 
   MemberProxy(const MemberProxy& src)
@@ -47,7 +47,7 @@ class MemberProxy
 
   VariantData* getData() const {
     return VariantData::getMember(
-        VariantAttorney::getData(upstream_), adaptString(key_),
+        VariantAttorney::getData(upstream_), key_,
         VariantAttorney::getResourceManager(upstream_));
   }
 
@@ -55,13 +55,13 @@ class MemberProxy
     auto data = VariantAttorney::getOrCreateData(upstream_);
     if (!data)
       return nullptr;
-    return data->getOrAddMember(adaptString(key_),
+    return data->getOrAddMember(key_,
                                 VariantAttorney::getResourceManager(upstream_));
   }
 
  private:
   TUpstream upstream_;
-  TStringRef key_;
+  AdaptedString key_;
 };
 
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 4 - 0
src/ArduinoJson/Strings/StringAdapters.hpp

@@ -70,4 +70,8 @@ static void stringGetChars(TAdaptedString s, char* p, size_t n) {
   }
 }
 
+template <typename T>
+using AdaptedString =
+    typename StringAdapter<remove_reference_t<T>>::AdaptedString;
+
 ARDUINOJSON_END_PRIVATE_NAMESPACE

+ 6 - 6
src/ArduinoJson/Variant/VariantRefBase.hpp

@@ -188,16 +188,16 @@ class VariantRefBase : public VariantTag {
   // Gets or sets an object member.
   // https://arduinojson.org/v7/api/jsonvariant/subscript/
   template <typename TString>
-  FORCE_INLINE
-      enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
-      operator[](const TString& key) const;
+  FORCE_INLINE enable_if_t<IsString<TString>::value,
+                           MemberProxy<TDerived, AdaptedString<TString>>>
+  operator[](const TString& key) const;
 
   // Gets or sets an object member.
   // https://arduinojson.org/v7/api/jsonvariant/subscript/
   template <typename TChar>
-  FORCE_INLINE
-      enable_if_t<IsString<TChar*>::value, MemberProxy<TDerived, TChar*>>
-      operator[](TChar* key) const;
+  FORCE_INLINE enable_if_t<IsString<TChar*>::value,
+                           MemberProxy<TDerived, AdaptedString<TChar*>>>
+  operator[](TChar* key) const;
 
   // Gets an object member or an array element.
   // https://arduinojson.org/v7/api/jsonvariant/subscript/

+ 8 - 6
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

@@ -123,17 +123,19 @@ inline ElementProxy<TDerived> VariantRefBase<TDerived>::operator[](
 }
 
 template <typename TDerived>
-template <typename TString>
-inline enable_if_t<IsString<TString*>::value, MemberProxy<TDerived, TString*>>
-VariantRefBase<TDerived>::operator[](TString* key) const {
-  return MemberProxy<TDerived, TString*>(derived(), key);
+template <typename TChar>
+inline enable_if_t<IsString<TChar*>::value,
+                   MemberProxy<TDerived, AdaptedString<TChar*>>>
+VariantRefBase<TDerived>::operator[](TChar* key) const {
+  return {derived(), adaptString(key)};
 }
 
 template <typename TDerived>
 template <typename TString>
-inline enable_if_t<IsString<TString>::value, MemberProxy<TDerived, TString>>
+inline enable_if_t<IsString<TString>::value,
+                   MemberProxy<TDerived, AdaptedString<TString>>>
 VariantRefBase<TDerived>::operator[](const TString& key) const {
-  return MemberProxy<TDerived, TString>(derived(), key);
+  return {derived(), adaptString(key)};
 }
 
 template <typename TDerived>