Return bool from all built-in toJson converters

This commit is contained in:
Benoit Blanchon
2025-07-17 22:11:36 +02:00
parent 0021ec81d1
commit e86c6acf2e
8 changed files with 134 additions and 123 deletions

View File

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

View File

@ -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) {

View File

@ -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;
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;
}
if (impl.isUnbound())
return false;
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;
}
impl.clear();
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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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) {

View File

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

View File

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