123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- //===- MsgPackTypes.cpp - MsgPack Types -------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- /// \file
- /// Implementation of types representing MessagePack "documents".
- //
- //===----------------------------------------------------------------------===//
- #include "llvm/BinaryFormat/MsgPackTypes.h"
- #include "llvm/Support/Error.h"
- using namespace llvm;
- using namespace msgpack;
- namespace llvm {
- namespace msgpack {
- void ScalarNode::anchor() {}
- void ArrayNode::anchor() {}
- void MapNode::anchor() {}
- }
- }
- Expected<OptNodePtr> Node::readArray(Reader &MPReader, size_t Length) {
- auto A = std::make_shared<ArrayNode>();
- for (size_t I = 0; I < Length; ++I) {
- auto OptNodeOrErr = Node::read(MPReader);
- if (auto Err = OptNodeOrErr.takeError())
- return std::move(Err);
- if (!*OptNodeOrErr)
- return make_error<StringError>(
- "Insufficient array elements",
- std::make_error_code(std::errc::invalid_argument));
- A->push_back(std::move(**OptNodeOrErr));
- }
- return OptNodePtr(std::move(A));
- }
- Expected<OptNodePtr> Node::readMap(Reader &MPReader, size_t Length) {
- auto M = std::make_shared<MapNode>();
- for (size_t I = 0; I < Length; ++I) {
- auto OptKeyOrErr = Node::read(MPReader);
- if (auto Err = OptKeyOrErr.takeError())
- return std::move(Err);
- if (!*OptKeyOrErr)
- return make_error<StringError>(
- "Insufficient map elements",
- std::make_error_code(std::errc::invalid_argument));
- auto OptValOrErr = Node::read(MPReader);
- if (auto Err = OptValOrErr.takeError())
- return std::move(Err);
- if (!*OptValOrErr)
- return make_error<StringError>(
- "Insufficient map elements",
- std::make_error_code(std::errc::invalid_argument));
- auto *Key = dyn_cast<ScalarNode>((*OptKeyOrErr)->get());
- if (!Key)
- return make_error<StringError>(
- "Only string map keys are supported",
- std::make_error_code(std::errc::invalid_argument));
- if (Key->getScalarKind() != ScalarNode::SK_String)
- return make_error<StringError>(
- "Only string map keys are supported",
- std::make_error_code(std::errc::invalid_argument));
- M->try_emplace(Key->getString(), std::move(**OptValOrErr));
- }
- return OptNodePtr(std::move(M));
- }
- Expected<OptNodePtr> Node::read(Reader &MPReader) {
- Object Obj;
- auto ContinueOrErr = MPReader.read(Obj);
- if (auto Err = ContinueOrErr.takeError())
- return std::move(Err);
- if (!*ContinueOrErr)
- return None;
- switch (Obj.Kind) {
- case Type::Int:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.Int));
- case Type::UInt:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.UInt));
- case Type::Nil:
- return OptNodePtr(std::make_shared<ScalarNode>());
- case Type::Boolean:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.Bool));
- case Type::Float:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.Float));
- case Type::String:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
- case Type::Binary:
- return OptNodePtr(std::make_shared<ScalarNode>(Obj.Raw));
- case Type::Array:
- return Node::readArray(MPReader, Obj.Length);
- case Type::Map:
- return Node::readMap(MPReader, Obj.Length);
- case Type::Extension:
- return make_error<StringError>(
- "Extension types are not supported",
- std::make_error_code(std::errc::invalid_argument));
- }
- llvm_unreachable("msgpack::Type not handled");
- }
- void ScalarNode::destroy() {
- switch (SKind) {
- case SK_String:
- case SK_Binary:
- StringValue.~basic_string();
- break;
- default:
- // POD types do not require destruction
- break;
- }
- }
- ScalarNode::ScalarNode(int64_t IntValue)
- : Node(NK_Scalar), SKind(SK_Int), IntValue(IntValue) {}
- ScalarNode::ScalarNode(int32_t IntValue)
- : ScalarNode(static_cast<int64_t>(IntValue)) {}
- ScalarNode::ScalarNode(uint64_t UIntValue)
- : Node(NK_Scalar), SKind(SK_UInt), UIntValue(UIntValue) {}
- ScalarNode::ScalarNode(uint32_t IntValue)
- : ScalarNode(static_cast<uint64_t>(IntValue)) {}
- ScalarNode::ScalarNode() : Node(NK_Scalar), SKind(SK_Nil) {}
- ScalarNode::ScalarNode(bool BoolValue)
- : Node(NK_Scalar), SKind(SK_Boolean), BoolValue(BoolValue) {}
- ScalarNode::ScalarNode(double FloatValue)
- : Node(NK_Scalar), SKind(SK_Float), BoolValue(FloatValue) {}
- ScalarNode::ScalarNode(StringRef StringValue)
- : Node(NK_Scalar), SKind(SK_String) {
- new (&this->StringValue) std::string(StringValue);
- }
- ScalarNode::ScalarNode(const char *StringValue)
- : ScalarNode(StringRef(StringValue)) {}
- ScalarNode::ScalarNode(std::string &&StringValue)
- : Node(NK_Scalar), SKind(SK_String) {
- new (&this->StringValue) std::string(StringValue);
- }
- ScalarNode::ScalarNode(MemoryBufferRef BinaryValue)
- : Node(NK_Scalar), SKind(SK_Binary) {
- new (&StringValue) std::string(BinaryValue.getBuffer());
- }
- ScalarNode::~ScalarNode() { destroy(); }
- ScalarNode &ScalarNode::operator=(ScalarNode &&RHS) {
- destroy();
- switch (SKind = RHS.SKind) {
- case SK_Int:
- IntValue = RHS.IntValue;
- break;
- case SK_UInt:
- UIntValue = RHS.UIntValue;
- break;
- case SK_Boolean:
- BoolValue = RHS.BoolValue;
- break;
- case SK_Float:
- FloatValue = RHS.FloatValue;
- break;
- case SK_String:
- case SK_Binary:
- new (&StringValue) std::string(std::move(RHS.StringValue));
- break;
- case SK_Nil:
- // pass
- break;
- }
- return *this;
- }
- StringRef ScalarNode::inputYAML(StringRef ScalarStr) {
- switch (SKind) {
- case SK_Int:
- return yaml::ScalarTraits<int64_t>::input(ScalarStr, nullptr, IntValue);
- case SK_UInt:
- return yaml::ScalarTraits<uint64_t>::input(ScalarStr, nullptr, UIntValue);
- case SK_Nil:
- return StringRef();
- case SK_Boolean:
- return yaml::ScalarTraits<bool>::input(ScalarStr, nullptr, BoolValue);
- case SK_Float:
- return yaml::ScalarTraits<double>::input(ScalarStr, nullptr, FloatValue);
- case SK_Binary:
- case SK_String:
- return yaml::ScalarTraits<std::string>::input(ScalarStr, nullptr,
- StringValue);
- }
- llvm_unreachable("unrecognized ScalarKind");
- }
- void ScalarNode::outputYAML(raw_ostream &OS) const {
- switch (SKind) {
- case SK_Int:
- yaml::ScalarTraits<int64_t>::output(IntValue, nullptr, OS);
- break;
- case SK_UInt:
- yaml::ScalarTraits<uint64_t>::output(UIntValue, nullptr, OS);
- break;
- case SK_Nil:
- yaml::ScalarTraits<StringRef>::output("", nullptr, OS);
- break;
- case SK_Boolean:
- yaml::ScalarTraits<bool>::output(BoolValue, nullptr, OS);
- break;
- case SK_Float:
- yaml::ScalarTraits<double>::output(FloatValue, nullptr, OS);
- break;
- case SK_Binary:
- case SK_String:
- yaml::ScalarTraits<std::string>::output(StringValue, nullptr, OS);
- break;
- }
- }
- yaml::QuotingType ScalarNode::mustQuoteYAML(StringRef ScalarStr) const {
- switch (SKind) {
- case SK_Int:
- return yaml::ScalarTraits<int64_t>::mustQuote(ScalarStr);
- case SK_UInt:
- return yaml::ScalarTraits<uint64_t>::mustQuote(ScalarStr);
- case SK_Nil:
- return yaml::ScalarTraits<StringRef>::mustQuote(ScalarStr);
- case SK_Boolean:
- return yaml::ScalarTraits<bool>::mustQuote(ScalarStr);
- case SK_Float:
- return yaml::ScalarTraits<double>::mustQuote(ScalarStr);
- case SK_Binary:
- case SK_String:
- return yaml::ScalarTraits<std::string>::mustQuote(ScalarStr);
- }
- llvm_unreachable("unrecognized ScalarKind");
- }
- const char *ScalarNode::IntTag = "!int";
- const char *ScalarNode::NilTag = "!nil";
- const char *ScalarNode::BooleanTag = "!bool";
- const char *ScalarNode::FloatTag = "!float";
- const char *ScalarNode::StringTag = "!str";
- const char *ScalarNode::BinaryTag = "!bin";
- StringRef ScalarNode::getYAMLTag() const {
- switch (SKind) {
- case SK_Int:
- return IntTag;
- case SK_UInt:
- return IntTag;
- case SK_Nil:
- return NilTag;
- case SK_Boolean:
- return BooleanTag;
- case SK_Float:
- return FloatTag;
- case SK_String:
- return StringTag;
- case SK_Binary:
- return BinaryTag;
- }
- llvm_unreachable("unrecognized ScalarKind");
- }
- void ScalarNode::write(Writer &MPWriter) {
- switch (SKind) {
- case SK_Int:
- MPWriter.write(IntValue);
- break;
- case SK_UInt:
- MPWriter.write(UIntValue);
- break;
- case SK_Nil:
- MPWriter.writeNil();
- break;
- case SK_Boolean:
- MPWriter.write(BoolValue);
- break;
- case SK_Float:
- MPWriter.write(FloatValue);
- break;
- case SK_String:
- MPWriter.write(StringValue);
- break;
- case SK_Binary:
- MPWriter.write(MemoryBufferRef(StringValue, ""));
- break;
- }
- }
|