Fixing @llvm.memcpy not honoring volatile.
[llvm-core.git] / lib / BinaryFormat / MsgPackWriter.cpp
blobb4d70e8f78c12e0f3f4d63ec6dd5402349591954
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 //===----------------------------------------------------------------------===//
14 #include "llvm/BinaryFormat/MsgPackWriter.h"
15 #include "llvm/BinaryFormat/MsgPack.h"
17 using namespace llvm;
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) {
28 if (i >= 0) {
29 write(static_cast<uint64_t>(i));
30 return;
33 if (i >= FixMin::NegativeInt) {
34 EW.write(static_cast<int8_t>(i));
35 return;
38 if (i >= INT8_MIN) {
39 EW.write(FirstByte::Int8);
40 EW.write(static_cast<int8_t>(i));
41 return;
44 if (i >= INT16_MIN) {
45 EW.write(FirstByte::Int16);
46 EW.write(static_cast<int16_t>(i));
47 return;
50 if (i >= INT32_MIN) {
51 EW.write(FirstByte::Int32);
52 EW.write(static_cast<int32_t>(i));
53 return;
56 EW.write(FirstByte::Int64);
57 EW.write(i);
60 void Writer::write(uint64_t u) {
61 if (u <= FixMax::PositiveInt) {
62 EW.write(static_cast<uint8_t>(u));
63 return;
66 if (u <= UINT8_MAX) {
67 EW.write(FirstByte::UInt8);
68 EW.write(static_cast<uint8_t>(u));
69 return;
72 if (u <= UINT16_MAX) {
73 EW.write(FirstByte::UInt16);
74 EW.write(static_cast<uint16_t>(u));
75 return;
78 if (u <= UINT32_MAX) {
79 EW.write(FirstByte::UInt32);
80 EW.write(static_cast<uint32_t>(u));
81 return;
84 EW.write(FirstByte::UInt64);
85 EW.write(u);
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));
95 } else {
96 EW.write(FirstByte::Float64);
97 EW.write(d);
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));
112 } else {
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));
118 EW.OS << s;
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));
132 } else {
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));
144 return;
147 if (Size <= UINT16_MAX) {
148 EW.write(FirstByte::Array16);
149 EW.write(static_cast<uint16_t>(Size));
150 return;
153 EW.write(FirstByte::Array32);
154 EW.write(Size);
157 void Writer::writeMapSize(uint32_t Size) {
158 if (Size <= FixMax::Map) {
159 EW.write(static_cast<uint8_t>(FixBits::Map | Size));
160 return;
163 if (Size <= UINT16_MAX) {
164 EW.write(FirstByte::Map16);
165 EW.write(static_cast<uint16_t>(Size));
166 return;
169 EW.write(FirstByte::Map32);
170 EW.write(Size);
173 void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {
174 size_t Size = Buffer.getBufferSize();
176 switch (Size) {
177 case FixLen::Ext1:
178 EW.write(FirstByte::FixExt1);
179 break;
180 case FixLen::Ext2:
181 EW.write(FirstByte::FixExt2);
182 break;
183 case FixLen::Ext4:
184 EW.write(FirstByte::FixExt4);
185 break;
186 case FixLen::Ext8:
187 EW.write(FirstByte::FixExt8);
188 break;
189 case FixLen::Ext16:
190 EW.write(FirstByte::FixExt16);
191 break;
192 default:
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));
199 } else {
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));
206 EW.write(Type);
207 EW.OS.write(Buffer.getBufferStart(), Size);