1 //===- MsgPackTypes.cpp - MsgPack Types -------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// Implementation of types representing MessagePack "documents".
12 //===----------------------------------------------------------------------===//
14 #include "llvm/BinaryFormat/MsgPackTypes.h"
15 #include "llvm/Support/Error.h"
18 using namespace msgpack
;
22 void ScalarNode::anchor() {}
23 void ArrayNode::anchor() {}
24 void MapNode::anchor() {}
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
);
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
));
40 return OptNodePtr(std::move(A
));
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
);
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
);
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());
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
));
71 return OptNodePtr(std::move(M
));
74 Expected
<OptNodePtr
> Node::read(Reader
&MPReader
) {
77 auto ContinueOrErr
= MPReader
.read(Obj
);
78 if (auto Err
= ContinueOrErr
.takeError())
79 return std::move(Err
);
85 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.Int
));
87 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.UInt
));
89 return OptNodePtr(std::make_shared
<ScalarNode
>());
91 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.Bool
));
93 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.Float
));
95 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.Raw
));
97 return OptNodePtr(std::make_shared
<ScalarNode
>(Obj
.Raw
));
99 return Node::readArray(MPReader
, Obj
.Length
);
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
));
107 llvm_unreachable("msgpack::Type not handled");
110 void ScalarNode::destroy() {
114 StringValue
.~basic_string();
117 // POD types do not require destruction
122 ScalarNode::ScalarNode(int64_t IntValue
)
123 : Node(NK_Scalar
), SKind(SK_Int
), IntValue(IntValue
) {}
125 ScalarNode::ScalarNode(int32_t IntValue
)
126 : ScalarNode(static_cast<int64_t>(IntValue
)) {}
128 ScalarNode::ScalarNode(uint64_t UIntValue
)
129 : Node(NK_Scalar
), SKind(SK_UInt
), UIntValue(UIntValue
) {}
131 ScalarNode::ScalarNode(uint32_t IntValue
)
132 : ScalarNode(static_cast<uint64_t>(IntValue
)) {}
134 ScalarNode::ScalarNode() : Node(NK_Scalar
), SKind(SK_Nil
) {}
136 ScalarNode::ScalarNode(bool BoolValue
)
137 : Node(NK_Scalar
), SKind(SK_Boolean
), BoolValue(BoolValue
) {}
139 ScalarNode::ScalarNode(double FloatValue
)
140 : Node(NK_Scalar
), SKind(SK_Float
), BoolValue(FloatValue
) {}
142 ScalarNode::ScalarNode(StringRef StringValue
)
143 : Node(NK_Scalar
), SKind(SK_String
) {
144 new (&this->StringValue
) std::string(StringValue
);
147 ScalarNode::ScalarNode(const char *StringValue
)
148 : ScalarNode(StringRef(StringValue
)) {}
150 ScalarNode::ScalarNode(std::string
&&StringValue
)
151 : Node(NK_Scalar
), SKind(SK_String
) {
152 new (&this->StringValue
) std::string(StringValue
);
155 ScalarNode::ScalarNode(MemoryBufferRef BinaryValue
)
156 : Node(NK_Scalar
), SKind(SK_Binary
) {
157 new (&StringValue
) std::string(BinaryValue
.getBuffer());
160 ScalarNode::~ScalarNode() { destroy(); }
162 ScalarNode
&ScalarNode::operator=(ScalarNode
&&RHS
) {
164 switch (SKind
= RHS
.SKind
) {
166 IntValue
= RHS
.IntValue
;
169 UIntValue
= RHS
.UIntValue
;
172 BoolValue
= RHS
.BoolValue
;
175 FloatValue
= RHS
.FloatValue
;
179 new (&StringValue
) std::string(std::move(RHS
.StringValue
));
188 StringRef
ScalarNode::inputYAML(StringRef ScalarStr
) {
191 return yaml::ScalarTraits
<int64_t>::input(ScalarStr
, nullptr, IntValue
);
193 return yaml::ScalarTraits
<uint64_t>::input(ScalarStr
, nullptr, UIntValue
);
197 return yaml::ScalarTraits
<bool>::input(ScalarStr
, nullptr, BoolValue
);
199 return yaml::ScalarTraits
<double>::input(ScalarStr
, nullptr, FloatValue
);
202 return yaml::ScalarTraits
<std::string
>::input(ScalarStr
, nullptr,
205 llvm_unreachable("unrecognized ScalarKind");
208 void ScalarNode::outputYAML(raw_ostream
&OS
) const {
211 yaml::ScalarTraits
<int64_t>::output(IntValue
, nullptr, OS
);
214 yaml::ScalarTraits
<uint64_t>::output(UIntValue
, nullptr, OS
);
217 yaml::ScalarTraits
<StringRef
>::output("", nullptr, OS
);
220 yaml::ScalarTraits
<bool>::output(BoolValue
, nullptr, OS
);
223 yaml::ScalarTraits
<double>::output(FloatValue
, nullptr, OS
);
227 yaml::ScalarTraits
<std::string
>::output(StringValue
, nullptr, OS
);
232 yaml::QuotingType
ScalarNode::mustQuoteYAML(StringRef ScalarStr
) const {
235 return yaml::ScalarTraits
<int64_t>::mustQuote(ScalarStr
);
237 return yaml::ScalarTraits
<uint64_t>::mustQuote(ScalarStr
);
239 return yaml::ScalarTraits
<StringRef
>::mustQuote(ScalarStr
);
241 return yaml::ScalarTraits
<bool>::mustQuote(ScalarStr
);
243 return yaml::ScalarTraits
<double>::mustQuote(ScalarStr
);
246 return yaml::ScalarTraits
<std::string
>::mustQuote(ScalarStr
);
248 llvm_unreachable("unrecognized ScalarKind");
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";
258 StringRef
ScalarNode::getYAMLTag() const {
275 llvm_unreachable("unrecognized ScalarKind");
278 void ScalarNode::write(Writer
&MPWriter
) {
281 MPWriter
.write(IntValue
);
284 MPWriter
.write(UIntValue
);
290 MPWriter
.write(BoolValue
);
293 MPWriter
.write(FloatValue
);
296 MPWriter
.write(StringValue
);
299 MPWriter
.write(MemoryBufferRef(StringValue
, ""));