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