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