LLVM  9.0.0svn
MsgPackTypes.cpp
Go to the documentation of this file.
1 //===- MsgPackTypes.cpp - MsgPack Types -------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Implementation of types representing MessagePack "documents".
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/Support/Error.h"
16 
17 using namespace llvm;
18 using namespace msgpack;
19 
20 namespace llvm {
21 namespace msgpack {
22 void ScalarNode::anchor() {}
23 void ArrayNode::anchor() {}
24 void MapNode::anchor() {}
25 }
26 }
27 
28 Expected<OptNodePtr> Node::readArray(Reader &MPReader, size_t Length) {
29  auto A = std::make_shared<ArrayNode>();
30  for (size_t I = 0; I < Length; ++I) {
31  auto OptNodeOrErr = Node::read(MPReader);
32  if (auto Err = OptNodeOrErr.takeError())
33  return std::move(Err);
34  if (!*OptNodeOrErr)
35  return make_error<StringError>(
36  "Insufficient array elements",
37  std::make_error_code(std::errc::invalid_argument));
38  A->push_back(std::move(**OptNodeOrErr));
39  }
40  return OptNodePtr(std::move(A));
41 }
42 
43 Expected<OptNodePtr> Node::readMap(Reader &MPReader, size_t Length) {
44  auto M = std::make_shared<MapNode>();
45  for (size_t I = 0; I < Length; ++I) {
46  auto OptKeyOrErr = Node::read(MPReader);
47  if (auto Err = OptKeyOrErr.takeError())
48  return std::move(Err);
49  if (!*OptKeyOrErr)
50  return make_error<StringError>(
51  "Insufficient map elements",
52  std::make_error_code(std::errc::invalid_argument));
53  auto OptValOrErr = Node::read(MPReader);
54  if (auto Err = OptValOrErr.takeError())
55  return std::move(Err);
56  if (!*OptValOrErr)
57  return make_error<StringError>(
58  "Insufficient map elements",
59  std::make_error_code(std::errc::invalid_argument));
60  auto *Key = dyn_cast<ScalarNode>((*OptKeyOrErr)->get());
61  if (!Key)
62  return make_error<StringError>(
63  "Only string map keys are supported",
64  std::make_error_code(std::errc::invalid_argument));
65  if (Key->getScalarKind() != ScalarNode::SK_String)
66  return make_error<StringError>(
67  "Only string map keys are supported",
68  std::make_error_code(std::errc::invalid_argument));
69  M->try_emplace(Key->getString(), std::move(**OptValOrErr));
70  }
71  return OptNodePtr(std::move(M));
72 }
73 
75  Object Obj;
76 
77  auto ContinueOrErr = MPReader.read(Obj);
78  if (auto Err = ContinueOrErr.takeError())
79  return std::move(Err);
80  if (!*ContinueOrErr)
81  return None;
82 
83  switch (Obj.Kind) {
84  case Type::Int:
85  return OptNodePtr(std::make_shared<ScalarNode>(Obj.Int));
86  case Type::UInt:
87  return OptNodePtr(std::make_shared<ScalarNode>(Obj.UInt));
88  case Type::Nil:
89  return OptNodePtr(std::make_shared<ScalarNode>());
90  case Type::Boolean:
91  return OptNodePtr(std::make_shared<ScalarNode>(Obj.Bool));
92  case Type::Float:
93  return OptNodePtr(std::make_shared<ScalarNode>(Obj.Float));
94  case Type::String:
95  return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
96  case Type::Binary:
97  return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
98  case Type::Array:
99  return Node::readArray(MPReader, Obj.Length);
100  case Type::Map:
101  return Node::readMap(MPReader, Obj.Length);
102  case Type::Extension:
103  return make_error<StringError>(
104  "Extension types are not supported",
105  std::make_error_code(std::errc::invalid_argument));
106  }
107  llvm_unreachable("msgpack::Type not handled");
108 }
109 
110 void ScalarNode::destroy() {
111  switch (SKind) {
112  case SK_String:
113  case SK_Binary:
114  StringValue.~basic_string();
115  break;
116  default:
117  // POD types do not require destruction
118  break;
119  }
120 }
121 
122 ScalarNode::ScalarNode(int64_t IntValue)
123  : Node(NK_Scalar), SKind(SK_Int), IntValue(IntValue) {}
124 
126  : ScalarNode(static_cast<int64_t>(IntValue)) {}
127 
129  : Node(NK_Scalar), SKind(SK_UInt), UIntValue(UIntValue) {}
130 
132  : ScalarNode(static_cast<uint64_t>(IntValue)) {}
133 
135 
137  : Node(NK_Scalar), SKind(SK_Boolean), BoolValue(BoolValue) {}
138 
140  : Node(NK_Scalar), SKind(SK_Float), BoolValue(FloatValue) {}
141 
143  : Node(NK_Scalar), SKind(SK_String) {
144  new (&this->StringValue) std::string(StringValue);
145 }
146 
148  : ScalarNode(StringRef(StringValue)) {}
149 
151  : Node(NK_Scalar), SKind(SK_String) {
152  new (&this->StringValue) std::string(StringValue);
153 }
154 
156  : Node(NK_Scalar), SKind(SK_Binary) {
157  new (&StringValue) std::string(BinaryValue.getBuffer());
158 }
159 
160 ScalarNode::~ScalarNode() { destroy(); }
161 
163  destroy();
164  switch (SKind = RHS.SKind) {
165  case SK_Int:
166  IntValue = RHS.IntValue;
167  break;
168  case SK_UInt:
169  UIntValue = RHS.UIntValue;
170  break;
171  case SK_Boolean:
172  BoolValue = RHS.BoolValue;
173  break;
174  case SK_Float:
175  FloatValue = RHS.FloatValue;
176  break;
177  case SK_String:
178  case SK_Binary:
179  new (&StringValue) std::string(std::move(RHS.StringValue));
180  break;
181  case SK_Nil:
182  // pass
183  break;
184  }
185  return *this;
186 }
187 
189  switch (SKind) {
190  case SK_Int:
191  return yaml::ScalarTraits<int64_t>::input(ScalarStr, nullptr, IntValue);
192  case SK_UInt:
193  return yaml::ScalarTraits<uint64_t>::input(ScalarStr, nullptr, UIntValue);
194  case SK_Nil:
195  return StringRef();
196  case SK_Boolean:
197  return yaml::ScalarTraits<bool>::input(ScalarStr, nullptr, BoolValue);
198  case SK_Float:
199  return yaml::ScalarTraits<double>::input(ScalarStr, nullptr, FloatValue);
200  case SK_Binary:
201  case SK_String:
202  return yaml::ScalarTraits<std::string>::input(ScalarStr, nullptr,
203  StringValue);
204  }
205  llvm_unreachable("unrecognized ScalarKind");
206 }
207 
209  switch (SKind) {
210  case SK_Int:
211  yaml::ScalarTraits<int64_t>::output(IntValue, nullptr, OS);
212  break;
213  case SK_UInt:
214  yaml::ScalarTraits<uint64_t>::output(UIntValue, nullptr, OS);
215  break;
216  case SK_Nil:
217  yaml::ScalarTraits<StringRef>::output("", nullptr, OS);
218  break;
219  case SK_Boolean:
220  yaml::ScalarTraits<bool>::output(BoolValue, nullptr, OS);
221  break;
222  case SK_Float:
223  yaml::ScalarTraits<double>::output(FloatValue, nullptr, OS);
224  break;
225  case SK_Binary:
226  case SK_String:
227  yaml::ScalarTraits<std::string>::output(StringValue, nullptr, OS);
228  break;
229  }
230 }
231 
232 yaml::QuotingType ScalarNode::mustQuoteYAML(StringRef ScalarStr) const {
233  switch (SKind) {
234  case SK_Int:
235  return yaml::ScalarTraits<int64_t>::mustQuote(ScalarStr);
236  case SK_UInt:
237  return yaml::ScalarTraits<uint64_t>::mustQuote(ScalarStr);
238  case SK_Nil:
239  return yaml::ScalarTraits<StringRef>::mustQuote(ScalarStr);
240  case SK_Boolean:
241  return yaml::ScalarTraits<bool>::mustQuote(ScalarStr);
242  case SK_Float:
243  return yaml::ScalarTraits<double>::mustQuote(ScalarStr);
244  case SK_Binary:
245  case SK_String:
246  return yaml::ScalarTraits<std::string>::mustQuote(ScalarStr);
247  }
248  llvm_unreachable("unrecognized ScalarKind");
249 }
250 
251 const char *ScalarNode::IntTag = "!int";
252 const char *ScalarNode::NilTag = "!nil";
253 const char *ScalarNode::BooleanTag = "!bool";
254 const char *ScalarNode::FloatTag = "!float";
255 const char *ScalarNode::StringTag = "!str";
256 const char *ScalarNode::BinaryTag = "!bin";
257 
259  switch (SKind) {
260  case SK_Int:
261  return IntTag;
262  case SK_UInt:
263  return IntTag;
264  case SK_Nil:
265  return NilTag;
266  case SK_Boolean:
267  return BooleanTag;
268  case SK_Float:
269  return FloatTag;
270  case SK_String:
271  return StringTag;
272  case SK_Binary:
273  return BinaryTag;
274  }
275  llvm_unreachable("unrecognized ScalarKind");
276 }
277 
278 void ScalarNode::write(Writer &MPWriter) {
279  switch (SKind) {
280  case SK_Int:
281  MPWriter.write(IntValue);
282  break;
283  case SK_UInt:
284  MPWriter.write(UIntValue);
285  break;
286  case SK_Nil:
287  MPWriter.writeNil();
288  break;
289  case SK_Boolean:
290  MPWriter.write(BoolValue);
291  break;
292  case SK_Float:
293  MPWriter.write(FloatValue);
294  break;
295  case SK_String:
296  MPWriter.write(StringValue);
297  break;
298  case SK_Binary:
299  MPWriter.write(MemoryBufferRef(StringValue, ""));
300  break;
301  }
302 }
const NoneType None
Definition: None.h:23
static const char * FloatTag
Definition: MsgPackTypes.h:240
Expected< bool > read(Object &Obj)
Read one object from the input buffer, advancing past it.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
StringRef getYAMLTag() const
Get the YAML tag for the current ScalarKind.
yaml::QuotingType mustQuoteYAML(StringRef ScalarStr) const
Determine which YAML quoting type the current value would need when output.
StringRef getBuffer() const
Definition: MemoryBuffer.h:272
Writes MessagePack objects to an output stream, one at a time.
Definition: MsgPackWriter.h:40
std::error_code make_error_code(BitcodeError E)
Tagged union holding either a T or a Error.
Definition: CachePruning.h:22
ScalarNode()
Construct a Nil ScalarNode.
static const char * BinaryTag
Definition: MsgPackTypes.h:242
void outputYAML(raw_ostream &OS) const
Output a YAML scalar of the current ScalarKind into OS.
Key
PAL metadata keys.
static const char * IntTag
Definition: MsgPackTypes.h:237
static Expected< OptNodePtr > read(Reader &MPReader)
Read from a MessagePack reader MPReader, returning an error if one is encountered, or None if MPReader is at the end of stream, or some Node pointer if some type is read.
MessagePack object, represented as a tagged union of C++ types.
Definition: MsgPackReader.h:75
This is a data structure for representing MessagePack "documents", with methods to go to and from Mes...
static const char * BooleanTag
Definition: MsgPackTypes.h:239
void writeNil()
Write a Nil to the output stream.
Reads MessagePack objects from memory, one at a time.
Definition: MsgPackReader.h:98
Abstract base-class which can be any MessagePack type.
Definition: MsgPackTypes.h:38
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
double Float
Value for Type::Float.
Definition: MsgPackReader.h:85
void write(Writer &MPWriter) override
Write to a MessagePack writer MPWriter.
static const char * NilTag
Definition: MsgPackTypes.h:238
void write(bool b)
Write a Boolean to the output stream.
StringRef Raw
Value for Type::String and Type::Binary.
Definition: MsgPackReader.h:87
ScalarNode & operator=(const ScalarNode &RHS)=delete
#define I(x, y, z)
Definition: MD5.cpp:58
int64_t Int
Value for Type::Int.
Definition: MsgPackReader.h:79
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:322
bool Bool
Value for Type::Boolean.
Definition: MsgPackReader.h:83
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
A MessagePack scalar.
Definition: MsgPackTypes.h:71
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
uint64_t UInt
Value for Type::Uint.
Definition: MsgPackReader.h:81
Optional< NodePtr > OptNodePtr
Short-hand for an Optional Node pointer.
Definition: MsgPackTypes.h:35
size_t Length
Value for Type::Array and Type::Map.
Definition: MsgPackReader.h:89
static const char * StringTag
Definition: MsgPackTypes.h:241
StringRef inputYAML(StringRef ScalarStr)
Parse a YAML scalar of the current ScalarKind from ScalarStr.