[llvm-exegesis][NFC] Fix typo
[llvm-complete.git] / lib / BinaryFormat / MsgPackReader.cpp
blobb510fdba960808c9742e7e0824dbe01de9498303
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 //===----------------------------------------------------------------------===//
15 #include "llvm/BinaryFormat/MsgPackReader.h"
16 #include "llvm/BinaryFormat/MsgPack.h"
17 #include "llvm/Support/Endian.h"
19 using namespace llvm;
20 using namespace llvm::support;
21 using namespace msgpack;
23 Reader::Reader(MemoryBufferRef InputBuffer)
24 : InputBuffer(InputBuffer), Current(InputBuffer.getBufferStart()),
25 End(InputBuffer.getBufferEnd()) {}
27 Reader::Reader(StringRef Input) : Reader({Input, "MsgPack"}) {}
29 Expected<bool> Reader::read(Object &Obj) {
30 if (Current == End)
31 return false;
33 uint8_t FB = static_cast<uint8_t>(*Current++);
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);
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;
154 if ((FB & FixBitsMask::PositiveInt) == FixBits::PositiveInt) {
155 Obj.Kind = Type::UInt;
156 Obj.UInt = FB;
157 return true;
160 if ((FB & FixBitsMask::String) == FixBits::String) {
161 Obj.Kind = Type::String;
162 uint8_t Size = FB & ~FixBitsMask::String;
163 return createRaw(Obj, Size);
166 if ((FB & FixBitsMask::Array) == FixBits::Array) {
167 Obj.Kind = Type::Array;
168 Obj.Length = FB & ~FixBitsMask::Array;
169 return true;
172 if ((FB & FixBitsMask::Map) == FixBits::Map) {
173 Obj.Kind = Type::Map;
174 Obj.Length = FB & ~FixBitsMask::Map;
175 return true;
178 return make_error<StringError>(
179 "Invalid first byte", std::make_error_code(std::errc::invalid_argument));
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);
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;
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;
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;
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);
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;
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;