1 //===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file implements a MessagePack writer.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/BinaryFormat/MsgPackWriter.h"
15 #include "llvm/BinaryFormat/MsgPack.h"
18 using namespace msgpack
;
20 Writer::Writer(raw_ostream
&OS
, bool Compatible
)
21 : EW(OS
, Endianness
), Compatible(Compatible
) {}
23 void Writer::writeNil() { EW
.write(FirstByte::Nil
); }
25 void Writer::write(bool b
) { EW
.write(b
? FirstByte::True
: FirstByte::False
); }
27 void Writer::write(int64_t i
) {
29 write(static_cast<uint64_t>(i
));
33 if (i
>= FixMin::NegativeInt
) {
34 EW
.write(static_cast<int8_t>(i
));
39 EW
.write(FirstByte::Int8
);
40 EW
.write(static_cast<int8_t>(i
));
45 EW
.write(FirstByte::Int16
);
46 EW
.write(static_cast<int16_t>(i
));
51 EW
.write(FirstByte::Int32
);
52 EW
.write(static_cast<int32_t>(i
));
56 EW
.write(FirstByte::Int64
);
60 void Writer::write(uint64_t u
) {
61 if (u
<= FixMax::PositiveInt
) {
62 EW
.write(static_cast<uint8_t>(u
));
67 EW
.write(FirstByte::UInt8
);
68 EW
.write(static_cast<uint8_t>(u
));
72 if (u
<= UINT16_MAX
) {
73 EW
.write(FirstByte::UInt16
);
74 EW
.write(static_cast<uint16_t>(u
));
78 if (u
<= UINT32_MAX
) {
79 EW
.write(FirstByte::UInt32
);
80 EW
.write(static_cast<uint32_t>(u
));
84 EW
.write(FirstByte::UInt64
);
88 void Writer::write(double d
) {
89 // If no loss of precision, encode as a Float32.
90 double a
= std::fabs(d
);
91 if (a
>= std::numeric_limits
<float>::min() &&
92 a
<= std::numeric_limits
<float>::max()) {
93 EW
.write(FirstByte::Float32
);
94 EW
.write(static_cast<float>(d
));
96 EW
.write(FirstByte::Float64
);
101 void Writer::write(StringRef s
) {
102 size_t Size
= s
.size();
104 if (Size
<= FixMax::String
)
105 EW
.write(static_cast<uint8_t>(FixBits::String
| Size
));
106 else if (!Compatible
&& Size
<= UINT8_MAX
) {
107 EW
.write(FirstByte::Str8
);
108 EW
.write(static_cast<uint8_t>(Size
));
109 } else if (Size
<= UINT16_MAX
) {
110 EW
.write(FirstByte::Str16
);
111 EW
.write(static_cast<uint16_t>(Size
));
113 assert(Size
<= UINT32_MAX
&& "String object too long to be encoded");
114 EW
.write(FirstByte::Str32
);
115 EW
.write(static_cast<uint32_t>(Size
));
121 void Writer::write(MemoryBufferRef Buffer
) {
122 assert(!Compatible
&& "Attempt to write Bin format in compatible mode");
124 size_t Size
= Buffer
.getBufferSize();
126 if (Size
<= UINT8_MAX
) {
127 EW
.write(FirstByte::Bin8
);
128 EW
.write(static_cast<uint8_t>(Size
));
129 } else if (Size
<= UINT16_MAX
) {
130 EW
.write(FirstByte::Bin16
);
131 EW
.write(static_cast<uint16_t>(Size
));
133 assert(Size
<= UINT32_MAX
&& "Binary object too long to be encoded");
134 EW
.write(FirstByte::Bin32
);
135 EW
.write(static_cast<uint32_t>(Size
));
138 EW
.OS
.write(Buffer
.getBufferStart(), Size
);
141 void Writer::writeArraySize(uint32_t Size
) {
142 if (Size
<= FixMax::Array
) {
143 EW
.write(static_cast<uint8_t>(FixBits::Array
| Size
));
147 if (Size
<= UINT16_MAX
) {
148 EW
.write(FirstByte::Array16
);
149 EW
.write(static_cast<uint16_t>(Size
));
153 EW
.write(FirstByte::Array32
);
157 void Writer::writeMapSize(uint32_t Size
) {
158 if (Size
<= FixMax::Map
) {
159 EW
.write(static_cast<uint8_t>(FixBits::Map
| Size
));
163 if (Size
<= UINT16_MAX
) {
164 EW
.write(FirstByte::Map16
);
165 EW
.write(static_cast<uint16_t>(Size
));
169 EW
.write(FirstByte::Map32
);
173 void Writer::writeExt(int8_t Type
, MemoryBufferRef Buffer
) {
174 size_t Size
= Buffer
.getBufferSize();
178 EW
.write(FirstByte::FixExt1
);
181 EW
.write(FirstByte::FixExt2
);
184 EW
.write(FirstByte::FixExt4
);
187 EW
.write(FirstByte::FixExt8
);
190 EW
.write(FirstByte::FixExt16
);
193 if (Size
<= UINT8_MAX
) {
194 EW
.write(FirstByte::Ext8
);
195 EW
.write(static_cast<uint8_t>(Size
));
196 } else if (Size
<= UINT16_MAX
) {
197 EW
.write(FirstByte::Ext16
);
198 EW
.write(static_cast<uint16_t>(Size
));
200 assert(Size
<= UINT32_MAX
&& "Ext size too large to be encoded");
201 EW
.write(FirstByte::Ext32
);
202 EW
.write(static_cast<uint32_t>(Size
));
207 EW
.OS
.write(Buffer
.getBufferStart(), Size
);