MsgPackReader.cpp 7.8 KB

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