Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MsgPackSerializer.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <ArduinoJson/MsgPack/endianess.hpp> 00008 #include <ArduinoJson/Polyfills/assert.hpp> 00009 #include <ArduinoJson/Polyfills/type_traits.hpp> 00010 #include <ArduinoJson/Serialization/CountingDecorator.hpp> 00011 #include <ArduinoJson/Serialization/measure.hpp> 00012 #include <ArduinoJson/Serialization/serialize.hpp> 00013 #include <ArduinoJson/Variant/VariantData.hpp> 00014 00015 namespace ARDUINOJSON_NAMESPACE { 00016 00017 template <typename TWriter> 00018 class MsgPackSerializer : public Visitor<size_t> { 00019 public: 00020 MsgPackSerializer(TWriter writer) : _writer(writer) {} 00021 00022 template <typename T> 00023 typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) { 00024 writeByte(0xCA); 00025 writeInteger(value32); 00026 return bytesWritten(); 00027 } 00028 00029 template <typename T> 00030 ARDUINOJSON_NO_SANITIZE("float-cast-overflow") 00031 typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) { 00032 float value32 = float(value64); 00033 if (value32 == value64) { 00034 writeByte(0xCA); 00035 writeInteger(value32); 00036 } else { 00037 writeByte(0xCB); 00038 writeInteger(value64); 00039 } 00040 return bytesWritten(); 00041 } 00042 00043 size_t visitArray(const CollectionData& array) { 00044 size_t n = array.size(); 00045 if (n < 0x10) { 00046 writeByte(uint8_t(0x90 + array.size())); 00047 } else if (n < 0x10000) { 00048 writeByte(0xDC); 00049 writeInteger(uint16_t(n)); 00050 } else { 00051 writeByte(0xDD); 00052 writeInteger(uint32_t(n)); 00053 } 00054 for (VariantSlot* slot = array.head(); slot; slot = slot->next()) { 00055 slot->data()->accept(*this); 00056 } 00057 return bytesWritten(); 00058 } 00059 00060 size_t visitObject(const CollectionData& object) { 00061 size_t n = object.size(); 00062 if (n < 0x10) { 00063 writeByte(uint8_t(0x80 + n)); 00064 } else if (n < 0x10000) { 00065 writeByte(0xDE); 00066 writeInteger(uint16_t(n)); 00067 } else { 00068 writeByte(0xDF); 00069 writeInteger(uint32_t(n)); 00070 } 00071 for (VariantSlot* slot = object.head(); slot; slot = slot->next()) { 00072 visitString(slot->key()); 00073 slot->data()->accept(*this); 00074 } 00075 return bytesWritten(); 00076 } 00077 00078 size_t visitString(const char* value) { 00079 ARDUINOJSON_ASSERT(value != NULL); 00080 00081 size_t n = strlen(value); 00082 00083 if (n < 0x20) { 00084 writeByte(uint8_t(0xA0 + n)); 00085 } else if (n < 0x100) { 00086 writeByte(0xD9); 00087 writeInteger(uint8_t(n)); 00088 } else if (n < 0x10000) { 00089 writeByte(0xDA); 00090 writeInteger(uint16_t(n)); 00091 } else { 00092 writeByte(0xDB); 00093 writeInteger(uint32_t(n)); 00094 } 00095 writeBytes(reinterpret_cast<const uint8_t*>(value), n); 00096 return bytesWritten(); 00097 } 00098 00099 size_t visitRawJson(const char* data, size_t size) { 00100 writeBytes(reinterpret_cast<const uint8_t*>(data), size); 00101 return bytesWritten(); 00102 } 00103 00104 size_t visitNegativeInteger(UInt value) { 00105 UInt negated = UInt(~value + 1); 00106 if (value <= 0x20) { 00107 writeInteger(int8_t(negated)); 00108 } else if (value <= 0x80) { 00109 writeByte(0xD0); 00110 writeInteger(int8_t(negated)); 00111 } else if (value <= 0x8000) { 00112 writeByte(0xD1); 00113 writeInteger(int16_t(negated)); 00114 } else if (value <= 0x80000000) { 00115 writeByte(0xD2); 00116 writeInteger(int32_t(negated)); 00117 } 00118 #if ARDUINOJSON_USE_LONG_LONG 00119 else { 00120 writeByte(0xD3); 00121 writeInteger(int64_t(negated)); 00122 } 00123 #endif 00124 return bytesWritten(); 00125 } 00126 00127 size_t visitPositiveInteger(UInt value) { 00128 if (value <= 0x7F) { 00129 writeInteger(uint8_t(value)); 00130 } else if (value <= 0xFF) { 00131 writeByte(0xCC); 00132 writeInteger(uint8_t(value)); 00133 } else if (value <= 0xFFFF) { 00134 writeByte(0xCD); 00135 writeInteger(uint16_t(value)); 00136 } 00137 #if ARDUINOJSON_USE_LONG_LONG 00138 else if (value <= 0xFFFFFFFF) 00139 #else 00140 else 00141 #endif 00142 { 00143 writeByte(0xCE); 00144 writeInteger(uint32_t(value)); 00145 } 00146 #if ARDUINOJSON_USE_LONG_LONG 00147 else { 00148 writeByte(0xCF); 00149 writeInteger(uint64_t(value)); 00150 } 00151 #endif 00152 return bytesWritten(); 00153 } 00154 00155 size_t visitBoolean(bool value) { 00156 writeByte(value ? 0xC3 : 0xC2); 00157 return bytesWritten(); 00158 } 00159 00160 size_t visitNull() { 00161 writeByte(0xC0); 00162 return bytesWritten(); 00163 } 00164 00165 private: 00166 size_t bytesWritten() const { 00167 return _writer.count(); 00168 } 00169 00170 void writeByte(uint8_t c) { 00171 _writer.write(c); 00172 } 00173 00174 void writeBytes(const uint8_t* p, size_t n) { 00175 _writer.write(p, n); 00176 } 00177 00178 template <typename T> 00179 void writeInteger(T value) { 00180 fixEndianess(value); 00181 writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); 00182 } 00183 00184 CountingDecorator<TWriter> _writer; 00185 }; 00186 00187 template <typename TSource, typename TDestination> 00188 inline size_t serializeMsgPack(const TSource& source, TDestination& output) { 00189 return serialize<MsgPackSerializer>(source, output); 00190 } 00191 00192 template <typename TSource> 00193 inline size_t serializeMsgPack(const TSource& source, void* output, 00194 size_t size) { 00195 return serialize<MsgPackSerializer>(source, output, size); 00196 } 00197 00198 template <typename TSource> 00199 inline size_t measureMsgPack(const TSource& source) { 00200 return measure<MsgPackSerializer>(source); 00201 } 00202 00203 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:36 by
1.7.2