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