Преглед изворни кода

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

Benoit Blanchon пре 3 месеци
родитељ
комит
bec657eda7

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

@@ -446,8 +446,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 - 34
src/ArduinoJson/MsgPack/MsgPackBinary.hpp

@@ -24,45 +24,48 @@ class MsgPackBinary {
 
 template <>
 struct Converter<MsgPackBinary> : private detail::VariantAttorney {
-  static void toJson(MsgPackBinary src, JsonVariant dst) {
+  static bool toJson(MsgPackBinary src, JsonVariant dst) {
     auto data = VariantAttorney::getData(dst);
     if (!data)
-      return;
+      return false;
+
     auto resources = getResourceManager(dst);
     detail::VariantImpl::clear(data, resources);
-    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;
-      }
+
+    if (!src.data())
+      return true;
+
+    size_t headerSize = src.size() >= 0x10000 ? 5 : src.size() >= 0x100 ? 3 : 2;
+
+    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());
+    data->setRawString(str);
+    return true;
   }
 
   static MsgPackBinary fromJson(JsonVariantConst src) {

+ 46 - 42
src/ArduinoJson/MsgPack/MsgPackExtension.hpp

@@ -30,53 +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 data = getData(dst);
     if (!data)
-      return;
+      return false;
+
     auto resources = getResourceManager(dst);
     detail::VariantImpl::clear(data, resources);
-    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 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());
+    data->setRawString(str);
+    return true;
   }
 
   static MsgPackExtension fromJson(JsonVariantConst src) {

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

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

+ 23 - 21
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
   }
 
@@ -124,8 +125,8 @@ 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) {
-    getVariantImpl(dst).setString(detail::adaptString(src));
+  static bool toJson(const char* src, JsonVariant dst) {
+    return getVariantImpl(dst).setString(detail::adaptString(src));
   }
 
   static const char* fromJson(JsonVariantConst src) {
@@ -176,8 +177,8 @@ struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
 
 template <>
 struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
-  static void toJson(detail::nullptr_t, JsonVariant dst) {
-    getVariantImpl(dst).clear();
+  static bool toJson(detail::nullptr_t, JsonVariant dst) {
+    return getVariantImpl(dst).clear();
   }
   static detail::nullptr_t fromJson(JsonVariantConst) {
     return nullptr;
@@ -225,17 +226,18 @@ class StringBuilderPrint : public Print {
 };
 }  // namespace detail
 
-inline void convertToJson(const ::Printable& src, JsonVariant dst) {
+inline bool convertToJson(const ::Printable& src, JsonVariant dst) {
   auto resources = detail::VariantAttorney::getResourceManager(dst);
   auto data = detail::VariantAttorney::getData(dst);
   if (!resources || !data)
-    return;
+    return false;
   detail::VariantImpl::clear(data, resources);
   detail::StringBuilderPrint print(resources);
   src.printTo(print);
   if (print.overflowed())
-    return;
+    return false;
   print.save(data);
+  return true;
 }
 
 #endif
@@ -288,11 +290,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) {
@@ -307,11 +309,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) {
@@ -326,11 +328,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) {
@@ -345,11 +347,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

@@ -47,8 +47,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) {
@@ -63,8 +63,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) {

+ 6 - 4
src/ArduinoJson/Variant/VariantImpl.hpp

@@ -515,7 +515,7 @@ class VariantImpl {
     ARDUINOJSON_ASSERT(resources != nullptr);
 
     if (value.isNull())
-      return false;
+      return true;  // TODO: should this be moved up to the member function?
 
     if (isTinyString(value, value.size())) {
       data->setTinyString(value);
@@ -577,9 +577,11 @@ class VariantImpl {
   }
 
   // Release the resources used by this variant and set it to null.
-  void clear() {
-    if (data_)
-      clear(data_, resources_);
+  bool clear() {
+    if (!data_)
+      return false;
+    clear(data_, resources_);
+    return true;
   }
 
   static void clear(VariantData* data, ResourceManager* resources) {

+ 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>