fixup data decode
This commit is contained in:
+179
-30
@@ -42,6 +42,15 @@ void testToBytes(bool be, Fn&& fn, const char(&expect)[N])
|
||||
testBytes(buf, expect);
|
||||
}
|
||||
|
||||
template<typename Fn, size_t N>
|
||||
void testFromBytes(bool be, const char(&input)[N], Fn&& fn)
|
||||
{
|
||||
std::vector<uint8_t> buf(input, input+N-1);
|
||||
FixedBuf S(be, buf);
|
||||
fn(S);
|
||||
testCase(S.good() && S.empty())<<"Deserialize \""<<escape(std::string((const char*)input, N-1))<<"\" leaves "<<S.good()<<" "<<S.size();
|
||||
}
|
||||
|
||||
void testSerialize1()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
@@ -76,35 +85,87 @@ void testSerialize1()
|
||||
}, "\x02 \x01\x0bhello world\x00\x00\x00\xab");
|
||||
}
|
||||
|
||||
void testDeserialize1()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = nt::NTScalar{TypeCode::UInt32}.build().create();
|
||||
testFromBytes(true, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_full(buf, ctxt, val);
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = nt::NTScalar{TypeCode::UInt32}.build().create();
|
||||
testFromBytes(true, "\x00",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = nt::NTScalar{TypeCode::UInt32}.build().create();
|
||||
testFromBytes(true, "\x01\x02\xde\xad\xbe\xef",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!!val["value"].isMarked());
|
||||
testOk1(!val["timeStamp.nanoseconds"].isMarked());
|
||||
testEq(val["value"].as<uint32_t>(), 0xdeadbeef);
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = nt::NTScalar{TypeCode::UInt32}.build().create();
|
||||
testFromBytes(true, "\x02 \x01\x0bhello world\x00\x00\x00\xab",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["timeStamp.nanoseconds"].isMarked());
|
||||
testOk1(!!val["alarm.message"].isMarked());
|
||||
testEq(val["value"].as<uint32_t>(), 0u);
|
||||
testEq(val["timeStamp.nanoseconds"].as<uint32_t>(), 0xab);
|
||||
testEq(val["alarm.message"].as<std::string>(), "hello world");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TypeDef simpledef(TypeCode::Struct, "simple_t", {
|
||||
Member(TypeCode::Float64A, "value"),
|
||||
Member(TypeCode::Struct, "timeStamp", "time_t", {
|
||||
Member(TypeCode::UInt64, "secondsPastEpoch"),
|
||||
Member(TypeCode::UInt32, "nanoseconds"),
|
||||
}),
|
||||
Member(TypeCode::Struct, "arbitrary", {
|
||||
Member(TypeCode::StructA, "sarr", {
|
||||
Member(TypeCode::UInt32, "value"),
|
||||
}),
|
||||
}),
|
||||
Member(TypeCode::Any, "any"),
|
||||
Member(TypeCode::AnyA, "anya"),
|
||||
Member(TypeCode::Union, "choice", {
|
||||
Member(TypeCode::Float32, "a"),
|
||||
Member(TypeCode::String, "b"),
|
||||
}),
|
||||
Member(TypeCode::UnionA, "achoice", {
|
||||
Member(TypeCode::String, "x"),
|
||||
Member(TypeCode::String, "y"),
|
||||
}),
|
||||
});
|
||||
|
||||
void testSerialize2()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
|
||||
TypeDef def(TypeCode::Struct, "simple_t", {
|
||||
Member(TypeCode::Float64A, "value"),
|
||||
Member(TypeCode::Struct, "timeStamp", "time_t", {
|
||||
Member(TypeCode::UInt64, "secondsPastEpoch"),
|
||||
Member(TypeCode::UInt32, "nanoseconds"),
|
||||
}),
|
||||
Member(TypeCode::Struct, "arbitrary", {
|
||||
Member(TypeCode::StructA, "sarr", {
|
||||
Member(TypeCode::UInt32, "value"),
|
||||
}),
|
||||
}),
|
||||
Member(TypeCode::Any, "any"),
|
||||
Member(TypeCode::AnyA, "anya"),
|
||||
Member(TypeCode::Union, "choice", {
|
||||
Member(TypeCode::Float32, "a"),
|
||||
Member(TypeCode::String, "b"),
|
||||
}),
|
||||
Member(TypeCode::UnionA, "achoice", {
|
||||
Member(TypeCode::String, "x"),
|
||||
Member(TypeCode::String, "y"),
|
||||
}),
|
||||
});
|
||||
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
|
||||
auto fld = val["arbitrary.sarr"];
|
||||
shared_array<Value> arr(3);
|
||||
@@ -122,7 +183,7 @@ void testSerialize2()
|
||||
}
|
||||
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
|
||||
val["choice->b"] = "test";
|
||||
testOk1(!!val["choice"].isMarked());
|
||||
@@ -133,7 +194,7 @@ void testSerialize2()
|
||||
}
|
||||
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
|
||||
auto fld = val["achoice"];
|
||||
shared_array<Value> arr(3);
|
||||
@@ -152,7 +213,7 @@ void testSerialize2()
|
||||
|
||||
// Any
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
|
||||
auto v = TypeDef(TypeCode::UInt32).create();
|
||||
v = 0x600df00d;
|
||||
@@ -166,7 +227,7 @@ void testSerialize2()
|
||||
|
||||
// Any
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
val["any"].mark();
|
||||
|
||||
testToBytes(true, [&val](Buffer& buf) {
|
||||
@@ -176,7 +237,7 @@ void testSerialize2()
|
||||
|
||||
// Any[]
|
||||
{
|
||||
auto val = def.create();
|
||||
auto val = simpledef.create();
|
||||
|
||||
auto fld = val["anya"];
|
||||
shared_array<Value> arr(3);
|
||||
@@ -195,13 +256,101 @@ void testSerialize2()
|
||||
}
|
||||
}
|
||||
|
||||
void testDeserialize2()
|
||||
{
|
||||
testDiag("%s", __func__);
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x01@\x03\x01\xde\xad\xbe\xef\x01\x1b\xad\xfa\xce\x00",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["arbitrary.sarr"].isMarked());
|
||||
testEq(val["arbitrary.sarr"].as<shared_array<const void>>().size(), 3u*sizeof(Value));
|
||||
testEq(val["arbitrary.sarr[0]value"].as<uint32_t>(), 0xdeadbeef);
|
||||
testEq(val["arbitrary.sarr[1]value"].as<uint32_t>(), 0x1badface);
|
||||
testEq(val["arbitrary.sarr[2]value"].type(), TypeCode::Null);
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x02\x00\x02\x01\x04test",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["choice"].isMarked());
|
||||
testEq(val["choice"].as<std::string>(), "test");
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x02\x00\x04\x03\x01\x00\x04theX\x01\x01\x04theY\x00",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["achoice"].isMarked());
|
||||
testEq(val["achoice"].as<shared_array<const void>>().size(), 3u*sizeof(Value));
|
||||
testEq(val["achoice[0]"].as<std::string>(), "theX");
|
||||
testEq(val["achoice[1]"].as<std::string>(), "theY");
|
||||
testEq(val["achoice[2]"].type(), TypeCode::Null);
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x01\x80\x26\x60\x0d\xf0\x0d",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["any"].isMarked());
|
||||
testEq(val["any"].as<uint32_t>(), 0x600df00d);
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x01\x80\xff",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["any"].isMarked());
|
||||
//testEq(val["any"].type(), TypeCode::Null); determine type _inside_ Any?
|
||||
}
|
||||
|
||||
{
|
||||
TypeStore ctxt;
|
||||
auto val = simpledef.create();
|
||||
testFromBytes(true, "\x02\x00\x01\x03\x01\x26\x00\x00\x00\x7b\x01\x80\x00\x01\x01q\x60\x04theq\x00",
|
||||
[&val, &ctxt](Buffer& buf) {
|
||||
from_wire_valid(buf, ctxt, val);
|
||||
});
|
||||
testOk1(!val["value"].isMarked());
|
||||
testOk1(!!val["anya"].isMarked());
|
||||
testEq(val["anya"].as<shared_array<const void>>().size(), 3u*sizeof(Value));
|
||||
testEq(val["anya[0]"].as<uint32_t>(), 0x7b);
|
||||
testEq(val["anya[1]q"].as<std::string>(), "theq");
|
||||
testEq(val["anya[2]"].type(), TypeCode::Null);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
MAIN(testdata)
|
||||
{
|
||||
testPlan(12);
|
||||
testPlan(58);
|
||||
testSerialize1();
|
||||
testDeserialize1();
|
||||
testSerialize2();
|
||||
testDeserialize2();
|
||||
cleanup_for_valgrind();
|
||||
return testDone();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user