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