summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Variant/ConverterImpl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/Variant/ConverterImpl.hpp')
-rw-r--r--include/lib/ArduinoJson/Variant/ConverterImpl.hpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Variant/ConverterImpl.hpp b/include/lib/ArduinoJson/Variant/ConverterImpl.hpp
new file mode 100644
index 0000000..34e12bb
--- /dev/null
+++ b/include/lib/ArduinoJson/Variant/ConverterImpl.hpp
@@ -0,0 +1,268 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Strings/IsWriteableString.hpp>
+#include <ArduinoJson/Variant/VariantFunctions.hpp>
+#include <ArduinoJson/Variant/VariantRef.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename T, typename Enable>
+struct Converter {
+ static bool toJson(const T& src, VariantRef dst) {
+ // clang-format off
+ return convertToJson(src, dst); // Error here? See https://arduinojson.org/v6/unsupported-set/
+ // clang-format on
+ }
+
+ static T fromJson(VariantConstRef src) {
+ // clang-format off
+ T result; // Error here? See https://arduinojson.org/v6/non-default-constructible/
+ convertFromJson(src, result); // Error here? See https://arduinojson.org/v6/unsupported-as/
+ // clang-format on
+ return result;
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ T dummy;
+ // clang-format off
+ return canConvertFromJson(src, dummy); // Error here? See https://arduinojson.org/v6/unsupported-is/
+ // clang-format on
+ }
+};
+
+template <typename T>
+struct Converter<
+ T, typename enable_if<is_integral<T>::value && !is_same<bool, T>::value &&
+ !is_same<char, T>::value>::type> {
+ static bool toJson(T src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
+ if (!data)
+ return false;
+ data->setInteger(src);
+ return true;
+ }
+
+ static T fromJson(VariantConstRef src) {
+ ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
+ const VariantData* data = getData(src);
+ return data ? data->asIntegral<T>() : T();
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isInteger<T>();
+ }
+};
+
+template <typename T>
+struct Converter<T, typename enable_if<is_enum<T>::value>::type> {
+ static bool toJson(T src, VariantRef dst) {
+ return dst.set(static_cast<Integer>(src));
+ }
+
+ static T fromJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data ? static_cast<T>(data->asIntegral<int>()) : T();
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isInteger<int>();
+ }
+};
+
+template <>
+struct Converter<bool> {
+ static bool toJson(bool src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ if (!data)
+ return false;
+ data->setBoolean(src);
+ return true;
+ }
+
+ static bool fromJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data ? data->asBoolean() : false;
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isBoolean();
+ }
+};
+
+template <typename T>
+struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
+ static bool toJson(T src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ if (!data)
+ return false;
+ data->setFloat(static_cast<Float>(src));
+ return true;
+ }
+
+ static T fromJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data ? data->asFloat<T>() : false;
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isFloat();
+ }
+};
+
+template <>
+struct Converter<const char*> {
+ static bool toJson(const char* src, VariantRef dst) {
+ return variantSetString(getData(dst), adaptString(src), getPool(dst));
+ }
+
+ static const char* fromJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data ? data->asString() : 0;
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isString();
+ }
+};
+
+template <typename T>
+inline typename enable_if<IsString<T>::value, bool>::type convertToJson(
+ const T& src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ MemoryPool* pool = getPool(dst);
+ return variantSetString(data, adaptString(src), pool);
+}
+
+template <typename T>
+inline typename enable_if<IsWriteableString<T>::value>::type convertFromJson(
+ VariantConstRef src, T& dst) {
+ const VariantData* data = getData(src);
+ const char* cstr = data != 0 ? data->asString() : 0;
+ if (cstr)
+ dst = cstr;
+ else
+ serializeJson(src, dst);
+}
+
+template <typename T>
+inline typename enable_if<IsWriteableString<T>::value, bool>::type
+canConvertFromJson(VariantConstRef src, const T&) {
+ const VariantData* data = getData(src);
+ return data && data->isString();
+}
+
+template <>
+struct Converter<SerializedValue<const char*> > {
+ static bool toJson(SerializedValue<const char*> src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ if (!data)
+ return false;
+ data->setLinkedRaw(src);
+ return true;
+ }
+};
+
+// SerializedValue<std::string>
+// SerializedValue<String>
+// SerializedValue<const __FlashStringHelper*>
+template <typename T>
+struct Converter<SerializedValue<T>,
+ typename enable_if<!is_same<const char*, T>::value>::type> {
+ static bool toJson(SerializedValue<T> src, VariantRef dst) {
+ VariantData* data = getData(dst);
+ MemoryPool* pool = getPool(dst);
+ return data != 0 && data->setOwnedRaw(src, pool);
+ }
+};
+
+#if ARDUINOJSON_HAS_NULLPTR
+
+template <>
+struct Converter<decltype(nullptr)> {
+ static bool toJson(decltype(nullptr), VariantRef dst) {
+ variantSetNull(getData(dst));
+ return true;
+ }
+ static decltype(nullptr) fromJson(VariantConstRef) {
+ return nullptr;
+ }
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data == 0 || data->isNull();
+ }
+};
+
+#endif
+
+#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
+
+class MemoryPoolPrint : public Print {
+ public:
+ MemoryPoolPrint(MemoryPool* pool) : _pool(pool), _size(0) {
+ pool->getFreeZone(&_string, &_capacity);
+ }
+
+ const char* c_str() {
+ _string[_size++] = 0;
+ ARDUINOJSON_ASSERT(_size <= _capacity);
+ return _pool->saveStringFromFreeZone(_size);
+ }
+
+ size_t write(uint8_t c) {
+ if (_size >= _capacity)
+ return 0;
+
+ _string[_size++] = char(c);
+ return 1;
+ }
+
+ size_t write(const uint8_t* buffer, size_t size) {
+ if (_size + size >= _capacity) {
+ _size = _capacity; // mark as overflowed
+ return 0;
+ }
+ memcpy(&_string[_size], buffer, size);
+ _size += size;
+ return size;
+ }
+
+ bool overflowed() const {
+ return _size >= _capacity;
+ }
+
+ private:
+ MemoryPool* _pool;
+ size_t _size;
+ char* _string;
+ size_t _capacity;
+};
+
+inline bool convertToJson(const ::Printable& src, VariantRef dst) {
+ MemoryPool* pool = getPool(dst);
+ VariantData* data = getData(dst);
+ if (!pool || !data)
+ return false;
+ MemoryPoolPrint print(pool);
+ src.printTo(print);
+ if (print.overflowed()) {
+ pool->markAsOverflowed();
+ data->setNull();
+ return false;
+ }
+ data->setStringPointer(print.c_str(), storage_policies::store_by_copy());
+ return true;
+}
+
+#endif
+
+} // namespace ARDUINOJSON_NAMESPACE