MsgPackWriter.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. //===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  10. /// This file implements a MessagePack writer.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/BinaryFormat/MsgPackWriter.h"
  14. #include "llvm/BinaryFormat/MsgPack.h"
  15. using namespace llvm;
  16. using namespace msgpack;
  17. Writer::Writer(raw_ostream &OS, bool Compatible)
  18. : EW(OS, Endianness), Compatible(Compatible) {}
  19. void Writer::writeNil() { EW.write(FirstByte::Nil); }
  20. void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }
  21. void Writer::write(int64_t i) {
  22. if (i >= 0) {
  23. write(static_cast<uint64_t>(i));
  24. return;
  25. }
  26. if (i >= FixMin::NegativeInt) {
  27. EW.write(static_cast<int8_t>(i));
  28. return;
  29. }
  30. if (i >= INT8_MIN) {
  31. EW.write(FirstByte::Int8);
  32. EW.write(static_cast<int8_t>(i));
  33. return;
  34. }
  35. if (i >= INT16_MIN) {
  36. EW.write(FirstByte::Int16);
  37. EW.write(static_cast<int16_t>(i));
  38. return;
  39. }
  40. if (i >= INT32_MIN) {
  41. EW.write(FirstByte::Int32);
  42. EW.write(static_cast<int32_t>(i));
  43. return;
  44. }
  45. EW.write(FirstByte::Int64);
  46. EW.write(i);
  47. }
  48. void Writer::write(uint64_t u) {
  49. if (u <= FixMax::PositiveInt) {
  50. EW.write(static_cast<uint8_t>(u));
  51. return;
  52. }
  53. if (u <= UINT8_MAX) {
  54. EW.write(FirstByte::UInt8);
  55. EW.write(static_cast<uint8_t>(u));
  56. return;
  57. }
  58. if (u <= UINT16_MAX) {
  59. EW.write(FirstByte::UInt16);
  60. EW.write(static_cast<uint16_t>(u));
  61. return;
  62. }
  63. if (u <= UINT32_MAX) {
  64. EW.write(FirstByte::UInt32);
  65. EW.write(static_cast<uint32_t>(u));
  66. return;
  67. }
  68. EW.write(FirstByte::UInt64);
  69. EW.write(u);
  70. }
  71. void Writer::write(double d) {
  72. // If no loss of precision, encode as a Float32.
  73. double a = std::fabs(d);
  74. if (a >= std::numeric_limits<float>::min() &&
  75. a <= std::numeric_limits<float>::max()) {
  76. EW.write(FirstByte::Float32);
  77. EW.write(static_cast<float>(d));
  78. } else {
  79. EW.write(FirstByte::Float64);
  80. EW.write(d);
  81. }
  82. }
  83. void Writer::write(StringRef s) {
  84. size_t Size = s.size();
  85. if (Size <= FixMax::String)
  86. EW.write(static_cast<uint8_t>(FixBits::String | Size));
  87. else if (!Compatible && Size <= UINT8_MAX) {
  88. EW.write(FirstByte::Str8);
  89. EW.write(static_cast<uint8_t>(Size));
  90. } else if (Size <= UINT16_MAX) {
  91. EW.write(FirstByte::Str16);
  92. EW.write(static_cast<uint16_t>(Size));
  93. } else {
  94. assert(Size <= UINT32_MAX && "String object too long to be encoded");
  95. EW.write(FirstByte::Str32);
  96. EW.write(static_cast<uint32_t>(Size));
  97. }
  98. EW.OS << s;
  99. }
  100. void Writer::write(MemoryBufferRef Buffer) {
  101. assert(!Compatible && "Attempt to write Bin format in compatible mode");
  102. size_t Size = Buffer.getBufferSize();
  103. if (Size <= UINT8_MAX) {
  104. EW.write(FirstByte::Bin8);
  105. EW.write(static_cast<uint8_t>(Size));
  106. } else if (Size <= UINT16_MAX) {
  107. EW.write(FirstByte::Bin16);
  108. EW.write(static_cast<uint16_t>(Size));
  109. } else {
  110. assert(Size <= UINT32_MAX && "Binary object too long to be encoded");
  111. EW.write(FirstByte::Bin32);
  112. EW.write(static_cast<uint32_t>(Size));
  113. }
  114. EW.OS.write(Buffer.getBufferStart(), Size);
  115. }
  116. void Writer::writeArraySize(uint32_t Size) {
  117. if (Size <= FixMax::Array) {
  118. EW.write(static_cast<uint8_t>(FixBits::Array | Size));
  119. return;
  120. }
  121. if (Size <= UINT16_MAX) {
  122. EW.write(FirstByte::Array16);
  123. EW.write(static_cast<uint16_t>(Size));
  124. return;
  125. }
  126. EW.write(FirstByte::Array32);
  127. EW.write(Size);
  128. }
  129. void Writer::writeMapSize(uint32_t Size) {
  130. if (Size <= FixMax::Map) {
  131. EW.write(static_cast<uint8_t>(FixBits::Map | Size));
  132. return;
  133. }
  134. if (Size <= UINT16_MAX) {
  135. EW.write(FirstByte::Map16);
  136. EW.write(static_cast<uint16_t>(Size));
  137. return;
  138. }
  139. EW.write(FirstByte::Map32);
  140. EW.write(Size);
  141. }
  142. void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {
  143. size_t Size = Buffer.getBufferSize();
  144. switch (Size) {
  145. case FixLen::Ext1:
  146. EW.write(FirstByte::FixExt1);
  147. break;
  148. case FixLen::Ext2:
  149. EW.write(FirstByte::FixExt2);
  150. break;
  151. case FixLen::Ext4:
  152. EW.write(FirstByte::FixExt4);
  153. break;
  154. case FixLen::Ext8:
  155. EW.write(FirstByte::FixExt8);
  156. break;
  157. case FixLen::Ext16:
  158. EW.write(FirstByte::FixExt16);
  159. break;
  160. default:
  161. if (Size <= UINT8_MAX) {
  162. EW.write(FirstByte::Ext8);
  163. EW.write(static_cast<uint8_t>(Size));
  164. } else if (Size <= UINT16_MAX) {
  165. EW.write(FirstByte::Ext16);
  166. EW.write(static_cast<uint16_t>(Size));
  167. } else {
  168. assert(Size <= UINT32_MAX && "Ext size too large to be encoded");
  169. EW.write(FirstByte::Ext32);
  170. EW.write(static_cast<uint32_t>(Size));
  171. }
  172. }
  173. EW.write(Type);
  174. EW.OS.write(Buffer.getBufferStart(), Size);
  175. }