summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/MsgPack
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/MsgPack')
-rw-r--r--include/lib/ArduinoJson/MsgPack/MsgPackDeserializer.hpp599
-rw-r--r--include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp212
-rw-r--r--include/lib/ArduinoJson/MsgPack/endianess.hpp41
-rw-r--r--include/lib/ArduinoJson/MsgPack/ieee754.hpp18
4 files changed, 870 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/include/lib/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
new file mode 100644
index 0000000..49c6fd4
--- /dev/null
+++ b/include/lib/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
@@ -0,0 +1,599 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Deserialization/deserialize.hpp>
+#include <ArduinoJson/Memory/MemoryPool.hpp>
+#include <ArduinoJson/MsgPack/endianess.hpp>
+#include <ArduinoJson/MsgPack/ieee754.hpp>
+#include <ArduinoJson/Polyfills/type_traits.hpp>
+#include <ArduinoJson/Variant/VariantData.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename TReader, typename TStringStorage>
+class MsgPackDeserializer {
+ public:
+ MsgPackDeserializer(MemoryPool &pool, TReader reader,
+ TStringStorage stringStorage)
+ : _pool(&pool),
+ _reader(reader),
+ _stringStorage(stringStorage),
+ _error(DeserializationError::Ok),
+ _foundSomething(false) {}
+
+ template <typename TFilter>
+ DeserializationError parse(VariantData &variant, TFilter filter,
+ NestingLimit nestingLimit) {
+ parseVariant(&variant, filter, nestingLimit);
+ return _foundSomething ? _error : DeserializationError::EmptyInput;
+ }
+
+ private:
+ // Prevent VS warning "assignment operator could not be generated"
+ MsgPackDeserializer &operator=(const MsgPackDeserializer &);
+
+ bool invalidInput() {
+ _error = DeserializationError::InvalidInput;
+ return false;
+ }
+
+ template <typename TFilter>
+ bool parseVariant(VariantData *variant, TFilter filter,
+ NestingLimit nestingLimit) {
+ uint8_t code = 0; // TODO: why do we need to initialize this variable?
+ if (!readByte(code))
+ return false;
+
+ _foundSomething = true;
+
+ bool allowValue = filter.allowValue();
+
+ switch (code) {
+ case 0xc0:
+ // already null
+ return true;
+
+ case 0xc1:
+ return invalidInput();
+
+ case 0xc2:
+ if (allowValue)
+ variant->setBoolean(false);
+ return true;
+
+ case 0xc3:
+ if (allowValue)
+ variant->setBoolean(true);
+ return true;
+
+ case 0xc4: // bin 8 (not supported)
+ return skipString<uint8_t>();
+
+ case 0xc5: // bin 16 (not supported)
+ return skipString<uint16_t>();
+
+ case 0xc6: // bin 32 (not supported)
+ return skipString<uint32_t>();
+
+ case 0xc7: // ext 8 (not supported)
+ return skipExt<uint8_t>();
+
+ case 0xc8: // ext 16 (not supported)
+ return skipExt<uint16_t>();
+
+ case 0xc9: // ext 32 (not supported)
+ return skipExt<uint32_t>();
+
+ case 0xca:
+ if (allowValue)
+ return readFloat<float>(variant);
+ else
+ return skipBytes(4);
+
+ case 0xcb:
+ if (allowValue)
+ return readDouble<double>(variant);
+ else
+ return skipBytes(8);
+
+ case 0xcc:
+ if (allowValue)
+ return readInteger<uint8_t>(variant);
+ else
+ return skipBytes(1);
+
+ case 0xcd:
+ if (allowValue)
+ return readInteger<uint16_t>(variant);
+ else
+ return skipBytes(2);
+
+ case 0xce:
+ if (allowValue)
+ return readInteger<uint32_t>(variant);
+ else
+ return skipBytes(4);
+
+ case 0xcf:
+#if ARDUINOJSON_USE_LONG_LONG
+ if (allowValue)
+ return readInteger<uint64_t>(variant);
+ else
+ return skipBytes(8);
+#else
+ return skipBytes(8); // not supported
+#endif
+
+ case 0xd0:
+ if (allowValue)
+ return readInteger<int8_t>(variant);
+ else
+ return skipBytes(1);
+
+ case 0xd1:
+ if (allowValue)
+ return readInteger<int16_t>(variant);
+ else
+ return skipBytes(2);
+
+ case 0xd2:
+ if (allowValue)
+ return readInteger<int32_t>(variant);
+ else
+ return skipBytes(4);
+
+ case 0xd3:
+#if ARDUINOJSON_USE_LONG_LONG
+ if (allowValue)
+ return readInteger<int64_t>(variant);
+ else
+ return skipBytes(8); // not supported
+#else
+ return skipBytes(8);
+#endif
+
+ case 0xd4: // fixext 1 (not supported)
+ return skipBytes(2);
+
+ case 0xd5: // fixext 2 (not supported)
+ return skipBytes(3);
+
+ case 0xd6: // fixext 4 (not supported)
+ return skipBytes(5);
+
+ case 0xd7: // fixext 8 (not supported)
+ return skipBytes(9);
+
+ case 0xd8: // fixext 16 (not supported)
+ return skipBytes(17);
+
+ case 0xd9:
+ if (allowValue)
+ return readString<uint8_t>(variant);
+ else
+ return skipString<uint8_t>();
+
+ case 0xda:
+ if (allowValue)
+ return readString<uint16_t>(variant);
+ else
+ return skipString<uint16_t>();
+
+ case 0xdb:
+ if (allowValue)
+ return readString<uint32_t>(variant);
+ else
+ return skipString<uint32_t>();
+
+ case 0xdc:
+ return readArray<uint16_t>(variant, filter, nestingLimit);
+
+ case 0xdd:
+ return readArray<uint32_t>(variant, filter, nestingLimit);
+
+ case 0xde:
+ return readObject<uint16_t>(variant, filter, nestingLimit);
+
+ case 0xdf:
+ return readObject<uint32_t>(variant, filter, nestingLimit);
+ }
+
+ switch (code & 0xf0) {
+ case 0x80:
+ return readObject(variant, code & 0x0F, filter, nestingLimit);
+
+ case 0x90:
+ return readArray(variant, code & 0x0F, filter, nestingLimit);
+ }
+
+ if ((code & 0xe0) == 0xa0) {
+ if (allowValue)
+ return readString(variant, code & 0x1f);
+ else
+ return skipBytes(code & 0x1f);
+ }
+
+ if (allowValue)
+ variant->setInteger(static_cast<int8_t>(code));
+
+ return true;
+ }
+
+ bool readByte(uint8_t &value) {
+ int c = _reader.read();
+ if (c < 0) {
+ _error = DeserializationError::IncompleteInput;
+ return false;
+ }
+ value = static_cast<uint8_t>(c);
+ return true;
+ }
+
+ bool readBytes(uint8_t *p, size_t n) {
+ if (_reader.readBytes(reinterpret_cast<char *>(p), n) == n)
+ return true;
+ _error = DeserializationError::IncompleteInput;
+ return false;
+ }
+
+ template <typename T>
+ bool readBytes(T &value) {
+ return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
+ }
+
+ bool skipBytes(size_t n) {
+ for (; n; --n) {
+ if (_reader.read() < 0) {
+ _error = DeserializationError::IncompleteInput;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template <typename T>
+ bool readInteger(T &value) {
+ if (!readBytes(value))
+ return false;
+ fixEndianess(value);
+ return true;
+ }
+
+ template <typename T>
+ bool readInteger(VariantData *variant) {
+ T value;
+ if (!readInteger(value))
+ return false;
+ variant->setInteger(value);
+ return true;
+ }
+
+ template <typename T>
+ typename enable_if<sizeof(T) == 4, bool>::type readFloat(
+ VariantData *variant) {
+ T value;
+ if (!readBytes(value))
+ return false;
+ fixEndianess(value);
+ variant->setFloat(value);
+ return true;
+ }
+
+ template <typename T>
+ typename enable_if<sizeof(T) == 8, bool>::type readDouble(
+ VariantData *variant) {
+ T value;
+ if (!readBytes(value))
+ return false;
+ fixEndianess(value);
+ variant->setFloat(value);
+ return true;
+ }
+
+ template <typename T>
+ typename enable_if<sizeof(T) == 4, bool>::type readDouble(
+ VariantData *variant) {
+ uint8_t i[8]; // input is 8 bytes
+ T value; // output is 4 bytes
+ uint8_t *o = reinterpret_cast<uint8_t *>(&value);
+ if (!readBytes(i, 8))
+ return false;
+ doubleToFloat(i, o);
+ fixEndianess(value);
+ variant->setFloat(value);
+ return true;
+ }
+
+ template <typename T>
+ bool readString(VariantData *variant) {
+ T size;
+ if (!readInteger(size))
+ return false;
+ return readString(variant, size);
+ }
+
+ template <typename T>
+ bool readString() {
+ T size;
+ if (!readInteger(size))
+ return false;
+ return readString(size);
+ }
+
+ template <typename T>
+ bool skipString() {
+ T size;
+ if (!readInteger(size))
+ return false;
+ return skipBytes(size);
+ }
+
+ bool readString(VariantData *variant, size_t n) {
+ if (!readString(n))
+ return false;
+ variant->setStringPointer(_stringStorage.save(),
+ typename TStringStorage::storage_policy());
+ return true;
+ }
+
+ bool readString(size_t n) {
+ _stringStorage.startString();
+ for (; n; --n) {
+ uint8_t c;
+ if (!readBytes(c))
+ return false;
+ _stringStorage.append(static_cast<char>(c));
+ }
+ _stringStorage.append('\0');
+ if (!_stringStorage.isValid()) {
+ _error = DeserializationError::NoMemory;
+ return false;
+ }
+
+ return true;
+ }
+
+ template <typename TSize, typename TFilter>
+ bool readArray(VariantData *variant, TFilter filter,
+ NestingLimit nestingLimit) {
+ TSize size;
+ if (!readInteger(size))
+ return false;
+ return readArray(variant, size, filter, nestingLimit);
+ }
+
+ template <typename TFilter>
+ bool readArray(VariantData *variant, size_t n, TFilter filter,
+ NestingLimit nestingLimit) {
+ if (nestingLimit.reached()) {
+ _error = DeserializationError::TooDeep;
+ return false;
+ }
+
+ bool allowArray = filter.allowArray();
+
+ CollectionData *array = allowArray ? &variant->toArray() : 0;
+
+ TFilter memberFilter = filter[0U];
+
+ for (; n; --n) {
+ VariantData *value;
+
+ if (memberFilter.allow()) {
+ value = array->addElement(_pool);
+ if (!value) {
+ _error = DeserializationError::NoMemory;
+ return false;
+ }
+ } else {
+ value = 0;
+ }
+
+ if (!parseVariant(value, memberFilter, nestingLimit.decrement()))
+ return false;
+ }
+
+ return true;
+ }
+
+ template <typename TSize, typename TFilter>
+ bool readObject(VariantData *variant, TFilter filter,
+ NestingLimit nestingLimit) {
+ TSize size;
+ if (!readInteger(size))
+ return false;
+ return readObject(variant, size, filter, nestingLimit);
+ }
+
+ template <typename TFilter>
+ bool readObject(VariantData *variant, size_t n, TFilter filter,
+ NestingLimit nestingLimit) {
+ if (nestingLimit.reached()) {
+ _error = DeserializationError::TooDeep;
+ return false;
+ }
+
+ CollectionData *object = filter.allowObject() ? &variant->toObject() : 0;
+
+ for (; n; --n) {
+ if (!readKey())
+ return false;
+
+ const char *key = _stringStorage.c_str();
+ TFilter memberFilter = filter[key];
+ VariantData *member;
+
+ if (memberFilter.allow()) {
+ // Save key in memory pool.
+ // This MUST be done before adding the slot.
+ key = _stringStorage.save();
+
+ VariantSlot *slot = object->addSlot(_pool);
+ if (!slot) {
+ _error = DeserializationError::NoMemory;
+ return false;
+ }
+
+ slot->setKey(key, typename TStringStorage::storage_policy());
+
+ member = slot->data();
+ } else {
+ member = 0;
+ }
+
+ if (!parseVariant(member, memberFilter, nestingLimit.decrement()))
+ return false;
+ }
+
+ return true;
+ }
+
+ bool readKey() {
+ uint8_t code;
+ if (!readByte(code))
+ return false;
+
+ if ((code & 0xe0) == 0xa0)
+ return readString(code & 0x1f);
+
+ switch (code) {
+ case 0xd9:
+ return readString<uint8_t>();
+
+ case 0xda:
+ return readString<uint16_t>();
+
+ case 0xdb:
+ return readString<uint32_t>();
+
+ default:
+ return invalidInput();
+ }
+ }
+
+ template <typename T>
+ bool skipExt() {
+ T size;
+ if (!readInteger(size))
+ return false;
+ return skipBytes(size + 1);
+ }
+
+ MemoryPool *_pool;
+ TReader _reader;
+ TStringStorage _stringStorage;
+ DeserializationError _error;
+ bool _foundSomething;
+};
+
+//
+// deserializeMsgPack(JsonDocument&, const std::string&, ...)
+//
+// ... = NestingLimit
+template <typename TString>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, const TString &input,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
+ AllowAllFilter());
+}
+// ... = Filter, NestingLimit
+template <typename TString>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, const TString &input, Filter filter,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+// ... = NestingLimit, Filter
+template <typename TString>
+DeserializationError deserializeMsgPack(JsonDocument &doc, const TString &input,
+ NestingLimit nestingLimit,
+ Filter filter) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+
+//
+// deserializeMsgPack(JsonDocument&, std::istream&, ...)
+//
+// ... = NestingLimit
+template <typename TStream>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TStream &input,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
+ AllowAllFilter());
+}
+// ... = Filter, NestingLimit
+template <typename TStream>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TStream &input, Filter filter,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+// ... = NestingLimit, Filter
+template <typename TStream>
+DeserializationError deserializeMsgPack(JsonDocument &doc, TStream &input,
+ NestingLimit nestingLimit,
+ Filter filter) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+
+//
+// deserializeMsgPack(JsonDocument&, char*, ...)
+//
+// ... = NestingLimit
+template <typename TChar>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TChar *input,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
+ AllowAllFilter());
+}
+// ... = Filter, NestingLimit
+template <typename TChar>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TChar *input, Filter filter,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+// ... = NestingLimit, Filter
+template <typename TChar>
+DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input,
+ NestingLimit nestingLimit,
+ Filter filter) {
+ return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter);
+}
+
+//
+// deserializeMsgPack(JsonDocument&, char*, size_t, ...)
+//
+// ... = NestingLimit
+template <typename TChar>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TChar *input, size_t inputSize,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
+ AllowAllFilter());
+}
+// ... = Filter, NestingLimit
+template <typename TChar>
+DeserializationError deserializeMsgPack(
+ JsonDocument &doc, TChar *input, size_t inputSize, Filter filter,
+ NestingLimit nestingLimit = NestingLimit()) {
+ return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
+ filter);
+}
+// ... = NestingLimit, Filter
+template <typename TChar>
+DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input,
+ size_t inputSize,
+ NestingLimit nestingLimit,
+ Filter filter) {
+ return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
+ filter);
+}
+
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp b/include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp
new file mode 100644
index 0000000..b1cd872
--- /dev/null
+++ b/include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp
@@ -0,0 +1,212 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/MsgPack/endianess.hpp>
+#include <ArduinoJson/Polyfills/assert.hpp>
+#include <ArduinoJson/Polyfills/type_traits.hpp>
+#include <ArduinoJson/Serialization/CountingDecorator.hpp>
+#include <ArduinoJson/Serialization/measure.hpp>
+#include <ArduinoJson/Serialization/serialize.hpp>
+#include <ArduinoJson/Variant/VariantData.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename TWriter>
+class MsgPackSerializer : public Visitor<size_t> {
+ public:
+ static const bool producesText = false;
+
+ MsgPackSerializer(TWriter writer) : _writer(writer) {}
+
+ template <typename T>
+ typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
+ writeByte(0xCA);
+ writeInteger(value32);
+ return bytesWritten();
+ }
+
+ template <typename T>
+ ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
+ typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
+ float value32 = float(value64);
+ if (value32 == value64) {
+ writeByte(0xCA);
+ writeInteger(value32);
+ } else {
+ writeByte(0xCB);
+ writeInteger(value64);
+ }
+ return bytesWritten();
+ }
+
+ size_t visitArray(const CollectionData& array) {
+ size_t n = array.size();
+ if (n < 0x10) {
+ writeByte(uint8_t(0x90 + array.size()));
+ } else if (n < 0x10000) {
+ writeByte(0xDC);
+ writeInteger(uint16_t(n));
+ } else {
+ writeByte(0xDD);
+ writeInteger(uint32_t(n));
+ }
+ for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
+ slot->data()->accept(*this);
+ }
+ return bytesWritten();
+ }
+
+ size_t visitObject(const CollectionData& object) {
+ size_t n = object.size();
+ if (n < 0x10) {
+ writeByte(uint8_t(0x80 + n));
+ } else if (n < 0x10000) {
+ writeByte(0xDE);
+ writeInteger(uint16_t(n));
+ } else {
+ writeByte(0xDF);
+ writeInteger(uint32_t(n));
+ }
+ for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
+ visitString(slot->key());
+ slot->data()->accept(*this);
+ }
+ return bytesWritten();
+ }
+
+ size_t visitString(const char* value) {
+ ARDUINOJSON_ASSERT(value != NULL);
+
+ size_t n = strlen(value);
+
+ if (n < 0x20) {
+ writeByte(uint8_t(0xA0 + n));
+ } else if (n < 0x100) {
+ writeByte(0xD9);
+ writeInteger(uint8_t(n));
+ } else if (n < 0x10000) {
+ writeByte(0xDA);
+ writeInteger(uint16_t(n));
+ } else {
+ writeByte(0xDB);
+ writeInteger(uint32_t(n));
+ }
+ writeBytes(reinterpret_cast<const uint8_t*>(value), n);
+ return bytesWritten();
+ }
+
+ size_t visitRawJson(const char* data, size_t size) {
+ writeBytes(reinterpret_cast<const uint8_t*>(data), size);
+ return bytesWritten();
+ }
+
+ size_t visitSignedInteger(Integer value) {
+ if (value > 0) {
+ visitUnsignedInteger(static_cast<UInt>(value));
+ } else if (value >= -0x20) {
+ writeInteger(int8_t(value));
+ } else if (value >= -0x80) {
+ writeByte(0xD0);
+ writeInteger(int8_t(value));
+ } else if (value >= -0x8000) {
+ writeByte(0xD1);
+ writeInteger(int16_t(value));
+ }
+#if ARDUINOJSON_USE_LONG_LONG
+ else if (value >= -0x80000000LL)
+#else
+ else
+#endif
+ {
+ writeByte(0xD2);
+ writeInteger(int32_t(value));
+ }
+#if ARDUINOJSON_USE_LONG_LONG
+ else {
+ writeByte(0xD3);
+ writeInteger(int64_t(value));
+ }
+#endif
+ return bytesWritten();
+ }
+
+ size_t visitUnsignedInteger(UInt value) {
+ if (value <= 0x7F) {
+ writeInteger(uint8_t(value));
+ } else if (value <= 0xFF) {
+ writeByte(0xCC);
+ writeInteger(uint8_t(value));
+ } else if (value <= 0xFFFF) {
+ writeByte(0xCD);
+ writeInteger(uint16_t(value));
+ }
+#if ARDUINOJSON_USE_LONG_LONG
+ else if (value <= 0xFFFFFFFF)
+#else
+ else
+#endif
+ {
+ writeByte(0xCE);
+ writeInteger(uint32_t(value));
+ }
+#if ARDUINOJSON_USE_LONG_LONG
+ else {
+ writeByte(0xCF);
+ writeInteger(uint64_t(value));
+ }
+#endif
+ return bytesWritten();
+ }
+
+ size_t visitBoolean(bool value) {
+ writeByte(value ? 0xC3 : 0xC2);
+ return bytesWritten();
+ }
+
+ size_t visitNull() {
+ writeByte(0xC0);
+ return bytesWritten();
+ }
+
+ private:
+ size_t bytesWritten() const {
+ return _writer.count();
+ }
+
+ void writeByte(uint8_t c) {
+ _writer.write(c);
+ }
+
+ void writeBytes(const uint8_t* p, size_t n) {
+ _writer.write(p, n);
+ }
+
+ template <typename T>
+ void writeInteger(T value) {
+ fixEndianess(value);
+ writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
+ }
+
+ CountingDecorator<TWriter> _writer;
+};
+
+template <typename TSource, typename TDestination>
+inline size_t serializeMsgPack(const TSource& source, TDestination& output) {
+ return serialize<MsgPackSerializer>(source, output);
+}
+
+template <typename TSource>
+inline size_t serializeMsgPack(const TSource& source, void* output,
+ size_t size) {
+ return serialize<MsgPackSerializer>(source, output, size);
+}
+
+template <typename TSource>
+inline size_t measureMsgPack(const TSource& source) {
+ return measure<MsgPackSerializer>(source);
+}
+
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/MsgPack/endianess.hpp b/include/lib/ArduinoJson/MsgPack/endianess.hpp
new file mode 100644
index 0000000..74f7e9d
--- /dev/null
+++ b/include/lib/ArduinoJson/MsgPack/endianess.hpp
@@ -0,0 +1,41 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Polyfills/type_traits.hpp>
+#include <ArduinoJson/Polyfills/utility.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+#if ARDUINOJSON_LITTLE_ENDIAN
+inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
+ swap(p[0], p[7]);
+ swap(p[1], p[6]);
+ swap(p[2], p[5]);
+ swap(p[3], p[4]);
+}
+
+inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
+ swap(p[0], p[3]);
+ swap(p[1], p[2]);
+}
+
+inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
+ swap(p[0], p[1]);
+}
+
+inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
+
+template <typename T>
+inline void fixEndianess(T &value) {
+ fixEndianess(reinterpret_cast<uint8_t *>(&value),
+ integral_constant<size_t, sizeof(T)>());
+}
+#else
+template <typename T>
+inline void fixEndianess(T &) {}
+#endif
+
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/MsgPack/ieee754.hpp b/include/lib/ArduinoJson/MsgPack/ieee754.hpp
new file mode 100644
index 0000000..016d533
--- /dev/null
+++ b/include/lib/ArduinoJson/MsgPack/ieee754.hpp
@@ -0,0 +1,18 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Namespace.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) {
+ f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5));
+ f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
+ f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
+ f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
+}
+
+} // namespace ARDUINOJSON_NAMESPACE