LLVM 17.0.0git
MsgPackWriter.cpp
Go to the documentation of this file.
1//===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- 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 writer.
11///
12//===----------------------------------------------------------------------===//
13
16
17#include <cmath>
18
19using namespace llvm;
20using namespace msgpack;
21
22Writer::Writer(raw_ostream &OS, bool Compatible)
23 : EW(OS, Endianness), Compatible(Compatible) {}
24
25void Writer::writeNil() { EW.write(FirstByte::Nil); }
26
27void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }
28
29void Writer::write(int64_t i) {
30 if (i >= 0) {
31 write(static_cast<uint64_t>(i));
32 return;
33 }
34
35 if (i >= FixMin::NegativeInt) {
36 EW.write(static_cast<int8_t>(i));
37 return;
38 }
39
40 if (i >= INT8_MIN) {
41 EW.write(FirstByte::Int8);
42 EW.write(static_cast<int8_t>(i));
43 return;
44 }
45
46 if (i >= INT16_MIN) {
47 EW.write(FirstByte::Int16);
48 EW.write(static_cast<int16_t>(i));
49 return;
50 }
51
52 if (i >= INT32_MIN) {
53 EW.write(FirstByte::Int32);
54 EW.write(static_cast<int32_t>(i));
55 return;
56 }
57
58 EW.write(FirstByte::Int64);
59 EW.write(i);
60}
61
63 if (u <= FixMax::PositiveInt) {
64 EW.write(static_cast<uint8_t>(u));
65 return;
66 }
67
68 if (u <= UINT8_MAX) {
69 EW.write(FirstByte::UInt8);
70 EW.write(static_cast<uint8_t>(u));
71 return;
72 }
73
74 if (u <= UINT16_MAX) {
75 EW.write(FirstByte::UInt16);
76 EW.write(static_cast<uint16_t>(u));
77 return;
78 }
79
80 if (u <= UINT32_MAX) {
81 EW.write(FirstByte::UInt32);
82 EW.write(static_cast<uint32_t>(u));
83 return;
84 }
85
86 EW.write(FirstByte::UInt64);
87 EW.write(u);
88}
89
90void Writer::write(double d) {
91 // If no loss of precision, encode as a Float32.
92 double a = std::fabs(d);
93 if (a >= std::numeric_limits<float>::min() &&
94 a <= std::numeric_limits<float>::max()) {
95 EW.write(FirstByte::Float32);
96 EW.write(static_cast<float>(d));
97 } else {
98 EW.write(FirstByte::Float64);
99 EW.write(d);
100 }
101}
102
104 size_t Size = s.size();
105
106 if (Size <= FixMax::String)
107 EW.write(static_cast<uint8_t>(FixBits::String | Size));
108 else if (!Compatible && Size <= UINT8_MAX) {
109 EW.write(FirstByte::Str8);
110 EW.write(static_cast<uint8_t>(Size));
111 } else if (Size <= UINT16_MAX) {
112 EW.write(FirstByte::Str16);
113 EW.write(static_cast<uint16_t>(Size));
114 } else {
115 assert(Size <= UINT32_MAX && "String object too long to be encoded");
116 EW.write(FirstByte::Str32);
117 EW.write(static_cast<uint32_t>(Size));
118 }
119
120 EW.OS << s;
121}
122
124 assert(!Compatible && "Attempt to write Bin format in compatible mode");
125
126 size_t Size = Buffer.getBufferSize();
127
128 if (Size <= UINT8_MAX) {
129 EW.write(FirstByte::Bin8);
130 EW.write(static_cast<uint8_t>(Size));
131 } else if (Size <= UINT16_MAX) {
132 EW.write(FirstByte::Bin16);
133 EW.write(static_cast<uint16_t>(Size));
134 } else {
135 assert(Size <= UINT32_MAX && "Binary object too long to be encoded");
136 EW.write(FirstByte::Bin32);
137 EW.write(static_cast<uint32_t>(Size));
138 }
139
140 EW.OS.write(Buffer.getBufferStart(), Size);
141}
142
144 if (Size <= FixMax::Array) {
145 EW.write(static_cast<uint8_t>(FixBits::Array | Size));
146 return;
147 }
148
149 if (Size <= UINT16_MAX) {
150 EW.write(FirstByte::Array16);
151 EW.write(static_cast<uint16_t>(Size));
152 return;
153 }
154
155 EW.write(FirstByte::Array32);
156 EW.write(Size);
157}
158
160 if (Size <= FixMax::Map) {
161 EW.write(static_cast<uint8_t>(FixBits::Map | Size));
162 return;
163 }
164
165 if (Size <= UINT16_MAX) {
166 EW.write(FirstByte::Map16);
167 EW.write(static_cast<uint16_t>(Size));
168 return;
169 }
170
171 EW.write(FirstByte::Map32);
172 EW.write(Size);
173}
174
176 size_t Size = Buffer.getBufferSize();
177
178 switch (Size) {
179 case FixLen::Ext1:
180 EW.write(FirstByte::FixExt1);
181 break;
182 case FixLen::Ext2:
183 EW.write(FirstByte::FixExt2);
184 break;
185 case FixLen::Ext4:
186 EW.write(FirstByte::FixExt4);
187 break;
188 case FixLen::Ext8:
189 EW.write(FirstByte::FixExt8);
190 break;
191 case FixLen::Ext16:
192 EW.write(FirstByte::FixExt16);
193 break;
194 default:
195 if (Size <= UINT8_MAX) {
196 EW.write(FirstByte::Ext8);
197 EW.write(static_cast<uint8_t>(Size));
198 } else if (Size <= UINT16_MAX) {
199 EW.write(FirstByte::Ext16);
200 EW.write(static_cast<uint16_t>(Size));
201 } else {
202 assert(Size <= UINT32_MAX && "Ext size too large to be encoded");
203 EW.write(FirstByte::Ext32);
204 EW.write(static_cast<uint32_t>(Size));
205 }
206 }
207
208 EW.write(Type);
209 EW.OS.write(Buffer.getBufferStart(), Size);
210}
uint64_t Size
This file contains a MessagePack writer.
This file contains constants used for implementing MessagePack support.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
size_t getBufferSize() const
const char * getBufferStart() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
void writeNil()
Write a Nil to the output stream.
Writer(raw_ostream &OS, bool Compatible=false)
Construct a writer, optionally enabling "Compatibility Mode" as defined in the MessagePack specificat...
void writeMapSize(uint32_t Size)
Write the header for a Map of the given size.
void writeArraySize(uint32_t Size)
Write the header for an Array of the given size.
void writeExt(int8_t Type, MemoryBufferRef Buffer)
Write a typed memory buffer (an extension type) to the output stream.
void write(bool b)
Write a Boolean to the output stream.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
raw_ostream & write(unsigned char C)
constexpr support::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
Definition: MsgPack.h:24
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
Definition: MsgPackReader.h:48
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void write(ArrayRef< value_type > Val)
Definition: EndianStream.h:56