1 //===- MsgPackTypes.cpp - MsgPack Types -------------------------*- 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 /// Implementation of types representing MessagePack "documents".
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/BinaryFormat/MsgPackTypes.h"
16 #include "llvm/Support/Error.h"
17
18 using namespace llvm;
19 using namespace msgpack;
20
21 namespace llvm {
22 namespace msgpack {
anchor()23 void ScalarNode::anchor() {}
anchor()24 void ArrayNode::anchor() {}
anchor()25 void MapNode::anchor() {}
26 }
27 }
28
readArray(Reader & MPReader,size_t Length)29 Expected<OptNodePtr> Node::readArray(Reader &MPReader, size_t Length) {
30 auto A = std::make_shared<ArrayNode>();
31 for (size_t I = 0; I < Length; ++I) {
32 auto OptNodeOrErr = Node::read(MPReader);
33 if (auto Err = OptNodeOrErr.takeError())
34 return std::move(Err);
35 if (!*OptNodeOrErr)
36 return make_error<StringError>(
37 "Insufficient array elements",
38 std::make_error_code(std::errc::invalid_argument));
39 A->push_back(std::move(**OptNodeOrErr));
40 }
41 return OptNodePtr(std::move(A));
42 }
43
readMap(Reader & MPReader,size_t Length)44 Expected<OptNodePtr> Node::readMap(Reader &MPReader, size_t Length) {
45 auto M = std::make_shared<MapNode>();
46 for (size_t I = 0; I < Length; ++I) {
47 auto OptKeyOrErr = Node::read(MPReader);
48 if (auto Err = OptKeyOrErr.takeError())
49 return std::move(Err);
50 if (!*OptKeyOrErr)
51 return make_error<StringError>(
52 "Insufficient map elements",
53 std::make_error_code(std::errc::invalid_argument));
54 auto OptValOrErr = Node::read(MPReader);
55 if (auto Err = OptValOrErr.takeError())
56 return std::move(Err);
57 if (!*OptValOrErr)
58 return make_error<StringError>(
59 "Insufficient map elements",
60 std::make_error_code(std::errc::invalid_argument));
61 auto *Key = dyn_cast<ScalarNode>((*OptKeyOrErr)->get());
62 if (!Key)
63 return make_error<StringError>(
64 "Only string map keys are supported",
65 std::make_error_code(std::errc::invalid_argument));
66 if (Key->getScalarKind() != ScalarNode::SK_String)
67 return make_error<StringError>(
68 "Only string map keys are supported",
69 std::make_error_code(std::errc::invalid_argument));
70 M->try_emplace(Key->getString(), std::move(**OptValOrErr));
71 }
72 return OptNodePtr(std::move(M));
73 }
74
read(Reader & MPReader)75 Expected<OptNodePtr> Node::read(Reader &MPReader) {
76 Object Obj;
77
78 auto ContinueOrErr = MPReader.read(Obj);
79 if (auto Err = ContinueOrErr.takeError())
80 return std::move(Err);
81 if (!*ContinueOrErr)
82 return None;
83
84 switch (Obj.Kind) {
85 case Type::Int:
86 return OptNodePtr(std::make_shared<ScalarNode>(Obj.Int));
87 case Type::UInt:
88 return OptNodePtr(std::make_shared<ScalarNode>(Obj.UInt));
89 case Type::Nil:
90 return OptNodePtr(std::make_shared<ScalarNode>());
91 case Type::Boolean:
92 return OptNodePtr(std::make_shared<ScalarNode>(Obj.Bool));
93 case Type::Float:
94 return OptNodePtr(std::make_shared<ScalarNode>(Obj.Float));
95 case Type::String:
96 return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
97 case Type::Binary:
98 return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
99 case Type::Array:
100 return Node::readArray(MPReader, Obj.Length);
101 case Type::Map:
102 return Node::readMap(MPReader, Obj.Length);
103 case Type::Extension:
104 return make_error<StringError>(
105 "Extension types are not supported",
106 std::make_error_code(std::errc::invalid_argument));
107 }
108 llvm_unreachable("msgpack::Type not handled");
109 }
110
destroy()111 void ScalarNode::destroy() {
112 switch (SKind) {
113 case SK_String:
114 case SK_Binary:
115 StringValue.~basic_string();
116 break;
117 default:
118 // POD types do not require destruction
119 break;
120 }
121 }
122
ScalarNode(int64_t IntValue)123 ScalarNode::ScalarNode(int64_t IntValue)
124 : Node(NK_Scalar), SKind(SK_Int), IntValue(IntValue) {}
125
ScalarNode(int32_t IntValue)126 ScalarNode::ScalarNode(int32_t IntValue)
127 : ScalarNode(static_cast<int64_t>(IntValue)) {}
128
ScalarNode(uint64_t UIntValue)129 ScalarNode::ScalarNode(uint64_t UIntValue)
130 : Node(NK_Scalar), SKind(SK_UInt), UIntValue(UIntValue) {}
131
ScalarNode(uint32_t IntValue)132 ScalarNode::ScalarNode(uint32_t IntValue)
133 : ScalarNode(static_cast<uint64_t>(IntValue)) {}
134
ScalarNode()135 ScalarNode::ScalarNode() : Node(NK_Scalar), SKind(SK_Nil) {}
136
ScalarNode(bool BoolValue)137 ScalarNode::ScalarNode(bool BoolValue)
138 : Node(NK_Scalar), SKind(SK_Boolean), BoolValue(BoolValue) {}
139
ScalarNode(double FloatValue)140 ScalarNode::ScalarNode(double FloatValue)
141 : Node(NK_Scalar), SKind(SK_Float), BoolValue(FloatValue) {}
142
ScalarNode(StringRef StringValue)143 ScalarNode::ScalarNode(StringRef StringValue)
144 : Node(NK_Scalar), SKind(SK_String) {
145 new (&this->StringValue) std::string(StringValue);
146 }
147
ScalarNode(const char * StringValue)148 ScalarNode::ScalarNode(const char *StringValue)
149 : ScalarNode(StringRef(StringValue)) {}
150
ScalarNode(std::string && StringValue)151 ScalarNode::ScalarNode(std::string &&StringValue)
152 : Node(NK_Scalar), SKind(SK_String) {
153 new (&this->StringValue) std::string(StringValue);
154 }
155
ScalarNode(MemoryBufferRef BinaryValue)156 ScalarNode::ScalarNode(MemoryBufferRef BinaryValue)
157 : Node(NK_Scalar), SKind(SK_Binary) {
158 new (&StringValue) std::string(BinaryValue.getBuffer());
159 }
160
~ScalarNode()161 ScalarNode::~ScalarNode() { destroy(); }
162
operator =(ScalarNode && RHS)163 ScalarNode &ScalarNode::operator=(ScalarNode &&RHS) {
164 destroy();
165 switch (SKind = RHS.SKind) {
166 case SK_Int:
167 IntValue = RHS.IntValue;
168 break;
169 case SK_UInt:
170 UIntValue = RHS.UIntValue;
171 break;
172 case SK_Boolean:
173 BoolValue = RHS.BoolValue;
174 break;
175 case SK_Float:
176 FloatValue = RHS.FloatValue;
177 break;
178 case SK_String:
179 case SK_Binary:
180 new (&StringValue) std::string(std::move(RHS.StringValue));
181 break;
182 case SK_Nil:
183 // pass
184 break;
185 }
186 return *this;
187 }
188
inputYAML(StringRef ScalarStr)189 StringRef ScalarNode::inputYAML(StringRef ScalarStr) {
190 switch (SKind) {
191 case SK_Int:
192 return yaml::ScalarTraits<int64_t>::input(ScalarStr, nullptr, IntValue);
193 case SK_UInt:
194 return yaml::ScalarTraits<uint64_t>::input(ScalarStr, nullptr, UIntValue);
195 case SK_Nil:
196 return StringRef();
197 case SK_Boolean:
198 return yaml::ScalarTraits<bool>::input(ScalarStr, nullptr, BoolValue);
199 case SK_Float:
200 return yaml::ScalarTraits<double>::input(ScalarStr, nullptr, FloatValue);
201 case SK_Binary:
202 case SK_String:
203 return yaml::ScalarTraits<std::string>::input(ScalarStr, nullptr,
204 StringValue);
205 }
206 llvm_unreachable("unrecognized ScalarKind");
207 }
208
outputYAML(raw_ostream & OS) const209 void ScalarNode::outputYAML(raw_ostream &OS) const {
210 switch (SKind) {
211 case SK_Int:
212 yaml::ScalarTraits<int64_t>::output(IntValue, nullptr, OS);
213 break;
214 case SK_UInt:
215 yaml::ScalarTraits<uint64_t>::output(UIntValue, nullptr, OS);
216 break;
217 case SK_Nil:
218 yaml::ScalarTraits<StringRef>::output("", nullptr, OS);
219 break;
220 case SK_Boolean:
221 yaml::ScalarTraits<bool>::output(BoolValue, nullptr, OS);
222 break;
223 case SK_Float:
224 yaml::ScalarTraits<double>::output(FloatValue, nullptr, OS);
225 break;
226 case SK_Binary:
227 case SK_String:
228 yaml::ScalarTraits<std::string>::output(StringValue, nullptr, OS);
229 break;
230 }
231 }
232
mustQuoteYAML(StringRef ScalarStr) const233 yaml::QuotingType ScalarNode::mustQuoteYAML(StringRef ScalarStr) const {
234 switch (SKind) {
235 case SK_Int:
236 return yaml::ScalarTraits<int64_t>::mustQuote(ScalarStr);
237 case SK_UInt:
238 return yaml::ScalarTraits<uint64_t>::mustQuote(ScalarStr);
239 case SK_Nil:
240 return yaml::ScalarTraits<StringRef>::mustQuote(ScalarStr);
241 case SK_Boolean:
242 return yaml::ScalarTraits<bool>::mustQuote(ScalarStr);
243 case SK_Float:
244 return yaml::ScalarTraits<double>::mustQuote(ScalarStr);
245 case SK_Binary:
246 case SK_String:
247 return yaml::ScalarTraits<std::string>::mustQuote(ScalarStr);
248 }
249 llvm_unreachable("unrecognized ScalarKind");
250 }
251
252 const char *ScalarNode::IntTag = "!int";
253 const char *ScalarNode::NilTag = "!nil";
254 const char *ScalarNode::BooleanTag = "!bool";
255 const char *ScalarNode::FloatTag = "!float";
256 const char *ScalarNode::StringTag = "!str";
257 const char *ScalarNode::BinaryTag = "!bin";
258
getYAMLTag() const259 StringRef ScalarNode::getYAMLTag() const {
260 switch (SKind) {
261 case SK_Int:
262 return IntTag;
263 case SK_UInt:
264 return IntTag;
265 case SK_Nil:
266 return NilTag;
267 case SK_Boolean:
268 return BooleanTag;
269 case SK_Float:
270 return FloatTag;
271 case SK_String:
272 return StringTag;
273 case SK_Binary:
274 return BinaryTag;
275 }
276 llvm_unreachable("unrecognized ScalarKind");
277 }
278
write(Writer & MPWriter)279 void ScalarNode::write(Writer &MPWriter) {
280 switch (SKind) {
281 case SK_Int:
282 MPWriter.write(IntValue);
283 break;
284 case SK_UInt:
285 MPWriter.write(UIntValue);
286 break;
287 case SK_Nil:
288 MPWriter.writeNil();
289 break;
290 case SK_Boolean:
291 MPWriter.write(BoolValue);
292 break;
293 case SK_Float:
294 MPWriter.write(FloatValue);
295 break;
296 case SK_String:
297 MPWriter.write(StringValue);
298 break;
299 case SK_Binary:
300 MPWriter.write(MemoryBufferRef(StringValue, ""));
301 break;
302 }
303 }
304