mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
7bca68b8dc
The readFromBlob method can now be used to read MsgPack into a Document that already contains something, merging the two. There is a new Merger argument to readFromBlob, a callback function to resolve conflicts. Differential Revision: https://reviews.llvm.org/D79671 Change-Id: Icf3e959217fe33cd907a41516c0386aef2847c0c
286 lines
9.1 KiB
C++
286 lines
9.1 KiB
C++
//===- MsgPackDocumentTest.cpp --------------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/BinaryFormat/MsgPackDocument.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
using namespace msgpack;
|
|
|
|
TEST(MsgPackDocument, TestReadInt) {
|
|
Document Doc;
|
|
bool Ok = Doc.readFromBlob(StringRef("\xd0\x00", 2), /*Multi=*/false);
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Int);
|
|
ASSERT_EQ(Doc.getRoot().getInt(), 0);
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestReadMergeArray) {
|
|
Document Doc;
|
|
bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
|
|
auto A = Doc.getRoot().getArray();
|
|
ASSERT_EQ(A.size(), 2u);
|
|
auto SI = A[0];
|
|
ASSERT_EQ(SI.getKind(), Type::Int);
|
|
ASSERT_EQ(SI.getInt(), 1);
|
|
auto SN = A[1];
|
|
ASSERT_EQ(SN.getKind(), Type::Nil);
|
|
|
|
Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
|
|
[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
|
|
// Allow array, merging into existing elements, ORing
|
|
// ints.
|
|
if (DestNode->getKind() == Type::Int &&
|
|
SrcNode.getKind() == Type::Int) {
|
|
*DestNode = DestNode->getDocument()->getNode(
|
|
DestNode->getInt() | SrcNode.getInt());
|
|
return 0;
|
|
}
|
|
return DestNode->isArray() && SrcNode.isArray() ? 0
|
|
: -1;
|
|
});
|
|
ASSERT_TRUE(Ok);
|
|
A = Doc.getRoot().getArray();
|
|
ASSERT_EQ(A.size(), 2u);
|
|
SI = A[0];
|
|
ASSERT_EQ(SI.getKind(), Type::Int);
|
|
ASSERT_EQ(SI.getInt(), 43);
|
|
SN = A[1];
|
|
ASSERT_EQ(SN.getKind(), Type::Nil);
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestReadAppendArray) {
|
|
Document Doc;
|
|
bool Ok = Doc.readFromBlob(StringRef("\x92\xd0\x01\xc0"), /*Multi=*/false);
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
|
|
auto A = Doc.getRoot().getArray();
|
|
ASSERT_EQ(A.size(), 2u);
|
|
auto SI = A[0];
|
|
ASSERT_EQ(SI.getKind(), Type::Int);
|
|
ASSERT_EQ(SI.getInt(), 1);
|
|
auto SN = A[1];
|
|
ASSERT_EQ(SN.getKind(), Type::Nil);
|
|
|
|
Ok = Doc.readFromBlob(StringRef("\x91\xd0\x2a"), /*Multi=*/false,
|
|
[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
|
|
// Allow array, appending after existing elements
|
|
return DestNode->isArray() && SrcNode.isArray()
|
|
? DestNode->getArray().size()
|
|
: -1;
|
|
});
|
|
ASSERT_TRUE(Ok);
|
|
A = Doc.getRoot().getArray();
|
|
ASSERT_EQ(A.size(), 3u);
|
|
SI = A[0];
|
|
ASSERT_EQ(SI.getKind(), Type::Int);
|
|
ASSERT_EQ(SI.getInt(), 1);
|
|
SN = A[1];
|
|
ASSERT_EQ(SN.getKind(), Type::Nil);
|
|
SI = A[2];
|
|
ASSERT_EQ(SI.getKind(), Type::Int);
|
|
ASSERT_EQ(SI.getInt(), 42);
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestReadMergeMap) {
|
|
Document Doc;
|
|
bool Ok = Doc.readFromBlob(StringRef("\x82\xa3"
|
|
"foo"
|
|
"\xd0\x01\xa3"
|
|
"bar"
|
|
"\xd0\x02"),
|
|
/*Multi=*/false);
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
|
|
auto M = Doc.getRoot().getMap();
|
|
ASSERT_EQ(M.size(), 2u);
|
|
auto FooS = M["foo"];
|
|
ASSERT_EQ(FooS.getKind(), Type::Int);
|
|
ASSERT_EQ(FooS.getInt(), 1);
|
|
auto BarS = M["bar"];
|
|
ASSERT_EQ(BarS.getKind(), Type::Int);
|
|
ASSERT_EQ(BarS.getInt(), 2);
|
|
|
|
Ok = Doc.readFromBlob(StringRef("\x82\xa3"
|
|
"foz"
|
|
"\xd0\x03\xa3"
|
|
"baz"
|
|
"\xd0\x04"),
|
|
/*Multi=*/false,
|
|
[](DocNode *DestNode, DocNode SrcNode, DocNode MapKey) {
|
|
return DestNode->isMap() && SrcNode.isMap() ? 0 : -1;
|
|
});
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(M.size(), 4u);
|
|
FooS = M["foo"];
|
|
ASSERT_EQ(FooS.getKind(), Type::Int);
|
|
ASSERT_EQ(FooS.getInt(), 1);
|
|
BarS = M["bar"];
|
|
ASSERT_EQ(BarS.getKind(), Type::Int);
|
|
ASSERT_EQ(BarS.getInt(), 2);
|
|
auto FozS = M["foz"];
|
|
ASSERT_EQ(FozS.getKind(), Type::Int);
|
|
ASSERT_EQ(FozS.getInt(), 3);
|
|
auto BazS = M["baz"];
|
|
ASSERT_EQ(BazS.getKind(), Type::Int);
|
|
ASSERT_EQ(BazS.getInt(), 4);
|
|
|
|
Ok = Doc.readFromBlob(
|
|
StringRef("\x82\xa3"
|
|
"foz"
|
|
"\xd0\x06\xa3"
|
|
"bay"
|
|
"\xd0\x08"),
|
|
/*Multi=*/false, [](DocNode *Dest, DocNode Src, DocNode MapKey) {
|
|
// Merger function that merges two ints by ORing their values, as long
|
|
// as the map key is "foz".
|
|
if (Src.isMap())
|
|
return Dest->isMap();
|
|
if (Src.isArray())
|
|
return Dest->isArray();
|
|
if (MapKey.isString() && MapKey.getString() == "foz" &&
|
|
Dest->getKind() == Type::Int && Src.getKind() == Type::Int) {
|
|
*Dest = Src.getDocument()->getNode(Dest->getInt() | Src.getInt());
|
|
return true;
|
|
}
|
|
return false;
|
|
});
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(M.size(), 5u);
|
|
FooS = M["foo"];
|
|
ASSERT_EQ(FooS.getKind(), Type::Int);
|
|
ASSERT_EQ(FooS.getInt(), 1);
|
|
BarS = M["bar"];
|
|
ASSERT_EQ(BarS.getKind(), Type::Int);
|
|
ASSERT_EQ(BarS.getInt(), 2);
|
|
FozS = M["foz"];
|
|
ASSERT_EQ(FozS.getKind(), Type::Int);
|
|
ASSERT_EQ(FozS.getInt(), 7);
|
|
BazS = M["baz"];
|
|
ASSERT_EQ(BazS.getKind(), Type::Int);
|
|
ASSERT_EQ(BazS.getInt(), 4);
|
|
auto BayS = M["bay"];
|
|
ASSERT_EQ(BayS.getKind(), Type::Int);
|
|
ASSERT_EQ(BayS.getInt(), 8);
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestWriteInt) {
|
|
Document Doc;
|
|
Doc.getRoot() = Doc.getNode(int64_t(1));
|
|
std::string Buffer;
|
|
Doc.writeToBlob(Buffer);
|
|
ASSERT_EQ(Buffer, "\x01");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestWriteArray) {
|
|
Document Doc;
|
|
auto A = Doc.getRoot().getArray(/*Convert=*/true);
|
|
A.push_back(Doc.getNode(int64_t(1)));
|
|
A.push_back(Doc.getNode());
|
|
std::string Buffer;
|
|
Doc.writeToBlob(Buffer);
|
|
ASSERT_EQ(Buffer, "\x92\x01\xc0");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestWriteMap) {
|
|
Document Doc;
|
|
auto M = Doc.getRoot().getMap(/*Convert=*/true);
|
|
M["foo"] = Doc.getNode(int64_t(1));
|
|
M["bar"] = Doc.getNode(int64_t(2));
|
|
std::string Buffer;
|
|
Doc.writeToBlob(Buffer);
|
|
ASSERT_EQ(Buffer, "\x82\xa3"
|
|
"bar"
|
|
"\x02\xa3"
|
|
"foo"
|
|
"\x01");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestOutputYAMLArray) {
|
|
Document Doc;
|
|
auto A = Doc.getRoot().getArray(/*Convert=*/true);
|
|
A.push_back(Doc.getNode(int64_t(1)));
|
|
A.push_back(Doc.getNode(int64_t(2)));
|
|
std::string Buffer;
|
|
raw_string_ostream OStream(Buffer);
|
|
Doc.toYAML(OStream);
|
|
ASSERT_EQ(OStream.str(), "---\n- 1\n- 2\n...\n");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestInputYAMLArray) {
|
|
Document Doc;
|
|
bool Ok = Doc.fromYAML("---\n- !int 0x1\n- !str 2\n...\n");
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Array);
|
|
auto A = Doc.getRoot().getArray();
|
|
ASSERT_EQ(A.size(), 2u);
|
|
auto SI = A[0];
|
|
ASSERT_EQ(SI.getKind(), Type::UInt);
|
|
ASSERT_EQ(SI.getUInt(), 1u);
|
|
auto SS = A[1];
|
|
ASSERT_EQ(SS.getKind(), Type::String);
|
|
ASSERT_EQ(SS.getString(), "2");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestOutputYAMLMap) {
|
|
Document Doc;
|
|
auto M = Doc.getRoot().getMap(/*Convert=*/true);
|
|
M["foo"] = Doc.getNode(int64_t(1));
|
|
M["bar"] = Doc.getNode(uint64_t(2));
|
|
auto N = Doc.getMapNode();
|
|
M["qux"] = N;
|
|
N["baz"] = Doc.getNode(true);
|
|
std::string Buffer;
|
|
raw_string_ostream OStream(Buffer);
|
|
Doc.toYAML(OStream);
|
|
ASSERT_EQ(OStream.str(), "---\n"
|
|
"bar: 2\n"
|
|
"foo: 1\n"
|
|
"qux:\n"
|
|
" baz: true\n"
|
|
"...\n");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestOutputYAMLMapHex) {
|
|
Document Doc;
|
|
Doc.setHexMode();
|
|
auto M = Doc.getRoot().getMap(/*Convert=*/true);
|
|
M["foo"] = Doc.getNode(int64_t(1));
|
|
M["bar"] = Doc.getNode(uint64_t(2));
|
|
auto N = Doc.getMapNode();
|
|
M["qux"] = N;
|
|
N["baz"] = Doc.getNode(true);
|
|
std::string Buffer;
|
|
raw_string_ostream OStream(Buffer);
|
|
Doc.toYAML(OStream);
|
|
ASSERT_EQ(OStream.str(), "---\n"
|
|
"bar: 0x2\n"
|
|
"foo: 1\n"
|
|
"qux:\n"
|
|
" baz: true\n"
|
|
"...\n");
|
|
}
|
|
|
|
TEST(MsgPackDocument, TestInputYAMLMap) {
|
|
Document Doc;
|
|
bool Ok = Doc.fromYAML("---\nfoo: !int 0x1\nbaz: !str 2\n...\n");
|
|
ASSERT_TRUE(Ok);
|
|
ASSERT_EQ(Doc.getRoot().getKind(), Type::Map);
|
|
auto M = Doc.getRoot().getMap();
|
|
ASSERT_EQ(M.size(), 2u);
|
|
auto SI = M["foo"];
|
|
ASSERT_EQ(SI.getKind(), Type::UInt);
|
|
ASSERT_EQ(SI.getUInt(), 1u);
|
|
auto SS = M["baz"];
|
|
ASSERT_EQ(SS.getKind(), Type::String);
|
|
ASSERT_EQ(SS.getString(), "2");
|
|
}
|