MsgPackReader.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. //===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- 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 reader.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13. #include "llvm/BinaryFormat/MsgPackReader.h"
  14. #include "llvm/BinaryFormat/MsgPack.h"
  15. #include "llvm/Support/Endian.h"
  16. #include "llvm/Support/MathExtras.h"
  17. using namespace llvm;
  18. using namespace llvm::support;
  19. using namespace msgpack;
  20. Reader::Reader(MemoryBufferRef InputBuffer)
  21. : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
  22. End(InputBuffer.getBufferEnd()) {}
  23. Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
  24. Expected<bool> Reader::read(Object &Obj) {
  25. if (Current == End)
  26. return false;
  27. uint8_t FB = static_cast<uint8_t>(*Current++);
  28. switch (FB) {
  29. case FirstByte::Nil:
  30. Obj.Kind = Type::Nil;
  31. return true;
  32. case FirstByte::True:
  33. Obj.Kind = Type::Boolean;
  34. Obj.Bool = true;
  35. return true;
  36. case FirstByte::False:
  37. Obj.Kind = Type::Boolean;
  38. Obj.Bool = false;
  39. return true;
  40. case FirstByte::Int8:
  41. Obj.Kind = Type::Int;
  42. return readInt<int8_t>(Obj);
  43. case FirstByte::Int16:
  44. Obj.Kind = Type::Int;
  45. return readInt<int16_t>(Obj);
  46. case FirstByte::Int32:
  47. Obj.Kind = Type::Int;
  48. return readInt<int32_t>(Obj);
  49. case FirstByte::Int64:
  50. Obj.Kind = Type::Int;
  51. return readInt<int64_t>(Obj);
  52. case FirstByte::UInt8:
  53. Obj.Kind = Type::UInt;
  54. return readUInt<uint8_t>(Obj);
  55. case FirstByte::UInt16:
  56. Obj.Kind = Type::UInt;
  57. return readUInt<uint16_t>(Obj);
  58. case FirstByte::UInt32:
  59. Obj.Kind = Type::UInt;
  60. return readUInt<uint32_t>(Obj);
  61. case FirstByte::UInt64:
  62. Obj.Kind = Type::UInt;
  63. return readUInt<uint64_t>(Obj);
  64. case FirstByte::Float32:
  65. Obj.Kind = Type::Float;
  66. if (sizeof(float) > remainingSpace())
  67. return make_error<StringError>(
  68. "Invalid Float32 with insufficient payload",
  69. std::make_error_code(std::errc::invalid_argument));
  70. Obj.Float = BitsToFloat(endian::read<uint32_t, Endianness>(Current));
  71. Current += sizeof(float);
  72. return true;
  73. case FirstByte::Float64:
  74. Obj.Kind = Type::Float;
  75. if (sizeof(double) > remainingSpace())
  76. return make_error<StringError>(
  77. "Invalid Float64 with insufficient payload",
  78. std::make_error_code(std::errc::invalid_argument));
  79. Obj.Float = BitsToDouble(endian::read<uint64_t, Endianness>(Current));
  80. Current += sizeof(double);
  81. return true;
  82. case FirstByte::Str8:
  83. Obj.Kind = Type::String;
  84. return readRaw<uint8_t>(Obj);
  85. case FirstByte::Str16:
  86. Obj.Kind = Type::String;
  87. return readRaw<uint16_t>(Obj);
  88. case FirstByte::Str32:
  89. Obj.Kind = Type::String;
  90. return readRaw<uint32_t>(Obj);
  91. case FirstByte::Bin8:
  92. Obj.Kind = Type::Binary;
  93. return readRaw<uint8_t>(Obj);
  94. case FirstByte::Bin16:
  95. Obj.Kind = Type::Binary;
  96. return readRaw<uint16_t>(Obj);
  97. case FirstByte::Bin32:
  98. Obj.Kind = Type::Binary;
  99. return readRaw<uint32_t>(Obj);
  100. case FirstByte::Array16:
  101. Obj.Kind = Type::Array;
  102. return readLength<uint16_t>(Obj);
  103. case FirstByte::Array32:
  104. Obj.Kind = Type::Array;
  105. return readLength<uint32_t>(Obj);
  106. case FirstByte::Map16:
  107. Obj.Kind = Type::Map;
  108. return readLength<uint16_t>(Obj);
  109. case FirstByte::Map32:
  110. Obj.Kind = Type::Map;
  111. return readLength<uint32_t>(Obj);
  112. case FirstByte::FixExt1:
  113. Obj.Kind = Type::Extension;
  114. return createExt(Obj, FixLen::Ext1);
  115. case FirstByte::FixExt2:
  116. Obj.Kind = Type::Extension;
  117. return createExt(Obj, FixLen::Ext2);
  118. case FirstByte::FixExt4:
  119. Obj.Kind = Type::Extension;
  120. return createExt(Obj, FixLen::Ext4);
  121. case FirstByte::FixExt8:
  122. Obj.Kind = Type::Extension;
  123. return createExt(Obj, FixLen::Ext8);
  124. case FirstByte::FixExt16:
  125. Obj.Kind = Type::Extension;
  126. return createExt(Obj, FixLen::Ext16);
  127. case FirstByte::Ext8:
  128. Obj.Kind = Type::Extension;
  129. return readExt<uint8_t>(Obj);
  130. case FirstByte::Ext16:
  131. Obj.Kind = Type::Extension;
  132. return readExt<uint16_t>(Obj);
  133. case FirstByte::Ext32:
  134. Obj.Kind = Type::Extension;
  135. return readExt<uint32_t>(Obj);
  136. }
  137. if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
  138. Obj.Kind = Type::Int;
  139. int8_t I;
  140. static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
  141. memcpy(&I, &FB, sizeof(FB));
  142. Obj.Int = I;
  143. return true;
  144. }
  145. if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
  146. Obj.Kind = Type::UInt;
  147. Obj.UInt = FB;
  148. return true;
  149. }
  150. if ((FB & FixBitsMask::String) == FixBits::String) {
  151. Obj.Kind = Type::String;
  152. uint8_t Size = FB & ~FixBitsMask::String;
  153. return createRaw(Obj, Size);
  154. }
  155. if ((FB & FixBitsMask::Array) == FixBits::Array) {
  156. Obj.Kind = Type::Array;
  157. Obj.Length = FB & ~FixBitsMask::Array;
  158. return true;
  159. }
  160. if ((FB & FixBitsMask::Map) == FixBits::Map) {
  161. Obj.Kind = Type::Map;
  162. Obj.Length = FB & ~FixBitsMask::Map;
  163. return true;
  164. }
  165. return make_error<StringError>(
  166. "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
  167. }
  168. template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
  169. if (sizeof(T) > remainingSpace())
  170. return make_error<StringError>(
  171. "Invalid Raw with insufficient payload",
  172. std::make_error_code(std::errc::invalid_argument));
  173. T Size = endian::read<T, Endianness>(Current);
  174. Current += sizeof(T);
  175. return createRaw(Obj, Size);
  176. }
  177. template <class T> Expected<bool> Reader::readInt(Object &Obj) {
  178. if (sizeof(T) > remainingSpace())
  179. return make_error<StringError>(
  180. "Invalid Int with insufficient payload",
  181. std::make_error_code(std::errc::invalid_argument));
  182. Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
  183. Current += sizeof(T);
  184. return true;
  185. }
  186. template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
  187. if (sizeof(T) > remainingSpace())
  188. return make_error<StringError>(
  189. "Invalid Int with insufficient payload",
  190. std::make_error_code(std::errc::invalid_argument));
  191. Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
  192. Current += sizeof(T);
  193. return true;
  194. }
  195. template <class T> Expected<bool> Reader::readLength(Object &Obj) {
  196. if (sizeof(T) > remainingSpace())
  197. return make_error<StringError>(
  198. "Invalid Map/Array with invalid length",
  199. std::make_error_code(std::errc::invalid_argument));
  200. Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
  201. Current += sizeof(T);
  202. return true;
  203. }
  204. template <class T> Expected<bool> Reader::readExt(Object &Obj) {
  205. if (sizeof(T) > remainingSpace())
  206. return make_error<StringError>(
  207. "Invalid Ext with invalid length",
  208. std::make_error_code(std::errc::invalid_argument));
  209. T Size = endian::read<T, Endianness>(Current);
  210. Current += sizeof(T);
  211. return createExt(Obj, Size);
  212. }
  213. Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
  214. if (Size > remainingSpace())
  215. return make_error<StringError>(
  216. "Invalid Raw with insufficient payload",
  217. std::make_error_code(std::errc::invalid_argument));
  218. Obj.Raw = StringRef(Current, Size);
  219. Current += Size;
  220. return true;
  221. }
  222. Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
  223. if (Current == End)
  224. return make_error<StringError>(
  225. "Invalid Ext with no type",
  226. std::make_error_code(std::errc::invalid_argument));
  227. Obj.Extension.Type = *Current++;
  228. if (Size > remainingSpace())
  229. return make_error<StringError>(
  230. "Invalid Ext with insufficient payload",
  231. std::make_error_code(std::errc::invalid_argument));
  232. Obj.Extension.Bytes = StringRef(Current, Size);
  233. Current += Size;
  234. return true;
  235. }