WireFormatter.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. * Copyright (C) 2020 Embedded AMS B.V. - All Rights Reserved
  3. *
  4. * This file is part of Embedded Proto.
  5. *
  6. * Embedded Proto is open source software: you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as published
  8. * by the Free Software Foundation, version 3 of the license.
  9. *
  10. * Embedded Proto is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Embedded Proto. If not, see <https://www.gnu.org/licenses/>.
  17. *
  18. * For commercial and closed source application please visit:
  19. * <https://EmbeddedProto.com/license/>.
  20. *
  21. * Embedded AMS B.V.
  22. * Info:
  23. * info at EmbeddedProto dot com
  24. *
  25. * Postal address:
  26. * Johan Huizingalaan 763a
  27. * 1066 VH, Amsterdam
  28. * the Netherlands
  29. */
  30. #ifndef _WIRE_FORMATTER_H_
  31. #define _WIRE_FORMATTER_H_
  32. #include <cstdint>
  33. #include <math.h>
  34. #include <type_traits>
  35. #include <limits>
  36. #include "WriteBufferInterface.h"
  37. #include "ReadBufferInterface.h"
  38. #include "Errors.h"
  39. namespace EmbeddedProto
  40. {
  41. //! This class combines functions to serialize and deserialize messages.
  42. class WireFormatter
  43. {
  44. //! Definition of the number of bits it takes to serialize a byte of a varint.
  45. static constexpr uint8_t VARINT_SHIFT_N_BITS = 7;
  46. //! Definition of a mask indicating the most significant bit used in varint encoding.
  47. static constexpr uint8_t VARINT_MSB_BYTE = 0x80;
  48. public:
  49. //! Definitions of the different encoding types used in protobuf.
  50. enum class WireType
  51. {
  52. VARINT = 0, //!< int32, int64, uint32, uint64, sint32, sint64, bool, enum.
  53. FIXED64 = 1, //!< fixed64, sfixed64, double
  54. LENGTH_DELIMITED = 2, //!< string, bytes, embedded messages, packed repeated fields
  55. START_GROUP = 3, //!< Deprecated
  56. END_GROUP = 4, //!< Deprecated
  57. FIXED32 = 5, //!< fixed32, sfixed32, float
  58. };
  59. /**
  60. @brief Serialize fields, including tags to the given buffer.
  61. @{
  62. **/
  63. template<class INT_TYPE>
  64. static Error SerializeInt(uint32_t field_number, INT_TYPE value, WriteBufferInterface& buffer)
  65. {
  66. typedef typename std::make_unsigned<INT_TYPE>::type UINT_TYPE;
  67. Error return_value = SerializeVarint(MakeTag(field_number, WireType::VARINT), buffer);
  68. if(Error::NO_ERRORS == return_value)
  69. {
  70. return_value = SerializeVarint(static_cast<UINT_TYPE>(value), buffer);
  71. }
  72. return return_value;
  73. }
  74. template<class UINT_TYPE>
  75. static Error SerializeUInt(uint32_t field_number, UINT_TYPE value, WriteBufferInterface& buffer)
  76. {
  77. Error return_value = SerializeVarint(MakeTag(field_number, WireType::VARINT), buffer);
  78. if(Error::NO_ERRORS == return_value)
  79. {
  80. return_value = SerializeVarint(value, buffer);
  81. }
  82. return return_value;
  83. }
  84. template<class INT_TYPE>
  85. static Error SerializeSInt(uint32_t field_number, INT_TYPE value, WriteBufferInterface& buffer)
  86. {
  87. Error return_value = SerializeVarint(MakeTag(field_number, WireType::VARINT), buffer);
  88. if(Error::NO_ERRORS == return_value)
  89. {
  90. return_value = SerializeVarint(ZigZagEncode(value), buffer);
  91. }
  92. return return_value;
  93. }
  94. static Error SerializeFixed(uint32_t field_number, uint32_t value, WriteBufferInterface& buffer)
  95. {
  96. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED32), buffer);
  97. if(Error::NO_ERRORS == return_value)
  98. {
  99. return_value = SerialzieFixedNoTag(value, buffer);
  100. }
  101. return return_value;
  102. }
  103. static Error SerializeFixed(uint32_t field_number, uint64_t value, WriteBufferInterface& buffer)
  104. {
  105. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED64), buffer);
  106. if(Error::NO_ERRORS == return_value)
  107. {
  108. return_value = SerialzieFixedNoTag(value, buffer);
  109. }
  110. return return_value;
  111. }
  112. static Error SerializeSFixed(uint32_t field_number, int32_t value, WriteBufferInterface& buffer)
  113. {
  114. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED32), buffer);
  115. if(Error::NO_ERRORS == return_value)
  116. {
  117. return_value = SerialzieSFixedNoTag(value, buffer);
  118. }
  119. return return_value;
  120. }
  121. static Error SerializeSFixed(uint32_t field_number, int64_t value, WriteBufferInterface& buffer)
  122. {
  123. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED64), buffer);
  124. if(Error::NO_ERRORS == return_value)
  125. {
  126. return_value = SerialzieSFixedNoTag(value, buffer);
  127. }
  128. return return_value;
  129. }
  130. static Error SerializeFloat(uint32_t field_number, float value, WriteBufferInterface& buffer)
  131. {
  132. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED32), buffer);
  133. if(Error::NO_ERRORS == return_value)
  134. {
  135. return_value = SerialzieFloatNoTag(value, buffer);
  136. }
  137. return return_value;
  138. }
  139. static Error SerializeDouble(uint32_t field_number, double value, WriteBufferInterface& buffer)
  140. {
  141. Error return_value = SerializeVarint(MakeTag(field_number, WireType::FIXED64), buffer);
  142. if(Error::NO_ERRORS == return_value)
  143. {
  144. return_value = SerialzieDoubleNoTag(value, buffer);
  145. }
  146. return return_value;
  147. }
  148. static Error SerializeBool(uint32_t field_number, bool value, WriteBufferInterface& buffer)
  149. {
  150. Error return_value = SerializeVarint(MakeTag(field_number, WireType::VARINT), buffer);
  151. if(Error::NO_ERRORS == return_value)
  152. {
  153. const uint8_t byte = value ? 0x01 : 0x00;
  154. return_value = buffer.push(byte) ? Error::NO_ERRORS : Error::BUFFER_FULL;
  155. }
  156. return return_value;
  157. }
  158. static Error SerializeEnum(uint32_t field_number, uint32_t value, WriteBufferInterface& buffer)
  159. {
  160. Error return_value = SerializeVarint(MakeTag(field_number, WireType::VARINT), buffer);
  161. if(Error::NO_ERRORS == return_value)
  162. {
  163. return_value = SerializeVarint(value, buffer);
  164. }
  165. return return_value;
  166. }
  167. /** @} **/
  168. /**
  169. @brief Deserialize fields from the given buffer.
  170. @{
  171. **/
  172. //! Read from the buffer the next wiretype and field id.
  173. /*!
  174. \param[in] buffer The data source from which to read the type and id.
  175. \param[out] type This parameter returns the wiretype of the next field in the data buffer.
  176. \param[out] id This parameter returns the next field id.
  177. \return A value from the EmbeddedProto::Error enum indicating if the process succeeded.
  178. */
  179. static Error DeserializeTag(ReadBufferInterface& buffer, WireType& type, uint32_t& id)
  180. {
  181. uint32_t temp_value;
  182. // Read the next varint considered to be a tag.
  183. Error return_value = DeserializeVarint(buffer, temp_value);
  184. if(Error::NO_ERRORS == return_value)
  185. {
  186. // Next check the validity of the wire type.
  187. if((temp_value & 0x07) <= static_cast<uint32_t>(WireType::FIXED32))
  188. {
  189. // If reading the tag succeeded and the wire type is a valid one.
  190. type = static_cast<WireType>(temp_value & 0x07);
  191. id = (temp_value >> 3);
  192. }
  193. else
  194. {
  195. return_value = Error::INVALID_WIRETYPE;
  196. }
  197. }
  198. return return_value;
  199. }
  200. template<class UINT_TYPE>
  201. static Error DeserializeUInt(ReadBufferInterface& buffer, UINT_TYPE& value)
  202. {
  203. static_assert(std::is_same<UINT_TYPE, uint32_t>::value ||
  204. std::is_same<UINT_TYPE, uint64_t>::value, "Wrong type passed to DeserializeUInt.");
  205. return DeserializeVarint(buffer, value);
  206. }
  207. template<class INT_TYPE>
  208. static Error DeserializeInt(ReadBufferInterface& buffer, INT_TYPE& value)
  209. {
  210. static_assert(std::is_same<INT_TYPE, int32_t>::value ||
  211. std::is_same<INT_TYPE, int64_t>::value, "Wrong type passed to DeserializeInt.");
  212. uint64_t uint_value;
  213. Error result = DeserializeVarint(buffer, uint_value);
  214. if(Error::NO_ERRORS == result)
  215. {
  216. value = static_cast<INT_TYPE>(uint_value);
  217. }
  218. return result;
  219. }
  220. template<class INT_TYPE>
  221. static Error DeserializeSInt(ReadBufferInterface& buffer, INT_TYPE& value)
  222. {
  223. static_assert(std::is_same<INT_TYPE, int32_t>::value ||
  224. std::is_same<INT_TYPE, int64_t>::value, "Wrong type passed to DeserializeSInt.");
  225. uint64_t uint_value;
  226. Error result = DeserializeVarint(buffer, uint_value);
  227. if(Error::NO_ERRORS == result)
  228. {
  229. value = ZigZagDecode(uint_value);
  230. }
  231. return result;
  232. }
  233. template<class TYPE>
  234. static Error DeserializeFixed(ReadBufferInterface& buffer, TYPE& value)
  235. {
  236. static_assert(std::is_same<TYPE, uint32_t>::value ||
  237. std::is_same<TYPE, uint64_t>::value, "Wrong type passed to DeserializeFixed.");
  238. // Deserialize the data little endian to the buffer.
  239. // TODO Define a little endian flag to support memcpy the data from the buffer.
  240. TYPE temp_value = 0;
  241. bool result(true);
  242. uint8_t byte = 0;
  243. for(uint8_t i = 0; (i < std::numeric_limits<TYPE>::digits) && result;
  244. i += std::numeric_limits<uint8_t>::digits)
  245. {
  246. result = buffer.pop(byte);
  247. if(result)
  248. {
  249. temp_value |= (static_cast<TYPE>(byte) << i);
  250. }
  251. }
  252. Error return_value = Error::NO_ERRORS;
  253. if(result)
  254. {
  255. value = temp_value;
  256. }
  257. else
  258. {
  259. return_value = Error::END_OF_BUFFER;
  260. }
  261. return return_value;
  262. }
  263. template<class STYPE>
  264. static Error DeserializeSFixed(ReadBufferInterface& buffer, STYPE& value)
  265. {
  266. static_assert(std::is_same<STYPE, int32_t>::value ||
  267. std::is_same<STYPE, int64_t>::value, "Wrong type passed to DeserializeSFixed.");
  268. typedef typename std::make_unsigned<STYPE>::type USTYPE;
  269. USTYPE temp_unsigned_value = 0;
  270. Error result = DeserializeFixed(buffer, temp_unsigned_value);
  271. if(Error::NO_ERRORS == result)
  272. {
  273. value = static_cast<STYPE>(temp_unsigned_value);
  274. }
  275. return result;
  276. }
  277. static Error DeserializeFloat(ReadBufferInterface& buffer, float& value)
  278. {
  279. uint32_t temp_value = 0;
  280. Error result = DeserializeFixed(buffer, temp_value);
  281. if(Error::NO_ERRORS == result)
  282. {
  283. // Cast from unsigned int to a float.
  284. const void* pVoid = static_cast<const void*>(&temp_value);
  285. const float* pFloat = static_cast<const float*>(pVoid);
  286. value = *pFloat;
  287. }
  288. return result;
  289. }
  290. static Error DeserializeDouble(ReadBufferInterface& buffer, double& value)
  291. {
  292. uint64_t temp_value = 0;
  293. Error result = DeserializeFixed(buffer, temp_value);
  294. if(Error::NO_ERRORS == result)
  295. {
  296. // Cast from unsigned int to a double.
  297. const void* pVoid = static_cast<const void*>(&temp_value);
  298. const double* pDouble = static_cast<const double*>(pVoid);
  299. value = *pDouble;
  300. }
  301. return result;
  302. }
  303. static Error DeserializeBool(ReadBufferInterface& buffer, bool& value)
  304. {
  305. uint8_t byte;
  306. Error result = Error::NO_ERRORS;
  307. if(buffer.pop(byte))
  308. {
  309. value = static_cast<bool>(byte);
  310. }
  311. else
  312. {
  313. result = Error::END_OF_BUFFER;
  314. }
  315. return result;
  316. }
  317. template<class ENUM_TYPE>
  318. static Error DeserializeEnum(ReadBufferInterface& buffer, ENUM_TYPE& value)
  319. {
  320. static_assert(std::is_enum<ENUM_TYPE>::value, "No enum given to DeserializeEnum parameter value.");
  321. uint64_t temp_value;
  322. Error result = DeserializeVarint(buffer, temp_value);
  323. if(Error::NO_ERRORS == result)
  324. {
  325. value = static_cast<ENUM_TYPE>(temp_value);
  326. }
  327. return result;
  328. }
  329. /** @} **/
  330. //! This function converts a given value unsigned integer to a varint formatted data buffer.
  331. /*!
  332. \param[in] value The data to be serialized, uint32_t or uint64_t.
  333. \param[in] buffer A reference to a message buffer object in which to store the variable.
  334. \return A value from the Error enum, NO_ERROR in case everything is fine.
  335. */
  336. template<class UINT_TYPE>
  337. static Error SerializeVarint(UINT_TYPE value, WriteBufferInterface& buffer)
  338. {
  339. static_assert(std::is_same<UINT_TYPE, uint32_t>::value ||
  340. std::is_same<UINT_TYPE, uint64_t>::value,
  341. "Wrong type passed to SerializeVarint.");
  342. bool memory_free = true;
  343. while((value >= VARINT_MSB_BYTE) && memory_free)
  344. {
  345. memory_free = buffer.push(static_cast<uint8_t>(value | VARINT_MSB_BYTE));
  346. value >>= VARINT_SHIFT_N_BITS;
  347. }
  348. memory_free = buffer.push(static_cast<uint8_t>(value));
  349. const Error return_value = memory_free ? Error::NO_ERRORS : Error::BUFFER_FULL;
  350. return return_value;
  351. }
  352. //! This function deserializes the following N bytes into a varint.
  353. /*!
  354. \param[in] buffer The data buffer from which bytes are popped.
  355. \param[out] value The variable in which the varint is returned.
  356. \return A value from the Error enum, NO_ERROR in case everything is fine.
  357. */
  358. template<class UINT_TYPE>
  359. static Error DeserializeVarint(ReadBufferInterface& buffer, UINT_TYPE& value)
  360. {
  361. static_assert(std::is_same<UINT_TYPE, uint32_t>::value ||
  362. std::is_same<UINT_TYPE, uint64_t>::value,
  363. "Wrong type passed to DeserializeVarint.");
  364. // Calculate how many bytes there are in a varint 128 base encoded number. This should
  365. // yield 5 for a 32bit number and 10 for a 64bit number.
  366. static constexpr uint8_t N_BYTES_IN_VARINT = static_cast<uint8_t>(std::ceil(
  367. std::numeric_limits<UINT_TYPE>::digits
  368. / static_cast<float>(VARINT_SHIFT_N_BITS)));
  369. UINT_TYPE temp_value = 0;
  370. uint8_t byte = 0;
  371. bool result = buffer.pop(byte);
  372. // Loop until the end of the encoded varint or until there is no more data in the buffer.
  373. for(uint8_t i = 0; (i < N_BYTES_IN_VARINT) && result; ++i)
  374. {
  375. temp_value |= static_cast<UINT_TYPE>(byte & (~VARINT_MSB_BYTE)) << (i * VARINT_SHIFT_N_BITS);
  376. if(byte & VARINT_MSB_BYTE)
  377. {
  378. // Continue
  379. result = buffer.pop(byte);
  380. }
  381. else
  382. {
  383. // The varint is complete
  384. break;
  385. }
  386. }
  387. Error return_value = Error::NO_ERRORS;
  388. if(result)
  389. {
  390. value = temp_value;
  391. }
  392. else
  393. {
  394. return_value = Error::END_OF_BUFFER;
  395. }
  396. return return_value;
  397. }
  398. //! Encode a signed integer using the zig zag method
  399. /*!
  400. As specified the right-shift must be arithmetic, hence the cast is after the shift. The
  401. left shift must be unsigned because of overflow.
  402. This function is suitable for 32 and 64 bit.
  403. \param[in] n The signed value to be encoded.
  404. \return The zig zag transformed value ready for serialization into the array.
  405. */
  406. template<class INT_TYPE>
  407. static constexpr auto ZigZagEncode(const INT_TYPE n)
  408. {
  409. static_assert(std::is_same<INT_TYPE, int32_t>::value ||
  410. std::is_same<INT_TYPE, int64_t>::value, "Wrong type passed to ZigZagEncode.");
  411. typedef typename std::make_unsigned<INT_TYPE>::type UINT_TYPE;
  412. constexpr uint8_t N_BITS_TO_ZIGZAG = std::numeric_limits<UINT_TYPE>::digits - 1;
  413. return (static_cast<UINT_TYPE>(n) << 1) ^ static_cast<UINT_TYPE>(n >> N_BITS_TO_ZIGZAG);
  414. }
  415. //! Decode a signed integer using the zig zag method
  416. /*!
  417. \param[in] n The value encoded in zig zag to be decoded.
  418. \return The decoded signed value.
  419. This function is suitable for 32 and 64 bit.
  420. */
  421. template<class UINT_TYPE>
  422. static constexpr auto ZigZagDecode(const UINT_TYPE n)
  423. {
  424. static_assert(std::is_same<UINT_TYPE, uint32_t>::value ||
  425. std::is_same<UINT_TYPE, uint64_t>::value, "Wrong type passed to ZigZagDecode.");
  426. typedef typename std::make_signed<UINT_TYPE>::type INT_TYPE;
  427. return static_cast<INT_TYPE>((n >> 1) ^ (~(n & 1) + 1));
  428. }
  429. //! Create the tag of a field.
  430. /*!
  431. This is the combination of the field number and wire type of the field. The field number is
  432. shifted to the left by three bits. This creates space to or the wire type of the designated
  433. field.
  434. */
  435. static constexpr uint32_t MakeTag(const uint32_t field_number, const WireType type)
  436. {
  437. return ((static_cast<uint32_t>(field_number) << 3) | static_cast<uint32_t>(type));
  438. }
  439. /**
  440. @brief Serialize fields, without tags the given buffer.
  441. @{
  442. **/
  443. //! Serialize an unsigned fixed length field without the tag.
  444. template<class UINT_TYPE>
  445. static Error SerialzieFixedNoTag(UINT_TYPE value, WriteBufferInterface& buffer)
  446. {
  447. static_assert(std::is_same<UINT_TYPE, uint32_t>::value ||
  448. std::is_same<UINT_TYPE, uint64_t>::value, "Wrong type passed to SerialzieFixedNoTag.");
  449. // Push the data little endian to the buffer.
  450. // TODO Define a little endian flag to support memcpy the data to the buffer.
  451. bool result = true;
  452. // Loop over all bytes in the integer.
  453. for(uint8_t i = 0; (i < std::numeric_limits<UINT_TYPE>::digits) && result; i += 8) {
  454. // Shift the value using the current value of i.
  455. result = buffer.push(static_cast<uint8_t>((value >> i) & 0x00FF));
  456. }
  457. return result ? Error::NO_ERRORS : Error::BUFFER_FULL;
  458. }
  459. //! Serialize a signed fixed length field without the tag.
  460. template<class INT_TYPE>
  461. static Error SerialzieSFixedNoTag(INT_TYPE value, WriteBufferInterface& buffer)
  462. {
  463. static_assert(std::is_same<INT_TYPE, int32_t>::value ||
  464. std::is_same<INT_TYPE, int64_t>::value, "Wrong type passed to SerialzieSFixedNoTag.");
  465. typedef typename std::make_unsigned<INT_TYPE>::type UINT_TYPE;
  466. return SerialzieFixedNoTag(static_cast<UINT_TYPE>(value), buffer);
  467. }
  468. //! Serialize a 32bit real value without tag.
  469. static Error SerialzieFloatNoTag(float value, WriteBufferInterface& buffer)
  470. {
  471. // Cast the type to void and to a 32 fixed number
  472. void* pVoid = static_cast<void*>(&value);
  473. uint32_t* fixed = static_cast<uint32_t*>(pVoid);
  474. return SerialzieFixedNoTag(*fixed, buffer);
  475. }
  476. //! Serialize a 64bit real value without tag.
  477. static Error SerialzieDoubleNoTag(double value, WriteBufferInterface& buffer)
  478. {
  479. // Cast the type to void and to a 64 fixed number
  480. void* pVoid = static_cast<void*>(&value);
  481. uint64_t* fixed = static_cast<uint64_t*>(pVoid);
  482. return SerialzieFixedNoTag(*fixed, buffer);
  483. }
  484. /** @} **/
  485. };
  486. } // End of namespace EmbeddedProto.
  487. #endif