xref: /src/contrib/llvm-project/llvm/lib/BinaryFormat/MsgPackWriter.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1d8e91e46SDimitry Andric //===- MsgPackWriter.cpp - Simple MsgPack writer ----------------*- C++ -*-===//
2d8e91e46SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d8e91e46SDimitry Andric //
7d8e91e46SDimitry Andric //===----------------------------------------------------------------------===//
8d8e91e46SDimitry Andric ///
9d8e91e46SDimitry Andric ///  \file
10d8e91e46SDimitry Andric ///  This file implements a MessagePack writer.
11d8e91e46SDimitry Andric ///
12d8e91e46SDimitry Andric //===----------------------------------------------------------------------===//
13d8e91e46SDimitry Andric 
14d8e91e46SDimitry Andric #include "llvm/BinaryFormat/MsgPackWriter.h"
15d8e91e46SDimitry Andric #include "llvm/BinaryFormat/MsgPack.h"
16d8e91e46SDimitry Andric 
17e3b55780SDimitry Andric #include <cmath>
18e3b55780SDimitry Andric 
19d8e91e46SDimitry Andric using namespace llvm;
20d8e91e46SDimitry Andric using namespace msgpack;
21d8e91e46SDimitry Andric 
Writer(raw_ostream & OS,bool Compatible)22d8e91e46SDimitry Andric Writer::Writer(raw_ostream &OS, bool Compatible)
23d8e91e46SDimitry Andric     : EW(OS, Endianness), Compatible(Compatible) {}
24d8e91e46SDimitry Andric 
writeNil()25d8e91e46SDimitry Andric void Writer::writeNil() { EW.write(FirstByte::Nil); }
26d8e91e46SDimitry Andric 
write(bool b)27d8e91e46SDimitry Andric void Writer::write(bool b) { EW.write(b ? FirstByte::True : FirstByte::False); }
28d8e91e46SDimitry Andric 
write(int64_t i)29d8e91e46SDimitry Andric void Writer::write(int64_t i) {
30d8e91e46SDimitry Andric   if (i >= 0) {
31d8e91e46SDimitry Andric     write(static_cast<uint64_t>(i));
32d8e91e46SDimitry Andric     return;
33d8e91e46SDimitry Andric   }
34d8e91e46SDimitry Andric 
35d8e91e46SDimitry Andric   if (i >= FixMin::NegativeInt) {
36d8e91e46SDimitry Andric     EW.write(static_cast<int8_t>(i));
37d8e91e46SDimitry Andric     return;
38d8e91e46SDimitry Andric   }
39d8e91e46SDimitry Andric 
40d8e91e46SDimitry Andric   if (i >= INT8_MIN) {
41d8e91e46SDimitry Andric     EW.write(FirstByte::Int8);
42d8e91e46SDimitry Andric     EW.write(static_cast<int8_t>(i));
43d8e91e46SDimitry Andric     return;
44d8e91e46SDimitry Andric   }
45d8e91e46SDimitry Andric 
46d8e91e46SDimitry Andric   if (i >= INT16_MIN) {
47d8e91e46SDimitry Andric     EW.write(FirstByte::Int16);
48d8e91e46SDimitry Andric     EW.write(static_cast<int16_t>(i));
49d8e91e46SDimitry Andric     return;
50d8e91e46SDimitry Andric   }
51d8e91e46SDimitry Andric 
52d8e91e46SDimitry Andric   if (i >= INT32_MIN) {
53d8e91e46SDimitry Andric     EW.write(FirstByte::Int32);
54d8e91e46SDimitry Andric     EW.write(static_cast<int32_t>(i));
55d8e91e46SDimitry Andric     return;
56d8e91e46SDimitry Andric   }
57d8e91e46SDimitry Andric 
58d8e91e46SDimitry Andric   EW.write(FirstByte::Int64);
59d8e91e46SDimitry Andric   EW.write(i);
60d8e91e46SDimitry Andric }
61d8e91e46SDimitry Andric 
write(uint64_t u)62d8e91e46SDimitry Andric void Writer::write(uint64_t u) {
63d8e91e46SDimitry Andric   if (u <= FixMax::PositiveInt) {
64d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(u));
65d8e91e46SDimitry Andric     return;
66d8e91e46SDimitry Andric   }
67d8e91e46SDimitry Andric 
68d8e91e46SDimitry Andric   if (u <= UINT8_MAX) {
69d8e91e46SDimitry Andric     EW.write(FirstByte::UInt8);
70d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(u));
71d8e91e46SDimitry Andric     return;
72d8e91e46SDimitry Andric   }
73d8e91e46SDimitry Andric 
74d8e91e46SDimitry Andric   if (u <= UINT16_MAX) {
75d8e91e46SDimitry Andric     EW.write(FirstByte::UInt16);
76d8e91e46SDimitry Andric     EW.write(static_cast<uint16_t>(u));
77d8e91e46SDimitry Andric     return;
78d8e91e46SDimitry Andric   }
79d8e91e46SDimitry Andric 
80d8e91e46SDimitry Andric   if (u <= UINT32_MAX) {
81d8e91e46SDimitry Andric     EW.write(FirstByte::UInt32);
82d8e91e46SDimitry Andric     EW.write(static_cast<uint32_t>(u));
83d8e91e46SDimitry Andric     return;
84d8e91e46SDimitry Andric   }
85d8e91e46SDimitry Andric 
86d8e91e46SDimitry Andric   EW.write(FirstByte::UInt64);
87d8e91e46SDimitry Andric   EW.write(u);
88d8e91e46SDimitry Andric }
89d8e91e46SDimitry Andric 
write(double d)90d8e91e46SDimitry Andric void Writer::write(double d) {
91d8e91e46SDimitry Andric   // If no loss of precision, encode as a Float32.
92d8e91e46SDimitry Andric   double a = std::fabs(d);
93d8e91e46SDimitry Andric   if (a >= std::numeric_limits<float>::min() &&
94d8e91e46SDimitry Andric       a <= std::numeric_limits<float>::max()) {
95d8e91e46SDimitry Andric     EW.write(FirstByte::Float32);
96d8e91e46SDimitry Andric     EW.write(static_cast<float>(d));
97d8e91e46SDimitry Andric   } else {
98d8e91e46SDimitry Andric     EW.write(FirstByte::Float64);
99d8e91e46SDimitry Andric     EW.write(d);
100d8e91e46SDimitry Andric   }
101d8e91e46SDimitry Andric }
102d8e91e46SDimitry Andric 
write(StringRef s)103d8e91e46SDimitry Andric void Writer::write(StringRef s) {
104d8e91e46SDimitry Andric   size_t Size = s.size();
105d8e91e46SDimitry Andric 
106d8e91e46SDimitry Andric   if (Size <= FixMax::String)
107d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(FixBits::String | Size));
108d8e91e46SDimitry Andric   else if (!Compatible && Size <= UINT8_MAX) {
109d8e91e46SDimitry Andric     EW.write(FirstByte::Str8);
110d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(Size));
111d8e91e46SDimitry Andric   } else if (Size <= UINT16_MAX) {
112d8e91e46SDimitry Andric     EW.write(FirstByte::Str16);
113d8e91e46SDimitry Andric     EW.write(static_cast<uint16_t>(Size));
114d8e91e46SDimitry Andric   } else {
115d8e91e46SDimitry Andric     assert(Size <= UINT32_MAX && "String object too long to be encoded");
116d8e91e46SDimitry Andric     EW.write(FirstByte::Str32);
117d8e91e46SDimitry Andric     EW.write(static_cast<uint32_t>(Size));
118d8e91e46SDimitry Andric   }
119d8e91e46SDimitry Andric 
120d8e91e46SDimitry Andric   EW.OS << s;
121d8e91e46SDimitry Andric }
122d8e91e46SDimitry Andric 
write(MemoryBufferRef Buffer)123d8e91e46SDimitry Andric void Writer::write(MemoryBufferRef Buffer) {
124d8e91e46SDimitry Andric   assert(!Compatible && "Attempt to write Bin format in compatible mode");
125d8e91e46SDimitry Andric 
126d8e91e46SDimitry Andric   size_t Size = Buffer.getBufferSize();
127d8e91e46SDimitry Andric 
128d8e91e46SDimitry Andric   if (Size <= UINT8_MAX) {
129d8e91e46SDimitry Andric     EW.write(FirstByte::Bin8);
130d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(Size));
131d8e91e46SDimitry Andric   } else if (Size <= UINT16_MAX) {
132d8e91e46SDimitry Andric     EW.write(FirstByte::Bin16);
133d8e91e46SDimitry Andric     EW.write(static_cast<uint16_t>(Size));
134d8e91e46SDimitry Andric   } else {
135d8e91e46SDimitry Andric     assert(Size <= UINT32_MAX && "Binary object too long to be encoded");
136d8e91e46SDimitry Andric     EW.write(FirstByte::Bin32);
137d8e91e46SDimitry Andric     EW.write(static_cast<uint32_t>(Size));
138d8e91e46SDimitry Andric   }
139d8e91e46SDimitry Andric 
140d8e91e46SDimitry Andric   EW.OS.write(Buffer.getBufferStart(), Size);
141d8e91e46SDimitry Andric }
142d8e91e46SDimitry Andric 
writeArraySize(uint32_t Size)143d8e91e46SDimitry Andric void Writer::writeArraySize(uint32_t Size) {
144d8e91e46SDimitry Andric   if (Size <= FixMax::Array) {
145d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(FixBits::Array | Size));
146d8e91e46SDimitry Andric     return;
147d8e91e46SDimitry Andric   }
148d8e91e46SDimitry Andric 
149d8e91e46SDimitry Andric   if (Size <= UINT16_MAX) {
150d8e91e46SDimitry Andric     EW.write(FirstByte::Array16);
151d8e91e46SDimitry Andric     EW.write(static_cast<uint16_t>(Size));
152d8e91e46SDimitry Andric     return;
153d8e91e46SDimitry Andric   }
154d8e91e46SDimitry Andric 
155d8e91e46SDimitry Andric   EW.write(FirstByte::Array32);
156d8e91e46SDimitry Andric   EW.write(Size);
157d8e91e46SDimitry Andric }
158d8e91e46SDimitry Andric 
writeMapSize(uint32_t Size)159d8e91e46SDimitry Andric void Writer::writeMapSize(uint32_t Size) {
160d8e91e46SDimitry Andric   if (Size <= FixMax::Map) {
161d8e91e46SDimitry Andric     EW.write(static_cast<uint8_t>(FixBits::Map | Size));
162d8e91e46SDimitry Andric     return;
163d8e91e46SDimitry Andric   }
164d8e91e46SDimitry Andric 
165d8e91e46SDimitry Andric   if (Size <= UINT16_MAX) {
166d8e91e46SDimitry Andric     EW.write(FirstByte::Map16);
167d8e91e46SDimitry Andric     EW.write(static_cast<uint16_t>(Size));
168d8e91e46SDimitry Andric     return;
169d8e91e46SDimitry Andric   }
170d8e91e46SDimitry Andric 
171d8e91e46SDimitry Andric   EW.write(FirstByte::Map32);
172d8e91e46SDimitry Andric   EW.write(Size);
173d8e91e46SDimitry Andric }
174d8e91e46SDimitry Andric 
writeExt(int8_t Type,MemoryBufferRef Buffer)175d8e91e46SDimitry Andric void Writer::writeExt(int8_t Type, MemoryBufferRef Buffer) {
176d8e91e46SDimitry Andric   size_t Size = Buffer.getBufferSize();
177d8e91e46SDimitry Andric 
178d8e91e46SDimitry Andric   switch (Size) {
179d8e91e46SDimitry Andric   case FixLen::Ext1:
180d8e91e46SDimitry Andric     EW.write(FirstByte::FixExt1);
181d8e91e46SDimitry Andric     break;
182d8e91e46SDimitry Andric   case FixLen::Ext2:
183d8e91e46SDimitry Andric     EW.write(FirstByte::FixExt2);
184d8e91e46SDimitry Andric     break;
185d8e91e46SDimitry Andric   case FixLen::Ext4:
186d8e91e46SDimitry Andric     EW.write(FirstByte::FixExt4);
187d8e91e46SDimitry Andric     break;
188d8e91e46SDimitry Andric   case FixLen::Ext8:
189d8e91e46SDimitry Andric     EW.write(FirstByte::FixExt8);
190d8e91e46SDimitry Andric     break;
191d8e91e46SDimitry Andric   case FixLen::Ext16:
192d8e91e46SDimitry Andric     EW.write(FirstByte::FixExt16);
193d8e91e46SDimitry Andric     break;
194d8e91e46SDimitry Andric   default:
195d8e91e46SDimitry Andric     if (Size <= UINT8_MAX) {
196d8e91e46SDimitry Andric       EW.write(FirstByte::Ext8);
197d8e91e46SDimitry Andric       EW.write(static_cast<uint8_t>(Size));
198d8e91e46SDimitry Andric     } else if (Size <= UINT16_MAX) {
199d8e91e46SDimitry Andric       EW.write(FirstByte::Ext16);
200d8e91e46SDimitry Andric       EW.write(static_cast<uint16_t>(Size));
201d8e91e46SDimitry Andric     } else {
202d8e91e46SDimitry Andric       assert(Size <= UINT32_MAX && "Ext size too large to be encoded");
203d8e91e46SDimitry Andric       EW.write(FirstByte::Ext32);
204d8e91e46SDimitry Andric       EW.write(static_cast<uint32_t>(Size));
205d8e91e46SDimitry Andric     }
206d8e91e46SDimitry Andric   }
207d8e91e46SDimitry Andric 
208d8e91e46SDimitry Andric   EW.write(Type);
209d8e91e46SDimitry Andric   EW.OS.write(Buffer.getBufferStart(), Size);
210d8e91e46SDimitry Andric }
211