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"
20 using namespace msgpack
;
22 Writer::Writer(raw_ostream
&OS
, bool Compatible
)
23 : EW(OS
, Endianness
), Compatible(Compatible
) {}
25 void Writer::writeNil() { EW
.write(FirstByte::Nil
); }
27 void Writer::write(bool b
) { EW
.write(b
? FirstByte::True
: FirstByte::False
); }
29 void Writer::write(int64_t i
) {
31 write(static_cast<uint64_t>(i
));
35 if (i
>= FixMin::NegativeInt
) {
36 EW
.write(static_cast<int8_t>(i
));
41 EW
.write(FirstByte::Int8
);
42 EW
.write(static_cast<int8_t>(i
));
47 EW
.write(FirstByte::Int16
);
48 EW
.write(static_cast<int16_t>(i
));
53 EW
.write(FirstByte::Int32
);
54 EW
.write(static_cast<int32_t>(i
));
58 EW
.write(FirstByte::Int64
);
62 void Writer::write(uint64_t u
) {
63 if (u
<= FixMax::PositiveInt
) {
64 EW
.write(static_cast<uint8_t>(u
));
69 EW
.write(FirstByte::UInt8
);
70 EW
.write(static_cast<uint8_t>(u
));
74 if (u
<= UINT16_MAX
) {
75 EW
.write(FirstByte::UInt16
);
76 EW
.write(static_cast<uint16_t>(u
));
80 if (u
<= UINT32_MAX
) {
81 EW
.write(FirstByte::UInt32
);
82 EW
.write(static_cast<uint32_t>(u
));
86 EW
.write(FirstByte::UInt64
);
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
));
98 EW
.write(FirstByte::Float64
);
103 void Writer::write(StringRef s
) {
104 size_t Size
= s
.size();
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
));
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
));
123 void Writer::write(MemoryBufferRef Buffer
) {
124 assert(!Compatible
&& "Attempt to write Bin format in compatible mode");
126 size_t Size
= Buffer
.getBufferSize();
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
));
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
));
140 EW
.OS
.write(Buffer
.getBufferStart(), Size
);
143 void Writer::writeArraySize(uint32_t Size
) {
144 if (Size
<= FixMax::Array
) {
145 EW
.write(static_cast<uint8_t>(FixBits::Array
| Size
));
149 if (Size
<= UINT16_MAX
) {
150 EW
.write(FirstByte::Array16
);
151 EW
.write(static_cast<uint16_t>(Size
));
155 EW
.write(FirstByte::Array32
);
159 void Writer::writeMapSize(uint32_t Size
) {
160 if (Size
<= FixMax::Map
) {
161 EW
.write(static_cast<uint8_t>(FixBits::Map
| Size
));
165 if (Size
<= UINT16_MAX
) {
166 EW
.write(FirstByte::Map16
);
167 EW
.write(static_cast<uint16_t>(Size
));
171 EW
.write(FirstByte::Map32
);
175 void Writer::writeExt(int8_t Type
, MemoryBufferRef Buffer
) {
176 size_t Size
= Buffer
.getBufferSize();
180 EW
.write(FirstByte::FixExt1
);
183 EW
.write(FirstByte::FixExt2
);
186 EW
.write(FirstByte::FixExt4
);
189 EW
.write(FirstByte::FixExt8
);
192 EW
.write(FirstByte::FixExt16
);
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
));
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
));
209 EW
.OS
.write(Buffer
.getBufferStart(), Size
);