Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp
35233 views
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
14
#include "llvm/BinaryFormat/MsgPackWriter.h"
15
#include "llvm/BinaryFormat/MsgPack.h"
16
17
#include <cmath>
18
19
using namespace llvm;
20
using namespace msgpack;
21
22
Writer::Writer(raw_ostream &OS, bool Compatible)
23
: EW(OS, Endianness), Compatible(Compatible) {}
24
25
void Writer::writeNil() { EW.write(FirstByte::Nil); }
26
27
void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }
28
29
void 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
62
void Writer::write(uint64_t u) {
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
90
void 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
103
void Writer::write(StringRef s) {
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
123
void Writer::write(MemoryBufferRef Buffer) {
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
143
void Writer::writeArraySize(uint32_t Size) {
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
159
void Writer::writeMapSize(uint32_t Size) {
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
175
void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {
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
}
211
212