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