PbWriter.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include "PbWriter.h"
  2. PbWriter::PbWriter(std::vector<uint8_t> &rawData) : rawData(rawData)
  3. {
  4. }
  5. void PbWriter::encodeVarInt(uint32_t low, uint32_t high, int32_t indexOffset)
  6. {
  7. size_t i = 0;
  8. uint8_t byte = (uint8_t)(low & 0x7F);
  9. low >>= 7;
  10. while (i < 4 && (low != 0 || high != 0))
  11. {
  12. byte |= 0x80;
  13. rawData.insert(rawData.end() + indexOffset, byte);
  14. i++;
  15. byte = (uint8_t)(low & 0x7F);
  16. low >>= 7;
  17. }
  18. if (high)
  19. {
  20. byte = (uint8_t)(byte | ((high & 0x07) << 4));
  21. high >>= 3;
  22. while (high)
  23. {
  24. byte |= 0x80;
  25. rawData.insert(rawData.end() + indexOffset, byte);
  26. i++;
  27. byte = (uint8_t)(high & 0x7F);
  28. high >>= 7;
  29. }
  30. }
  31. rawData.insert(rawData.end() + indexOffset, byte);
  32. }
  33. template void PbWriter::encodeVarInt(uint8_t, int32_t);
  34. template void PbWriter::encodeVarInt(uint32_t, int32_t);
  35. template void PbWriter::encodeVarInt(uint64_t, int32_t);
  36. template void PbWriter::encodeVarInt(long long, int32_t);
  37. template <typename T>
  38. void PbWriter::encodeVarInt(T data, int32_t offset)
  39. {
  40. auto value = static_cast<uint64_t>(data);
  41. if (value <= 0x7F)
  42. {
  43. rawData.insert(rawData.end() + offset, (uint8_t)value);
  44. }
  45. else
  46. {
  47. encodeVarInt((uint32_t)value, (uint32_t)(value >> 32), offset);
  48. }
  49. }
  50. uint32_t PbWriter::encodeZigzag32(int32_t value) {
  51. return (static_cast<uint32_t>(value) << 1U) ^ static_cast<uint32_t>(-static_cast<int32_t>(static_cast<uint32_t>(value) >> 31U));
  52. }
  53. uint64_t PbWriter::encodeZigzag64(int64_t value) {
  54. return (static_cast<uint64_t>(value) << 1U) ^ static_cast<uint64_t>(-static_cast<int64_t>(static_cast<uint64_t>(value) >> 63U));
  55. }
  56. void PbWriter::addSVarInt32(uint32_t tag, int32_t data) {
  57. auto val = encodeZigzag32(data);
  58. addVarInt(tag, val);
  59. }
  60. template <typename T>
  61. void PbWriter::encodeFixed(T data) {
  62. auto val = reinterpret_cast<const char*>(&data);
  63. rawData.insert(rawData.end(), val, val + sizeof(T));
  64. }
  65. template void PbWriter::encodeFixed(int64_t);
  66. template void PbWriter::encodeFixed(int32_t);
  67. void PbWriter::addSVarInt64(uint32_t tag, int64_t data) {
  68. auto val = encodeZigzag64(data);
  69. addVarInt(tag, val);
  70. }
  71. void PbWriter::addString(uint32_t tag, std::string &target)
  72. {
  73. addField(tag, PbWireType::length_delimited);
  74. uint32_t stringSize = target.size();
  75. encodeVarInt(stringSize);
  76. rawData.insert(rawData.end(), target.begin(), target.end());
  77. }
  78. void PbWriter::addVector(uint32_t tag, std::vector<uint8_t> &target)
  79. {
  80. addField(tag, PbWireType::length_delimited);
  81. uint32_t vectorSize = target.size();
  82. encodeVarInt(vectorSize);
  83. rawData.insert(rawData.end(), target.begin(), target.end());
  84. }
  85. template <typename T>
  86. void PbWriter::addVarInt(uint32_t tag, T intType)
  87. {
  88. addField(tag, PbWireType::varint);
  89. encodeVarInt(intType);
  90. }
  91. void PbWriter::addBool(uint32_t tag, bool value)
  92. {
  93. addField(tag, PbWireType::varint);
  94. rawData.push_back(char(value));
  95. }
  96. template void PbWriter::addVarInt(uint32_t, uint8_t);
  97. template void PbWriter::addVarInt(uint32_t, uint32_t);
  98. template void PbWriter::addVarInt(uint32_t, uint64_t);
  99. template void PbWriter::addVarInt(uint32_t, int64_t);
  100. template void PbWriter::addVarInt(uint32_t, bool);
  101. void PbWriter::addField(uint32_t tag, PbWireType wiretype)
  102. {
  103. const uint32_t value = (tag << 3U) | uint32_t(wiretype);
  104. encodeVarInt(value);
  105. }
  106. uint32_t PbWriter::startMessage()
  107. {
  108. return rawData.size();
  109. }
  110. void PbWriter::finishMessage(uint32_t tag, uint32_t lastMessagePosition)
  111. {
  112. uint32_t finalMessageSize = rawData.size() - lastMessagePosition;
  113. uint32_t msgHeader = (tag << 3U) | uint32_t(PbWireType::length_delimited);
  114. int32_t offset = -finalMessageSize;
  115. encodeVarInt(msgHeader, offset);
  116. encodeVarInt(finalMessageSize, offset);
  117. }