LLVM  8.0.1
MsgPackReader.cpp
Go to the documentation of this file.
1 //===- MsgPackReader.cpp - Simple MsgPack reader ----------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// This file implements a MessagePack reader.
12 ///
13 //===----------------------------------------------------------------------===//
14 
17 #include "llvm/Support/Endian.h"
18 
19 using namespace llvm;
20 using namespace llvm::support;
21 using namespace msgpack;
22 
23 Reader::Reader(MemoryBufferRef InputBuffer)
24  : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
25  End(InputBuffer.getBufferEnd()) {}
26 
27 Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
28 
30  if (Current == End)
31  return false;
32 
33  uint8_t FB = static_cast<uint8_t>(*Current++);
34 
35  switch (FB) {
36  case FirstByte::Nil:
37  Obj.Kind = Type::Nil;
38  return true;
39  case FirstByte::True:
40  Obj.Kind = Type::Boolean;
41  Obj.Bool = true;
42  return true;
43  case FirstByte::False:
44  Obj.Kind = Type::Boolean;
45  Obj.Bool = false;
46  return true;
47  case FirstByte::Int8:
48  Obj.Kind = Type::Int;
49  return readInt<int8_t>(Obj);
50  case FirstByte::Int16:
51  Obj.Kind = Type::Int;
52  return readInt<int16_t>(Obj);
53  case FirstByte::Int32:
54  Obj.Kind = Type::Int;
55  return readInt<int32_t>(Obj);
56  case FirstByte::Int64:
57  Obj.Kind = Type::Int;
58  return readInt<int64_t>(Obj);
59  case FirstByte::UInt8:
60  Obj.Kind = Type::UInt;
61  return readUInt<uint8_t>(Obj);
62  case FirstByte::UInt16:
63  Obj.Kind = Type::UInt;
64  return readUInt<uint16_t>(Obj);
65  case FirstByte::UInt32:
66  Obj.Kind = Type::UInt;
67  return readUInt<uint32_t>(Obj);
68  case FirstByte::UInt64:
69  Obj.Kind = Type::UInt;
70  return readUInt<uint64_t>(Obj);
71  case FirstByte::Float32:
72  Obj.Kind = Type::Float;
73  if (sizeof(float) > remainingSpace())
74  return make_error<StringError>(
75  "Invalid Float32 with insufficient payload",
76  std::make_error_code(std::errc::invalid_argument));
77  Obj.Float = BitsToFloat(endian::read<uint32_t, Endianness>(Current));
78  Current += sizeof(float);
79  return true;
80  case FirstByte::Float64:
81  Obj.Kind = Type::Float;
82  if (sizeof(double) > remainingSpace())
83  return make_error<StringError>(
84  "Invalid Float64 with insufficient payload",
85  std::make_error_code(std::errc::invalid_argument));
86  Obj.Float = BitsToDouble(endian::read<uint64_t, Endianness>(Current));
87  Current += sizeof(double);
88  return true;
89  case FirstByte::Str8:
90  Obj.Kind = Type::String;
91  return readRaw<uint8_t>(Obj);
92  case FirstByte::Str16:
93  Obj.Kind = Type::String;
94  return readRaw<uint16_t>(Obj);
95  case FirstByte::Str32:
96  Obj.Kind = Type::String;
97  return readRaw<uint32_t>(Obj);
98  case FirstByte::Bin8:
99  Obj.Kind = Type::Binary;
100  return readRaw<uint8_t>(Obj);
101  case FirstByte::Bin16:
102  Obj.Kind = Type::Binary;
103  return readRaw<uint16_t>(Obj);
104  case FirstByte::Bin32:
105  Obj.Kind = Type::Binary;
106  return readRaw<uint32_t>(Obj);
107  case FirstByte::Array16:
108  Obj.Kind = Type::Array;
109  return readLength<uint16_t>(Obj);
110  case FirstByte::Array32:
111  Obj.Kind = Type::Array;
112  return readLength<uint32_t>(Obj);
113  case FirstByte::Map16:
114  Obj.Kind = Type::Map;
115  return readLength<uint16_t>(Obj);
116  case FirstByte::Map32:
117  Obj.Kind = Type::Map;
118  return readLength<uint32_t>(Obj);
119  case FirstByte::FixExt1:
120  Obj.Kind = Type::Extension;
121  return createExt(Obj, FixLen::Ext1);
122  case FirstByte::FixExt2:
123  Obj.Kind = Type::Extension;
124  return createExt(Obj, FixLen::Ext2);
125  case FirstByte::FixExt4:
126  Obj.Kind = Type::Extension;
127  return createExt(Obj, FixLen::Ext4);
128  case FirstByte::FixExt8:
129  Obj.Kind = Type::Extension;
130  return createExt(Obj, FixLen::Ext8);
131  case FirstByte::FixExt16:
132  Obj.Kind = Type::Extension;
133  return createExt(Obj, FixLen::Ext16);
134  case FirstByte::Ext8:
135  Obj.Kind = Type::Extension;
136  return readExt<uint8_t>(Obj);
137  case FirstByte::Ext16:
138  Obj.Kind = Type::Extension;
139  return readExt<uint16_t>(Obj);
140  case FirstByte::Ext32:
141  Obj.Kind = Type::Extension;
142  return readExt<uint32_t>(Obj);
143  }
144 
145  if ((FB & FixBitsMask::NegativeInt) == FixBits::NegativeInt) {
146  Obj.Kind = Type::Int;
147  int8_t I;
148  static_assert(sizeof(I) == sizeof(FB), "Unexpected type sizes");
149  memcpy(&I, &FB, sizeof(FB));
150  Obj.Int = I;
151  return true;
152  }
153 
154  if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
155  Obj.Kind = Type::UInt;
156  Obj.UInt = FB;
157  return true;
158  }
159 
160  if ((FB & FixBitsMask::String) == FixBits::String) {
161  Obj.Kind = Type::String;
162  uint8_t Size = FB & ~FixBitsMask::String;
163  return createRaw(Obj, Size);
164  }
165 
166  if ((FB & FixBitsMask::Array) == FixBits::Array) {
167  Obj.Kind = Type::Array;
168  Obj.Length = FB & ~FixBitsMask::Array;
169  return true;
170  }
171 
172  if ((FB & FixBitsMask::Map) == FixBits::Map) {
173  Obj.Kind = Type::Map;
174  Obj.Length = FB & ~FixBitsMask::Map;
175  return true;
176  }
177 
178  return make_error<StringError>(
179  "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
180 }
181 
182 template <class T> Expected<bool> Reader::readRaw(Object &Obj) {
183  if (sizeof(T) > remainingSpace())
184  return make_error<StringError>(
185  "Invalid Raw with insufficient payload",
186  std::make_error_code(std::errc::invalid_argument));
187  T Size = endian::read<T, Endianness>(Current);
188  Current += sizeof(T);
189  return createRaw(Obj, Size);
190 }
191 
192 template <class T> Expected<bool> Reader::readInt(Object &Obj) {
193  if (sizeof(T) > remainingSpace())
194  return make_error<StringError>(
195  "Invalid Int with insufficient payload",
196  std::make_error_code(std::errc::invalid_argument));
197  Obj.Int = static_cast<int64_t>(endian::read<T, Endianness>(Current));
198  Current += sizeof(T);
199  return true;
200 }
201 
202 template <class T> Expected<bool> Reader::readUInt(Object &Obj) {
203  if (sizeof(T) > remainingSpace())
204  return make_error<StringError>(
205  "Invalid Int with insufficient payload",
206  std::make_error_code(std::errc::invalid_argument));
207  Obj.UInt = static_cast<uint64_t>(endian::read<T, Endianness>(Current));
208  Current += sizeof(T);
209  return true;
210 }
211 
212 template <class T> Expected<bool> Reader::readLength(Object &Obj) {
213  if (sizeof(T) > remainingSpace())
214  return make_error<StringError>(
215  "Invalid Map/Array with invalid length",
216  std::make_error_code(std::errc::invalid_argument));
217  Obj.Length = static_cast<size_t>(endian::read<T, Endianness>(Current));
218  Current += sizeof(T);
219  return true;
220 }
221 
222 template <class T> Expected<bool> Reader::readExt(Object &Obj) {
223  if (sizeof(T) > remainingSpace())
224  return make_error<StringError>(
225  "Invalid Ext with invalid length",
226  std::make_error_code(std::errc::invalid_argument));
227  T Size = endian::read<T, Endianness>(Current);
228  Current += sizeof(T);
229  return createExt(Obj, Size);
230 }
231 
232 Expected<bool> Reader::createRaw(Object &Obj, uint32_t Size) {
233  if (Size > remainingSpace())
234  return make_error<StringError>(
235  "Invalid Raw with insufficient payload",
236  std::make_error_code(std::errc::invalid_argument));
237  Obj.Raw = StringRef(Current, Size);
238  Current += Size;
239  return true;
240 }
241 
242 Expected<bool> Reader::createExt(Object &Obj, uint32_t Size) {
243  if (Current == End)
244  return make_error<StringError>(
245  "Invalid Ext with no type",
246  std::make_error_code(std::errc::invalid_argument));
247  Obj.Extension.Type = *Current++;
248  if (Size > remainingSpace())
249  return make_error<StringError>(
250  "Invalid Ext with insufficient payload",
251  std::make_error_code(std::errc::invalid_argument));
252  Obj.Extension.Bytes = StringRef(Current, Size);
253  Current += Size;
254  return true;
255 }
ExtensionType Extension
Value for Type::Extension.
Definition: MsgPackReader.h:92
Expected< bool > read(Object &Obj)
Read one object from the input buffer, advancing past it.
This class represents lattice values for constants.
Definition: AllocatorList.h:24
float BitsToFloat(uint32_t Bits)
This function takes a 32-bit integer and returns the bit equivalent float.
Definition: MathExtras.h:581
std::error_code make_error_code(BitcodeError E)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
#define T
MessagePack object, represented as a tagged union of C++ types.
Definition: MsgPackReader.h:76
Reads MessagePack objects from memory, one at a time.
Definition: MsgPackReader.h:99
double Float
Value for Type::Float.
Definition: MsgPackReader.h:86
This is a MessagePack reader.
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
Definition: MathExtras.h:573
int8_t Type
User-defined extension type.
Definition: MsgPackReader.h:66
StringRef Raw
Value for Type::String and Type::Binary.
Definition: MsgPackReader.h:88
#define I(x, y, z)
Definition: MD5.cpp:58
int64_t Int
Value for Type::Int.
Definition: MsgPackReader.h:80
uint32_t Size
Definition: Profile.cpp:47
This file contains constants used for implementing MessagePack support.
StringRef Bytes
Raw bytes of the extension object.
Definition: MsgPackReader.h:68
bool Bool
Value for Type::Boolean.
Definition: MsgPackReader.h:84
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
uint64_t UInt
Value for Type::Uint.
Definition: MsgPackReader.h:82
size_t Length
Value for Type::Array and Type::Map.
Definition: MsgPackReader.h:90
Reader(MemoryBufferRef InputBuffer)
Construct a reader, keeping a reference to the InputBuffer.