summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp')
-rw-r--r--include/lib/ArduinoJson/MsgPack/MsgPackSerializer.hpp212
1 files changed, 212 insertions, 0 deletions
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