Index: include/llvm/BinaryFormat/MsgPackTypes.h =================================================================== --- include/llvm/BinaryFormat/MsgPackTypes.h +++ /dev/null @@ -1,371 +0,0 @@ -//===- MsgPackTypes.h - 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 -/// This is a data structure for representing MessagePack "documents", with -/// methods to go to and from MessagePack. The types also specialize YAMLIO -/// traits in order to go to and from YAML. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ADT/Optional.h" -#include "llvm/BinaryFormat/MsgPackReader.h" -#include "llvm/BinaryFormat/MsgPackWriter.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/YAMLTraits.h" -#include - -#ifndef LLVM_BINARYFORMAT_MSGPACKTYPES_H -#define LLVM_BINARYFORMAT_MSGPACKTYPES_H - -namespace llvm { -namespace msgpack { - -class Node; - -/// Short-hand for a Node pointer. -using NodePtr = std::shared_ptr; - -/// Short-hand for an Optional Node pointer. -using OptNodePtr = Optional; - -/// Abstract base-class which can be any MessagePack type. -class Node { -public: - enum NodeKind { - NK_Scalar, - NK_Array, - NK_Map, - }; - -private: - virtual void anchor() = 0; - const NodeKind Kind; - - static Expected readArray(Reader &MPReader, size_t Length); - static Expected readMap(Reader &MPReader, size_t Length); - -public: - NodeKind getKind() const { return Kind; } - - /// Construct a Node. Used by derived classes to track kind information. - Node(NodeKind Kind) : Kind(Kind) {} - - virtual ~Node() = default; - - /// Read from a MessagePack reader \p MPReader, returning an error if one is - /// encountered, or None if \p MPReader is at the end of stream, or some Node - /// pointer if some type is read. - static Expected read(Reader &MPReader); - - /// Write to a MessagePack writer \p MPWriter. - virtual void write(Writer &MPWriter) = 0; -}; - -/// A MessagePack scalar. -class ScalarNode : public Node { -public: - enum ScalarKind { - SK_Int, - SK_UInt, - SK_Nil, - SK_Boolean, - SK_Float, - SK_String, - SK_Binary, - }; - -private: - void anchor() override; - - void destroy(); - - ScalarKind SKind; - - union { - int64_t IntValue; - uint64_t UIntValue; - bool BoolValue; - double FloatValue; - std::string StringValue; - }; - -public: - /// Construct an Int ScalarNode. - ScalarNode(int64_t IntValue); - /// Construct an Int ScalarNode. - ScalarNode(int32_t IntValue); - /// Construct an UInt ScalarNode. - ScalarNode(uint64_t UIntValue); - /// Construct an UInt ScalarNode. - ScalarNode(uint32_t UIntValue); - /// Construct a Nil ScalarNode. - ScalarNode(); - /// Construct a Boolean ScalarNode. - ScalarNode(bool BoolValue); - /// Construct a Float ScalarNode. - ScalarNode(double FloatValue); - /// Construct a String ScalarNode. - ScalarNode(StringRef StringValue); - /// Construct a String ScalarNode. - ScalarNode(const char *StringValue); - /// Construct a String ScalarNode. - ScalarNode(std::string &&StringValue); - /// Construct a Binary ScalarNode. - ScalarNode(MemoryBufferRef BinaryValue); - - ~ScalarNode(); - - ScalarNode &operator=(const ScalarNode &RHS) = delete; - /// A ScalarNode can only be move assigned. - ScalarNode &operator=(ScalarNode &&RHS); - - /// Change the kind of this ScalarNode, zero initializing it to the new type. - void setScalarKind(ScalarKind SKind) { - switch (SKind) { - case SK_Int: - *this = int64_t(0); - break; - case SK_UInt: - *this = uint64_t(0); - break; - case SK_Boolean: - *this = false; - break; - case SK_Float: - *this = 0.0; - break; - case SK_String: - *this = StringRef(); - break; - case SK_Binary: - *this = MemoryBufferRef("", ""); - break; - case SK_Nil: - *this = ScalarNode(); - break; - } - } - - /// Get the current kind of ScalarNode. - ScalarKind getScalarKind() { return SKind; } - - /// Get the value of an Int scalar. - /// - /// \warning Assumes getScalarKind() == SK_Int - int64_t getInt() { - assert(SKind == SK_Int); - return IntValue; - } - - /// Get the value of a UInt scalar. - /// - /// \warning Assumes getScalarKind() == SK_UInt - uint64_t getUInt() { - assert(SKind == SK_UInt); - return UIntValue; - } - - /// Get the value of an Boolean scalar. - /// - /// \warning Assumes getScalarKind() == SK_Boolean - bool getBool() { - assert(SKind == SK_Boolean); - return BoolValue; - } - - /// Get the value of an Float scalar. - /// - /// \warning Assumes getScalarKind() == SK_Float - double getFloat() { - assert(SKind == SK_Float); - return FloatValue; - } - - /// Get the value of a String scalar. - /// - /// \warning Assumes getScalarKind() == SK_String - StringRef getString() { - assert(SKind == SK_String); - return StringValue; - } - - /// Get the value of a Binary scalar. - /// - /// \warning Assumes getScalarKind() == SK_Binary - StringRef getBinary() { - assert(SKind == SK_Binary); - return StringValue; - } - - static bool classof(const Node *N) { return N->getKind() == NK_Scalar; } - - void write(Writer &MPWriter) override; - - /// Parse a YAML scalar of the current ScalarKind from \p ScalarStr. - /// - /// \returns An empty string on success, otherwise an error message. - StringRef inputYAML(StringRef ScalarStr); - - /// Output a YAML scalar of the current ScalarKind into \p OS. - void outputYAML(raw_ostream &OS) const; - - /// Determine which YAML quoting type the current value would need when - /// output. - yaml::QuotingType mustQuoteYAML(StringRef ScalarStr) const; - - /// Get the YAML tag for the current ScalarKind. - StringRef getYAMLTag() const; - - /// Flag which affects how the type handles YAML tags when reading and - /// writing. - /// - /// When false, tags are used when reading and writing. When reading, the tag - /// is used to decide the ScalarKind before parsing. When writing, the tag is - /// output along with the value. - /// - /// When true, tags are ignored when reading and writing. When reading, the - /// ScalarKind is always assumed to be String. When writing, the tag is not - /// output. - bool IgnoreTag = false; - - static const char *IntTag; - static const char *NilTag; - static const char *BooleanTag; - static const char *FloatTag; - static const char *StringTag; - static const char *BinaryTag; -}; - -class ArrayNode : public Node, public std::vector { - void anchor() override; - -public: - ArrayNode() : Node(NK_Array) {} - static bool classof(const Node *N) { return N->getKind() == NK_Array; } - - void write(Writer &MPWriter) override { - MPWriter.writeArraySize(this->size()); - for (auto &N : *this) - N->write(MPWriter); - } -}; - -class MapNode : public Node, public StringMap { - void anchor() override; - -public: - MapNode() : Node(NK_Map) {} - static bool classof(const Node *N) { return N->getKind() == NK_Map; } - - void write(Writer &MPWriter) override { - MPWriter.writeMapSize(this->size()); - for (auto &N : *this) { - MPWriter.write(N.first()); - N.second->write(MPWriter); - } - } -}; - -} // end namespace msgpack - -namespace yaml { - -template <> struct PolymorphicTraits { - static NodeKind getKind(const msgpack::NodePtr &N) { - if (isa(*N)) - return NodeKind::Scalar; - if (isa(*N)) - return NodeKind::Map; - if (isa(*N)) - return NodeKind::Sequence; - llvm_unreachable("NodeKind not supported"); - } - static msgpack::ScalarNode &getAsScalar(msgpack::NodePtr &N) { - if (!N || !isa(*N)) - N.reset(new msgpack::ScalarNode()); - return *cast(N.get()); - } - static msgpack::MapNode &getAsMap(msgpack::NodePtr &N) { - if (!N || !isa(*N)) - N.reset(new msgpack::MapNode()); - return *cast(N.get()); - } - static msgpack::ArrayNode &getAsSequence(msgpack::NodePtr &N) { - if (!N || !isa(*N)) - N.reset(new msgpack::ArrayNode()); - return *cast(N.get()); - } -}; - -template <> struct TaggedScalarTraits { - static void output(const msgpack::ScalarNode &S, void *Ctxt, - raw_ostream &ScalarOS, raw_ostream &TagOS) { - if (!S.IgnoreTag) - TagOS << S.getYAMLTag(); - S.outputYAML(ScalarOS); - } - - static StringRef input(StringRef ScalarStr, StringRef Tag, void *Ctxt, - msgpack::ScalarNode &S) { - if (Tag == msgpack::ScalarNode::IntTag) { - S.setScalarKind(msgpack::ScalarNode::SK_UInt); - if (S.inputYAML(ScalarStr) == StringRef()) - return StringRef(); - S.setScalarKind(msgpack::ScalarNode::SK_Int); - return S.inputYAML(ScalarStr); - } - - if (S.IgnoreTag || Tag == msgpack::ScalarNode::StringTag || - Tag == "tag:yaml.org,2002:str") - S.setScalarKind(msgpack::ScalarNode::SK_String); - else if (Tag == msgpack::ScalarNode::NilTag) - S.setScalarKind(msgpack::ScalarNode::SK_Nil); - else if (Tag == msgpack::ScalarNode::BooleanTag) - S.setScalarKind(msgpack::ScalarNode::SK_Boolean); - else if (Tag == msgpack::ScalarNode::FloatTag) - S.setScalarKind(msgpack::ScalarNode::SK_Float); - else if (Tag == msgpack::ScalarNode::StringTag) - S.setScalarKind(msgpack::ScalarNode::SK_String); - else if (Tag == msgpack::ScalarNode::BinaryTag) - S.setScalarKind(msgpack::ScalarNode::SK_Binary); - else - return "Unsupported messagepack tag"; - - return S.inputYAML(ScalarStr); - } - - static QuotingType mustQuote(const msgpack::ScalarNode &S, StringRef Str) { - return S.mustQuoteYAML(Str); - } -}; - -template <> struct CustomMappingTraits { - static void inputOne(IO &IO, StringRef Key, msgpack::MapNode &M) { - IO.mapRequired(Key.str().c_str(), M[Key]); - } - static void output(IO &IO, msgpack::MapNode &M) { - for (auto &N : M) - IO.mapRequired(N.getKey().str().c_str(), N.getValue()); - } -}; - -template <> struct SequenceTraits { - static size_t size(IO &IO, msgpack::ArrayNode &A) { return A.size(); } - static msgpack::NodePtr &element(IO &IO, msgpack::ArrayNode &A, - size_t Index) { - if (Index >= A.size()) - A.resize(Index + 1); - return A[Index]; - } -}; - -} // end namespace yaml -} // end namespace llvm - -#endif // LLVM_BINARYFORMAT_MSGPACKTYPES_H Index: lib/BinaryFormat/CMakeLists.txt =================================================================== --- lib/BinaryFormat/CMakeLists.txt +++ lib/BinaryFormat/CMakeLists.txt @@ -5,7 +5,6 @@ MsgPackDocument.cpp MsgPackDocumentYAML.cpp MsgPackReader.cpp - MsgPackTypes.cpp MsgPackWriter.cpp Wasm.cpp Index: lib/BinaryFormat/MsgPackTypes.cpp =================================================================== --- lib/BinaryFormat/MsgPackTypes.cpp +++ /dev/null @@ -1,302 +0,0 @@ -//===- 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 Node::readArray(Reader &MPReader, size_t Length) { - auto A = std::make_shared(); - 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( - "Insufficient array elements", - std::make_error_code(std::errc::invalid_argument)); - A->push_back(std::move(**OptNodeOrErr)); - } - return OptNodePtr(std::move(A)); -} - -Expected Node::readMap(Reader &MPReader, size_t Length) { - auto M = std::make_shared(); - 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( - "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( - "Insufficient map elements", - std::make_error_code(std::errc::invalid_argument)); - auto *Key = dyn_cast((*OptKeyOrErr)->get()); - if (!Key) - return make_error( - "Only string map keys are supported", - std::make_error_code(std::errc::invalid_argument)); - if (Key->getScalarKind() != ScalarNode::SK_String) - return make_error( - "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 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(Obj.Int)); - case Type::UInt: - return OptNodePtr(std::make_shared(Obj.UInt)); - case Type::Nil: - return OptNodePtr(std::make_shared()); - case Type::Boolean: - return OptNodePtr(std::make_shared(Obj.Bool)); - case Type::Float: - return OptNodePtr(std::make_shared(Obj.Float)); - case Type::String: - return OptNodePtr(std::make_shared(Obj.Raw)); - case Type::Binary: - return OptNodePtr(std::make_shared(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( - "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(IntValue)) {} - -ScalarNode::ScalarNode(uint64_t UIntValue) - : Node(NK_Scalar), SKind(SK_UInt), UIntValue(UIntValue) {} - -ScalarNode::ScalarNode(uint32_t IntValue) - : ScalarNode(static_cast(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::input(ScalarStr, nullptr, IntValue); - case SK_UInt: - return yaml::ScalarTraits::input(ScalarStr, nullptr, UIntValue); - case SK_Nil: - return StringRef(); - case SK_Boolean: - return yaml::ScalarTraits::input(ScalarStr, nullptr, BoolValue); - case SK_Float: - return yaml::ScalarTraits::input(ScalarStr, nullptr, FloatValue); - case SK_Binary: - case SK_String: - return yaml::ScalarTraits::input(ScalarStr, nullptr, - StringValue); - } - llvm_unreachable("unrecognized ScalarKind"); -} - -void ScalarNode::outputYAML(raw_ostream &OS) const { - switch (SKind) { - case SK_Int: - yaml::ScalarTraits::output(IntValue, nullptr, OS); - break; - case SK_UInt: - yaml::ScalarTraits::output(UIntValue, nullptr, OS); - break; - case SK_Nil: - yaml::ScalarTraits::output("", nullptr, OS); - break; - case SK_Boolean: - yaml::ScalarTraits::output(BoolValue, nullptr, OS); - break; - case SK_Float: - yaml::ScalarTraits::output(FloatValue, nullptr, OS); - break; - case SK_Binary: - case SK_String: - yaml::ScalarTraits::output(StringValue, nullptr, OS); - break; - } -} - -yaml::QuotingType ScalarNode::mustQuoteYAML(StringRef ScalarStr) const { - switch (SKind) { - case SK_Int: - return yaml::ScalarTraits::mustQuote(ScalarStr); - case SK_UInt: - return yaml::ScalarTraits::mustQuote(ScalarStr); - case SK_Nil: - return yaml::ScalarTraits::mustQuote(ScalarStr); - case SK_Boolean: - return yaml::ScalarTraits::mustQuote(ScalarStr); - case SK_Float: - return yaml::ScalarTraits::mustQuote(ScalarStr); - case SK_Binary: - case SK_String: - return yaml::ScalarTraits::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; - } -} Index: unittests/BinaryFormat/CMakeLists.txt =================================================================== --- unittests/BinaryFormat/CMakeLists.txt +++ unittests/BinaryFormat/CMakeLists.txt @@ -7,7 +7,6 @@ MachOTest.cpp MsgPackDocumentTest.cpp MsgPackReaderTest.cpp - MsgPackTypesTest.cpp MsgPackWriterTest.cpp TestFileMagic.cpp ) Index: unittests/BinaryFormat/MsgPackTypesTest.cpp =================================================================== --- unittests/BinaryFormat/MsgPackTypesTest.cpp +++ /dev/null @@ -1,187 +0,0 @@ -//===- MsgPackTypesTest.cpp -------------------------------------*- 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 -// -//===----------------------------------------------------------------------===// - -#include "llvm/BinaryFormat/MsgPackTypes.h" -#include "gtest/gtest.h" - -using namespace llvm; -using namespace msgpack; - -TEST(MsgPackTypes, TestReadInt) { - Reader MPReader(StringRef("\xd0\x00", 2)); - auto OptNodeOrErr = Node::read(MPReader); - ASSERT_TRUE(static_cast(OptNodeOrErr)); - ASSERT_TRUE(*OptNodeOrErr); - auto *S = dyn_cast((*OptNodeOrErr)->get()); - ASSERT_TRUE(S); - ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_Int); - ASSERT_EQ(S->getInt(), 0); -} - -TEST(MsgPackTypes, TestReadArray) { - Reader MPReader(StringRef("\x92\xd0\x01\xc0")); - auto OptNodeOrErr = Node::read(MPReader); - ASSERT_TRUE(static_cast(OptNodeOrErr)); - ASSERT_TRUE(*OptNodeOrErr); - auto *A = dyn_cast((*OptNodeOrErr)->get()); - ASSERT_TRUE(A); - ASSERT_EQ(A->size(), 2u); - auto *SI = dyn_cast((*A)[0].get()); - ASSERT_TRUE(SI); - ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_Int); - ASSERT_EQ(SI->getInt(), 1); - auto *SN = dyn_cast((*A)[1].get()); - ASSERT_TRUE(SN); - ASSERT_EQ(SN->getScalarKind(), ScalarNode::SK_Nil); -} - -TEST(MsgPackTypes, TestReadMap) { - Reader MPReader(StringRef("\x82\xa3" - "foo" - "\xd0\x01\xa3" - "bar" - "\xd0\x02")); - auto OptNodeOrErr = Node::read(MPReader); - ASSERT_TRUE(static_cast(OptNodeOrErr)); - ASSERT_TRUE(*OptNodeOrErr); - auto *A = dyn_cast((*OptNodeOrErr)->get()); - ASSERT_TRUE(A); - ASSERT_EQ(A->size(), 2u); - auto *FooS = dyn_cast((*A)["foo"].get()); - ASSERT_TRUE(FooS); - ASSERT_EQ(FooS->getScalarKind(), ScalarNode::SK_Int); - ASSERT_EQ(FooS->getInt(), 1); - auto *BarS = dyn_cast((*A)["bar"].get()); - ASSERT_TRUE(BarS); - ASSERT_EQ(BarS->getScalarKind(), ScalarNode::SK_Int); - ASSERT_EQ(BarS->getInt(), 2); -} - -TEST(MsgPackTypes, TestWriteInt) { - std::string Buffer; - raw_string_ostream OStream(Buffer); - Writer MPWriter(OStream); - ScalarNode I(int64_t(1)); - I.write(MPWriter); - ASSERT_EQ(OStream.str(), "\x01"); -} - -TEST(MsgPackTypes, TestWriteArray) { - std::string Buffer; - raw_string_ostream OStream(Buffer); - Writer MPWriter(OStream); - ArrayNode A; - A.push_back(std::make_shared(int64_t(1))); - A.push_back(std::make_shared()); - A.write(MPWriter); - ASSERT_EQ(OStream.str(), "\x92\x01\xc0"); -} - -TEST(MsgPackTypes, TestWriteMap) { - std::string Buffer; - raw_string_ostream OStream(Buffer); - Writer MPWriter(OStream); - MapNode M; - M["foo"] = std::make_shared(int64_t(1)); - M["bar"] = std::make_shared(int64_t(2)); - M.write(MPWriter); - ASSERT_EQ(OStream.str(), "\x82\xa3" - "foo" - "\x01\xa3" - "bar" - "\x02"); -} - -TEST(MsgPackTypes, TestOutputYAMLArray) { - std::string Buffer; - raw_string_ostream OStream(Buffer); - yaml::Output yout(OStream); - ArrayNode A; - A.push_back(std::make_shared(int64_t(1))); - A.push_back(std::make_shared(int64_t(2))); - yout << A; - ASSERT_EQ(OStream.str(), "---\n- !int 1\n- !int 2\n...\n"); -} - -TEST(MsgPackTypes, TestInputYAMLArray) { - NodePtr RootNode; - yaml::Input yin("---\n- !int 1\n- !str 2\n...\n"); - yin >> RootNode; - auto *A = dyn_cast(RootNode.get()); - ASSERT_TRUE(A); - ASSERT_EQ(A->size(), 2u); - auto *SI = dyn_cast((*A)[0].get()); - ASSERT_TRUE(SI); - ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt); - ASSERT_EQ(SI->getUInt(), 1u); - auto *SS = dyn_cast((*A)[1].get()); - ASSERT_TRUE(SS); - ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String); - ASSERT_EQ(SS->getString(), "2"); -} - -TEST(MsgPackTypes, TestOutputYAMLMap) { - std::string Buffer; - raw_string_ostream OStream(Buffer); - yaml::Output yout(OStream); - MapNode M; - M["foo"] = std::make_shared(int64_t(1)); - M["bar"] = std::make_shared(uint64_t(2)); - auto N = std::make_shared(); - (*N)["baz"] = std::make_shared(true); - M["qux"] = std::move(N); - yout << M; - ASSERT_EQ(OStream.str(), "---\nfoo: !int 1\nbar: " - "!int 2\nqux: \n baz: " - "!bool true\n...\n"); -} - -TEST(MsgPackTypes, TestInputYAMLMap) { - NodePtr RootNode; - yaml::Input yin("---\nfoo: !int 1\nbaz: !str 2\n...\n"); - yin >> RootNode; - auto *M = dyn_cast(RootNode.get()); - ASSERT_TRUE(M); - ASSERT_EQ(M->size(), 2u); - auto *SI = dyn_cast((*M)["foo"].get()); - ASSERT_TRUE(SI); - ASSERT_EQ(SI->getScalarKind(), ScalarNode::SK_UInt); - ASSERT_EQ(SI->getUInt(), 1u); - auto *SS = dyn_cast((*M)["baz"].get()); - ASSERT_TRUE(SS); - ASSERT_EQ(SS->getScalarKind(), ScalarNode::SK_String); - ASSERT_EQ(SS->getString(), "2"); -} - -// Test that the document is parsed into a tree of shared_ptr where each node -// can have multiple owners. -TEST(MsgPackTypes, TestInputShared) { - yaml::Input yin("---\nfoo:\n bar: !int 1\n...\n"); - NodePtr InnerMap; - NodePtr IntNode; - { - { - { - NodePtr RootNode; - yin >> RootNode; - auto *M = dyn_cast(RootNode.get()); - ASSERT_TRUE(M); - ASSERT_EQ(M->size(), 1u); - InnerMap = (*M)["foo"]; - } - auto *N = dyn_cast(InnerMap.get()); - ASSERT_TRUE(N); - ASSERT_EQ(N->size(), 1u); - IntNode = (*N)["bar"]; - } - auto *S = dyn_cast(IntNode.get()); - ASSERT_TRUE(S); - ASSERT_EQ(S->getScalarKind(), ScalarNode::SK_UInt); - ASSERT_EQ(S->getUInt(), 1u); - } -}