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