Przeglądaj źródła

Return `bool` from all built-in `toJson` converters

Benoit Blanchon 6 miesięcy temu
rodzic
commit
e86c6acf2e

+ 2 - 2
src/ArduinoJson/Document/JsonDocument.hpp

@@ -412,8 +412,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
   mutable detail::VariantData data_;
 };
 
-inline void convertToJson(const JsonDocument& src, JsonVariant dst) {
-  dst.set(src.as<JsonVariantConst>());
+inline bool convertToJson(const JsonDocument& src, JsonVariant dst) {
+  return dst.set(src.as<JsonVariantConst>());
 }
 
 ARDUINOJSON_END_PUBLIC_NAMESPACE

+ 37 - 37
src/ArduinoJson/MsgPack/MsgPackBinary.hpp

@@ -24,46 +24,46 @@ class MsgPackBinary {
 
 template <>
 struct Converter<MsgPackBinary> : private detail::VariantAttorney {
-  static void toJson(MsgPackBinary src, JsonVariant dst) {
+  static bool toJson(MsgPackBinary src, JsonVariant dst) {
     auto impl = getImpl(dst);
-    auto data = impl.data();
-    if (!data)
-      return;
+    if (impl.isUnbound())
+      return false;
+
+    if (!src.data())
+      return true;
+
+    size_t headerSize = src.size() >= 0x10000 ? 5 : src.size() >= 0x100 ? 3 : 2;
+
     auto resources = impl.resources();
-    impl.clear();
-    if (src.data()) {
-      size_t headerSize = src.size() >= 0x10000 ? 5
-                          : src.size() >= 0x100 ? 3
-                                                : 2;
-      auto str = resources->createString(src.size() + headerSize);
-      if (str) {
-        resources->saveString(str);
-        auto ptr = reinterpret_cast<uint8_t*>(str->data);
-        switch (headerSize) {
-          case 2:
-            ptr[0] = uint8_t(0xc4);
-            ptr[1] = uint8_t(src.size() & 0xff);
-            break;
-          case 3:
-            ptr[0] = uint8_t(0xc5);
-            ptr[1] = uint8_t(src.size() >> 8 & 0xff);
-            ptr[2] = uint8_t(src.size() & 0xff);
-            break;
-          case 5:
-            ptr[0] = uint8_t(0xc6);
-            ptr[1] = uint8_t(src.size() >> 24 & 0xff);
-            ptr[2] = uint8_t(src.size() >> 16 & 0xff);
-            ptr[3] = uint8_t(src.size() >> 8 & 0xff);
-            ptr[4] = uint8_t(src.size() & 0xff);
-            break;
-          default:
-            ARDUINOJSON_ASSERT(false);
-        }
-        memcpy(ptr + headerSize, src.data(), src.size());
-        data->setRawString(str);
-        return;
-      }
+    auto str = resources->createString(src.size() + headerSize);
+    if (!str)
+      return false;
+    resources->saveString(str);
+
+    auto ptr = reinterpret_cast<uint8_t*>(str->data);
+    switch (headerSize) {
+      case 2:
+        ptr[0] = uint8_t(0xc4);
+        ptr[1] = uint8_t(src.size() & 0xff);
+        break;
+      case 3:
+        ptr[0] = uint8_t(0xc5);
+        ptr[1] = uint8_t(src.size() >> 8 & 0xff);
+        ptr[2] = uint8_t(src.size() & 0xff);
+        break;
+      case 5:
+        ptr[0] = uint8_t(0xc6);
+        ptr[1] = uint8_t(src.size() >> 24 & 0xff);
+        ptr[2] = uint8_t(src.size() >> 16 & 0xff);
+        ptr[3] = uint8_t(src.size() >> 8 & 0xff);
+        ptr[4] = uint8_t(src.size() & 0xff);
+        break;
+      default:
+        ARDUINOJSON_ASSERT(false);
     }
+    memcpy(ptr + headerSize, src.data(), src.size());
+    impl.data()->setRawString(str);
+    return true;
   }
 
   static MsgPackBinary fromJson(JsonVariantConst src) {

+ 48 - 45
src/ArduinoJson/MsgPack/MsgPackExtension.hpp

@@ -30,54 +30,57 @@ class MsgPackExtension {
 
 template <>
 struct Converter<MsgPackExtension> : private detail::VariantAttorney {
-  static void toJson(MsgPackExtension src, JsonVariant dst) {
+  static bool toJson(MsgPackExtension src, JsonVariant dst) {
     auto impl = getImpl(dst);
-    auto data = impl.data();
-    auto resources = impl.resources();
-    if (!data)
-      return;
+    if (impl.isUnbound())
+      return false;
+
     impl.clear();
-    if (src.data()) {
-      uint8_t format, sizeBytes;
-      if (src.size() >= 0x10000) {
-        format = 0xc9;  // ext 32
-        sizeBytes = 4;
-      } else if (src.size() >= 0x100) {
-        format = 0xc8;  // ext 16
-        sizeBytes = 2;
-      } else if (src.size() == 16) {
-        format = 0xd8;  // fixext 16
-        sizeBytes = 0;
-      } else if (src.size() == 8) {
-        format = 0xd7;  // fixext 8
-        sizeBytes = 0;
-      } else if (src.size() == 4) {
-        format = 0xd6;  // fixext 4
-        sizeBytes = 0;
-      } else if (src.size() == 2) {
-        format = 0xd5;  // fixext 2
-        sizeBytes = 0;
-      } else if (src.size() == 1) {
-        format = 0xd4;  // fixext 1
-        sizeBytes = 0;
-      } else {
-        format = 0xc7;  // ext 8
-        sizeBytes = 1;
-      }
-
-      auto str = resources->createString(src.size() + 2 + sizeBytes);
-      if (str) {
-        resources->saveString(str);
-        auto ptr = reinterpret_cast<uint8_t*>(str->data);
-        *ptr++ = uint8_t(format);
-        for (uint8_t i = 0; i < sizeBytes; i++)
-          *ptr++ = uint8_t(src.size() >> (sizeBytes - i - 1) * 8 & 0xff);
-        *ptr++ = uint8_t(src.type());
-        memcpy(ptr, src.data(), src.size());
-        data->setRawString(str);
-        return;
-      }
+
+    if (!src.data())
+      return true;
+
+    uint8_t format, sizeBytes;
+    if (src.size() >= 0x10000) {
+      format = 0xc9;  // ext 32
+      sizeBytes = 4;
+    } else if (src.size() >= 0x100) {
+      format = 0xc8;  // ext 16
+      sizeBytes = 2;
+    } else if (src.size() == 16) {
+      format = 0xd8;  // fixext 16
+      sizeBytes = 0;
+    } else if (src.size() == 8) {
+      format = 0xd7;  // fixext 8
+      sizeBytes = 0;
+    } else if (src.size() == 4) {
+      format = 0xd6;  // fixext 4
+      sizeBytes = 0;
+    } else if (src.size() == 2) {
+      format = 0xd5;  // fixext 2
+      sizeBytes = 0;
+    } else if (src.size() == 1) {
+      format = 0xd4;  // fixext 1
+      sizeBytes = 0;
+    } else {
+      format = 0xc7;  // ext 8
+      sizeBytes = 1;
     }
+
+    auto resources = impl.resources();
+    auto str = resources->createString(src.size() + 2 + sizeBytes);
+    if (!str)
+      return false;
+    resources->saveString(str);
+
+    auto ptr = reinterpret_cast<uint8_t*>(str->data);
+    *ptr++ = uint8_t(format);
+    for (uint8_t i = 0; i < sizeBytes; i++)
+      *ptr++ = uint8_t(src.size() >> (sizeBytes - i - 1) * 8 & 0xff);
+    *ptr++ = uint8_t(src.type());
+    memcpy(ptr, src.data(), src.size());
+    impl.data()->setRawString(str);
+    return true;
   }
 
   static MsgPackExtension fromJson(JsonVariantConst src) {

+ 3 - 0
src/ArduinoJson/Object/ObjectImpl.hpp

@@ -55,6 +55,9 @@ inline VariantData* VariantImpl::addMember(TAdaptedString key) {
   if (!isObject())
     return nullptr;
 
+  if (key.isNull())
+    return nullptr;  // Ignore null key
+
   auto keySlot = allocVariant();
   if (!keySlot)
     return nullptr;

+ 37 - 32
src/ArduinoJson/Variant/ConverterImpl.hpp

@@ -25,9 +25,10 @@ struct Converter {
                 "type 'char' is not supported, use 'signed char', 'unsigned "
                 "char' or another integer type instead");
 
-  static void toJson(const T& src, JsonVariant dst) {
+  static auto toJson(const T& src, JsonVariant dst)
+      -> decltype(convertToJson(src, dst)) {
     // clang-format off
-    convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
+    return convertToJson(src, dst); // Error here? See https://arduinojson.org/v7/unsupported-set/
     // clang-format on
   }
 
@@ -60,9 +61,9 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
     : private detail::VariantAttorney {
   static bool toJson(T src, JsonVariant dst) {
     ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
-    auto variant = getImpl(dst);
-    variant.clear();
-    return variant.setInteger(src);
+    auto impl = getImpl(dst);
+    impl.clear();
+    return impl.setInteger(src);
   }
 
   static T fromJson(JsonVariantConst src) {
@@ -128,10 +129,10 @@ struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
 
 template <>
 struct Converter<const char*> : private detail::VariantAttorney {
-  static void toJson(const char* src, JsonVariant dst) {
+  static bool toJson(const char* src, JsonVariant dst) {
     auto impl = getImpl(dst);
     impl.clear();
-    impl.setString(detail::adaptString(src));
+    return impl.setString(detail::adaptString(src));
   }
 
   static const char* fromJson(JsonVariantConst src) {
@@ -145,10 +146,10 @@ struct Converter<const char*> : private detail::VariantAttorney {
 
 template <>
 struct Converter<JsonString> : private detail::VariantAttorney {
-  static void toJson(JsonString src, JsonVariant dst) {
+  static bool toJson(JsonString src, JsonVariant dst) {
     auto impl = getImpl(dst);
     impl.clear();
-    impl.setString(detail::adaptString(src));
+    return impl.setString(detail::adaptString(src));
   }
 
   static JsonString fromJson(JsonVariantConst src) {
@@ -161,11 +162,11 @@ struct Converter<JsonString> : private detail::VariantAttorney {
 };
 
 template <typename T>
-inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
+inline detail::enable_if_t<detail::IsString<T>::value, bool> convertToJson(
     const T& src, JsonVariant dst) {
-  auto variant = detail::VariantAttorney::getImpl(dst);
-  variant.clear();
-  variant.setString(detail::adaptString(src));
+  auto impl = detail::VariantAttorney::getImpl(dst);
+  impl.clear();
+  return impl.setString(detail::adaptString(src));
 }
 
 // SerializedValue<std::string>
@@ -174,16 +175,19 @@ inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
 template <typename T>
 struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
   static bool toJson(SerializedValue<T> src, JsonVariant dst) {
-    auto variant = getImpl(dst);
-    variant.clear();
-    return variant.setRawString(detail::adaptString(src.data(), src.size()));
+    auto impl = getImpl(dst);
+    impl.clear();
+    return impl.setRawString(detail::adaptString(src.data(), src.size()));
   }
 };
 
 template <>
 struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
-  static void toJson(detail::nullptr_t, JsonVariant dst) {
+  static bool toJson(detail::nullptr_t, JsonVariant dst) {
+    if (dst.isUnbound())
+      return false;
     getImpl(dst).clear();
+    return true;
   }
   static detail::nullptr_t fromJson(JsonVariantConst) {
     return nullptr;
@@ -230,16 +234,17 @@ class StringBuilderPrint : public Print {
 };
 }  // namespace detail
 
-inline void convertToJson(const ::Printable& src, JsonVariant dst) {
+inline bool convertToJson(const ::Printable& src, JsonVariant dst) {
   auto impl = detail::VariantAttorney::getImpl(dst);
   if (impl.isUnbound())
-    return;
+    return false;
   impl.clear();
   detail::StringBuilderPrint print(impl.resources());
   src.printTo(print);
   if (print.overflowed())
-    return;
+    return false;
   print.save(impl.data());
+  return true;
 }
 
 #endif
@@ -292,11 +297,11 @@ inline bool canConvertFromJson(JsonVariantConst src, const std::string_view&) {
 
 template <>
 struct Converter<JsonArrayConst> : private detail::VariantAttorney {
-  static void toJson(JsonArrayConst src, JsonVariant dst) {
+  static bool toJson(JsonArrayConst src, JsonVariant dst) {
     if (src.isNull())
-      dst.set(nullptr);
+      return dst.set(nullptr);
     else
-      dst.to<JsonArray>().set(src);
+      return dst.to<JsonArray>().set(src);
   }
 
   static JsonArrayConst fromJson(JsonVariantConst src) {
@@ -310,11 +315,11 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
 
 template <>
 struct Converter<JsonArray> : private detail::VariantAttorney {
-  static void toJson(JsonVariantConst src, JsonVariant dst) {
+  static bool toJson(JsonVariantConst src, JsonVariant dst) {
     if (src.isNull())
-      dst.set(nullptr);
+      return dst.set(nullptr);
     else
-      dst.to<JsonArray>().set(src);
+      return dst.to<JsonArray>().set(src);
   }
 
   static JsonArray fromJson(JsonVariant src) {
@@ -328,11 +333,11 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
 
 template <>
 struct Converter<JsonObjectConst> : private detail::VariantAttorney {
-  static void toJson(JsonVariantConst src, JsonVariant dst) {
+  static bool toJson(JsonVariantConst src, JsonVariant dst) {
     if (src.isNull())
-      dst.set(nullptr);
+      return dst.set(nullptr);
     else
-      dst.to<JsonObject>().set(src);
+      return dst.to<JsonObject>().set(src);
   }
 
   static JsonObjectConst fromJson(JsonVariantConst src) {
@@ -346,11 +351,11 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
 
 template <>
 struct Converter<JsonObject> : private detail::VariantAttorney {
-  static void toJson(JsonVariantConst src, JsonVariant dst) {
+  static bool toJson(JsonVariantConst src, JsonVariant dst) {
     if (src.isNull())
-      dst.set(nullptr);
+      return dst.set(nullptr);
     else
-      dst.to<JsonObject>().set(src);
+      return dst.to<JsonObject>().set(src);
   }
 
   static JsonObject fromJson(JsonVariant src) {

+ 4 - 4
src/ArduinoJson/Variant/JsonVariant.hpp

@@ -43,8 +43,8 @@ bool copyVariant(JsonVariant dst, JsonVariantConst src);
 
 template <>
 struct Converter<JsonVariant> : private detail::VariantAttorney {
-  static void toJson(JsonVariantConst src, JsonVariant dst) {
-    copyVariant(dst, src);
+  static bool toJson(JsonVariantConst src, JsonVariant dst) {
+    return copyVariant(dst, src);
   }
 
   static JsonVariant fromJson(JsonVariant src) {
@@ -58,8 +58,8 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
 
 template <>
 struct Converter<JsonVariantConst> : private detail::VariantAttorney {
-  static void toJson(JsonVariantConst src, JsonVariant dst) {
-    copyVariant(dst, src);
+  static bool toJson(JsonVariantConst src, JsonVariant dst) {
+    return copyVariant(dst, src);
   }
 
   static JsonVariantConst fromJson(JsonVariantConst src) {

+ 1 - 1
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -468,7 +468,7 @@ class VariantImpl {
       return false;
 
     if (value.isNull())
-      return false;
+      return true;
 
     if (value.isStatic())
       return setLinkedString(value.data());

+ 2 - 2
src/ArduinoJson/Variant/VariantRefBaseImpl.hpp

@@ -61,9 +61,9 @@ inline JsonObject VariantRefBase<TDerived>::createNestedObject(
 }
 
 template <typename TDerived>
-inline void convertToJson(const VariantRefBase<TDerived>& src,
+inline bool convertToJson(const VariantRefBase<TDerived>& src,
                           JsonVariant dst) {
-  dst.set(src.template as<JsonVariantConst>());
+  return dst.set(src.template as<JsonVariantConst>());
 }
 
 template <typename TDerived>