| // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors |
| // Licensed under the MIT License: |
| // |
| // Permission is hereby granted, free of charge, to any person obtaining a copy |
| // of this software and associated documentation files (the "Software"), to deal |
| // in the Software without restriction, including without limitation the rights |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| // copies of the Software, and to permit persons to whom the Software is |
| // furnished to do so, subject to the following conditions: |
| // |
| // The above copyright notice and this permission notice shall be included in |
| // all copies or substantial portions of the Software. |
| // |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| // THE SOFTWARE. |
| |
| #ifndef _GNU_SOURCE |
| #define _GNU_SOURCE |
| #endif |
| |
| #include "test-util.h" |
| #include <kj/debug.h> |
| #include <kj/compat/gtest.h> |
| #include <kj/io.h> |
| #include <kj/miniposix.h> |
| |
| namespace capnp { |
| namespace _ { // private |
| namespace { |
| |
| template <typename Builder> |
| void genericInitTestMessage(Builder builder) { |
| builder.setVoidField(VOID); |
| builder.setVoidField(); // Means the same as above. |
| builder.setBoolField(true); |
| builder.setInt8Field(-123); |
| builder.setInt16Field(-12345); |
| builder.setInt32Field(-12345678); |
| builder.setInt64Field(-123456789012345ll); |
| builder.setUInt8Field(234u); |
| builder.setUInt16Field(45678u); |
| builder.setUInt32Field(3456789012u); |
| builder.setUInt64Field(12345678901234567890ull); |
| builder.setFloat32Field(1234.5); |
| builder.setFloat64Field(-123e45); |
| builder.setTextField("foo"); |
| builder.setDataField(data("bar")); |
| { |
| auto subBuilder = builder.initStructField(); |
| subBuilder.setVoidField(VOID); |
| subBuilder.setBoolField(true); |
| subBuilder.setInt8Field(-12); |
| subBuilder.setInt16Field(3456); |
| subBuilder.setInt32Field(-78901234); |
| subBuilder.setInt64Field(56789012345678ll); |
| subBuilder.setUInt8Field(90u); |
| subBuilder.setUInt16Field(1234u); |
| subBuilder.setUInt32Field(56789012u); |
| subBuilder.setUInt64Field(345678901234567890ull); |
| subBuilder.setFloat32Field(-1.25e-10f); |
| subBuilder.setFloat64Field(345); |
| subBuilder.setTextField("baz"); |
| subBuilder.setDataField(data("qux")); |
| { |
| auto subSubBuilder = subBuilder.initStructField(); |
| subSubBuilder.setTextField("nested"); |
| subSubBuilder.initStructField().setTextField("really nested"); |
| } |
| subBuilder.setEnumField(TestEnum::BAZ); |
| |
| subBuilder.setVoidList({VOID, VOID, VOID}); |
| subBuilder.setBoolList({false, true, false, true, true}); |
| subBuilder.setInt8List({12, -34, -0x80, 0x7f}); |
| subBuilder.setInt16List({1234, -5678, -0x8000, 0x7fff}); |
| // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1. |
| subBuilder.setInt32List({12345678, -90123456, -0x7fffffff - 1, 0x7fffffff}); |
| subBuilder.setInt64List({123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll}); |
| subBuilder.setUInt8List({12u, 34u, 0u, 0xffu}); |
| subBuilder.setUInt16List({1234u, 5678u, 0u, 0xffffu}); |
| subBuilder.setUInt32List({12345678u, 90123456u, 0u, 0xffffffffu}); |
| subBuilder.setUInt64List({123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull}); |
| subBuilder.setFloat32List({0, 1234567, 1e37f, -1e37f, 1e-37f, -1e-37f}); |
| subBuilder.setFloat64List({0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306}); |
| subBuilder.setTextList({"quux", "corge", "grault"}); |
| subBuilder.setDataList({data("garply"), data("waldo"), data("fred")}); |
| { |
| auto listBuilder = subBuilder.initStructList(3); |
| listBuilder[0].setTextField("x structlist 1"); |
| listBuilder[1].setTextField("x structlist 2"); |
| listBuilder[2].setTextField("x structlist 3"); |
| } |
| subBuilder.setEnumList({TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT}); |
| } |
| builder.setEnumField(TestEnum::CORGE); |
| |
| builder.initVoidList(6); |
| builder.setBoolList({true, false, false, true}); |
| builder.setInt8List({111, -111}); |
| builder.setInt16List({11111, -11111}); |
| builder.setInt32List({111111111, -111111111}); |
| builder.setInt64List({1111111111111111111ll, -1111111111111111111ll}); |
| builder.setUInt8List({111u, 222u}); |
| builder.setUInt16List({33333u, 44444u}); |
| builder.setUInt32List({3333333333u}); |
| builder.setUInt64List({11111111111111111111ull}); |
| builder.setFloat32List({5555.5, kj::inf(), -kj::inf(), kj::nan()}); |
| builder.setFloat64List({7777.75, kj::inf(), -kj::inf(), kj::nan()}); |
| builder.setTextList({"plugh", "xyzzy", "thud"}); |
| builder.setDataList({data("oops"), data("exhausted"), data("rfc3092")}); |
| { |
| auto listBuilder = builder.initStructList(3); |
| listBuilder[0].setTextField("structlist 1"); |
| listBuilder[1].setTextField("structlist 2"); |
| listBuilder[2].setTextField("structlist 3"); |
| } |
| builder.setEnumList({TestEnum::FOO, TestEnum::GARPLY}); |
| } |
| |
| #if !CAPNP_LITE |
| |
| void dynamicInitTestMessage(DynamicStruct::Builder builder) { |
| builder.set("voidField", VOID); |
| builder.set("boolField", true); |
| builder.set("int8Field", -123); |
| builder.set("int16Field", -12345); |
| builder.set("int32Field", -12345678); |
| builder.set("int64Field", -123456789012345ll); |
| builder.set("uInt8Field", 234u); |
| builder.set("uInt16Field", 45678u); |
| builder.set("uInt32Field", 3456789012u); |
| builder.set("uInt64Field", 12345678901234567890ull); |
| builder.set("float32Field", 1234.5); |
| builder.set("float64Field", -123e45); |
| builder.set("textField", "foo"); |
| builder.set("dataField", data("bar")); |
| { |
| auto subBuilder = builder.init("structField").as<DynamicStruct>(); |
| subBuilder.set("voidField", VOID); |
| subBuilder.set("boolField", true); |
| subBuilder.set("int8Field", -12); |
| subBuilder.set("int16Field", 3456); |
| subBuilder.set("int32Field", -78901234); |
| subBuilder.set("int64Field", 56789012345678ll); |
| subBuilder.set("uInt8Field", 90u); |
| subBuilder.set("uInt16Field", 1234u); |
| subBuilder.set("uInt32Field", 56789012u); |
| subBuilder.set("uInt64Field", 345678901234567890ull); |
| subBuilder.set("float32Field", -1.25e-10); |
| subBuilder.set("float64Field", 345); |
| subBuilder.set("textField", "baz"); |
| subBuilder.set("dataField", data("qux")); |
| { |
| auto subSubBuilder = subBuilder.init("structField").as<DynamicStruct>(); |
| subSubBuilder.set("textField", "nested"); |
| subSubBuilder.init("structField").as<DynamicStruct>().set("textField", "really nested"); |
| } |
| subBuilder.set("enumField", "baz"); |
| |
| subBuilder.set("voidList", {VOID, VOID, VOID}); |
| subBuilder.set("boolList", {false, true, false, true, true}); |
| subBuilder.set("int8List", {12, -34, -0x80, 0x7f}); |
| subBuilder.set("int16List", {1234, -5678, -0x8000, 0x7fff}); |
| // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1. |
| subBuilder.set("int32List", {12345678, -90123456, -0x7fffffff - 1, 0x7fffffff}); |
| subBuilder.set("int64List", {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll}); |
| subBuilder.set("uInt8List", {12u, 34u, 0u, 0xffu}); |
| subBuilder.set("uInt16List", {1234u, 5678u, 0u, 0xffffu}); |
| subBuilder.set("uInt32List", {12345678u, 90123456u, 0u, 0xffffffffu}); |
| subBuilder.set("uInt64List", {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull}); |
| subBuilder.set("float32List", {0, 1234567, 1e37, -1e37, 1e-37, -1e-37}); |
| subBuilder.set("float64List", {0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306}); |
| subBuilder.set("textList", {"quux", "corge", "grault"}); |
| subBuilder.set("dataList", {data("garply"), data("waldo"), data("fred")}); |
| { |
| auto listBuilder = subBuilder.init("structList", 3).as<DynamicList>(); |
| listBuilder[0].as<DynamicStruct>().set("textField", "x structlist 1"); |
| listBuilder[1].as<DynamicStruct>().set("textField", "x structlist 2"); |
| listBuilder[2].as<DynamicStruct>().set("textField", "x structlist 3"); |
| } |
| subBuilder.set("enumList", {"qux", "bar", "grault"}); |
| } |
| builder.set("enumField", "corge"); |
| |
| builder.init("voidList", 6); |
| builder.set("boolList", {true, false, false, true}); |
| builder.set("int8List", {111, -111}); |
| builder.set("int16List", {11111, -11111}); |
| builder.set("int32List", {111111111, -111111111}); |
| builder.set("int64List", {1111111111111111111ll, -1111111111111111111ll}); |
| builder.set("uInt8List", {111u, 222u}); |
| builder.set("uInt16List", {33333u, 44444u}); |
| builder.set("uInt32List", {3333333333u}); |
| builder.set("uInt64List", {11111111111111111111ull}); |
| builder.set("float32List", {5555.5, kj::inf(), -kj::inf(), kj::nan()}); |
| builder.set("float64List", {7777.75, kj::inf(), -kj::inf(), kj::nan()}); |
| builder.set("textList", {"plugh", "xyzzy", "thud"}); |
| builder.set("dataList", {data("oops"), data("exhausted"), data("rfc3092")}); |
| { |
| auto listBuilder = builder.init("structList", 3).as<DynamicList>(); |
| listBuilder[0].as<DynamicStruct>().set("textField", "structlist 1"); |
| listBuilder[1].as<DynamicStruct>().set("textField", "structlist 2"); |
| listBuilder[2].as<DynamicStruct>().set("textField", "structlist 3"); |
| } |
| builder.set("enumList", {"foo", "garply"}); |
| } |
| |
| #endif // !CAPNP_LITE |
| |
| inline bool isNaN(float f) { return f != f; } |
| inline bool isNaN(double f) { return f != f; } |
| |
| template <typename Reader> |
| void genericCheckTestMessage(Reader reader) { |
| EXPECT_EQ(VOID, reader.getVoidField()); |
| EXPECT_EQ(true, reader.getBoolField()); |
| EXPECT_EQ(-123, reader.getInt8Field()); |
| EXPECT_EQ(-12345, reader.getInt16Field()); |
| EXPECT_EQ(-12345678, reader.getInt32Field()); |
| EXPECT_EQ(-123456789012345ll, reader.getInt64Field()); |
| EXPECT_EQ(234u, reader.getUInt8Field()); |
| EXPECT_EQ(45678u, reader.getUInt16Field()); |
| EXPECT_EQ(3456789012u, reader.getUInt32Field()); |
| EXPECT_EQ(12345678901234567890ull, reader.getUInt64Field()); |
| EXPECT_FLOAT_EQ(1234.5f, reader.getFloat32Field()); |
| EXPECT_DOUBLE_EQ(-123e45, reader.getFloat64Field()); |
| EXPECT_EQ("foo", reader.getTextField()); |
| EXPECT_EQ(data("bar"), reader.getDataField()); |
| { |
| auto subReader = reader.getStructField(); |
| EXPECT_EQ(VOID, subReader.getVoidField()); |
| EXPECT_EQ(true, subReader.getBoolField()); |
| EXPECT_EQ(-12, subReader.getInt8Field()); |
| EXPECT_EQ(3456, subReader.getInt16Field()); |
| EXPECT_EQ(-78901234, subReader.getInt32Field()); |
| EXPECT_EQ(56789012345678ll, subReader.getInt64Field()); |
| EXPECT_EQ(90u, subReader.getUInt8Field()); |
| EXPECT_EQ(1234u, subReader.getUInt16Field()); |
| EXPECT_EQ(56789012u, subReader.getUInt32Field()); |
| EXPECT_EQ(345678901234567890ull, subReader.getUInt64Field()); |
| EXPECT_FLOAT_EQ(-1.25e-10f, subReader.getFloat32Field()); |
| EXPECT_DOUBLE_EQ(345, subReader.getFloat64Field()); |
| EXPECT_EQ("baz", subReader.getTextField()); |
| EXPECT_EQ(data("qux"), subReader.getDataField()); |
| { |
| auto subSubReader = subReader.getStructField(); |
| EXPECT_EQ("nested", subSubReader.getTextField()); |
| EXPECT_EQ("really nested", subSubReader.getStructField().getTextField()); |
| } |
| EXPECT_EQ(TestEnum::BAZ, subReader.getEnumField()); |
| |
| checkList(subReader.getVoidList(), {VOID, VOID, VOID}); |
| checkList(subReader.getBoolList(), {false, true, false, true, true}); |
| checkList(subReader.getInt8List(), {12, -34, -0x80, 0x7f}); |
| checkList(subReader.getInt16List(), {1234, -5678, -0x8000, 0x7fff}); |
| // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1. |
| checkList(subReader.getInt32List(), {12345678, -90123456, -0x7fffffff - 1, 0x7fffffff}); |
| checkList(subReader.getInt64List(), {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll}); |
| checkList(subReader.getUInt8List(), {12u, 34u, 0u, 0xffu}); |
| checkList(subReader.getUInt16List(), {1234u, 5678u, 0u, 0xffffu}); |
| checkList(subReader.getUInt32List(), {12345678u, 90123456u, 0u, 0xffffffffu}); |
| checkList(subReader.getUInt64List(), {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull}); |
| checkList(subReader.getFloat32List(), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f}); |
| checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306}); |
| checkList(subReader.getTextList(), {"quux", "corge", "grault"}); |
| checkList(subReader.getDataList(), {data("garply"), data("waldo"), data("fred")}); |
| { |
| auto listReader = subReader.getStructList(); |
| ASSERT_EQ(3u, listReader.size()); |
| EXPECT_EQ("x structlist 1", listReader[0].getTextField()); |
| EXPECT_EQ("x structlist 2", listReader[1].getTextField()); |
| EXPECT_EQ("x structlist 3", listReader[2].getTextField()); |
| } |
| checkList(subReader.getEnumList(), {TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT}); |
| } |
| EXPECT_EQ(TestEnum::CORGE, reader.getEnumField()); |
| |
| EXPECT_EQ(6u, reader.getVoidList().size()); |
| checkList(reader.getBoolList(), {true, false, false, true}); |
| checkList(reader.getInt8List(), {111, -111}); |
| checkList(reader.getInt16List(), {11111, -11111}); |
| checkList(reader.getInt32List(), {111111111, -111111111}); |
| checkList(reader.getInt64List(), {1111111111111111111ll, -1111111111111111111ll}); |
| checkList(reader.getUInt8List(), {111u, 222u}); |
| checkList(reader.getUInt16List(), {33333u, 44444u}); |
| checkList(reader.getUInt32List(), {3333333333u}); |
| checkList(reader.getUInt64List(), {11111111111111111111ull}); |
| { |
| auto listReader = reader.getFloat32List(); |
| ASSERT_EQ(4u, listReader.size()); |
| EXPECT_EQ(5555.5f, listReader[0]); |
| EXPECT_EQ(kj::inf(), listReader[1]); |
| EXPECT_EQ(-kj::inf(), listReader[2]); |
| EXPECT_TRUE(isNaN(listReader[3])); |
| } |
| { |
| auto listReader = reader.getFloat64List(); |
| ASSERT_EQ(4u, listReader.size()); |
| EXPECT_EQ(7777.75, listReader[0]); |
| EXPECT_EQ(kj::inf(), listReader[1]); |
| EXPECT_EQ(-kj::inf(), listReader[2]); |
| EXPECT_TRUE(isNaN(listReader[3])); |
| } |
| checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"}); |
| checkList(reader.getDataList(), {data("oops"), data("exhausted"), data("rfc3092")}); |
| { |
| auto listReader = reader.getStructList(); |
| ASSERT_EQ(3u, listReader.size()); |
| EXPECT_EQ("structlist 1", listReader[0].getTextField()); |
| EXPECT_EQ("structlist 2", listReader[1].getTextField()); |
| EXPECT_EQ("structlist 3", listReader[2].getTextField()); |
| } |
| checkList(reader.getEnumList(), {TestEnum::FOO, TestEnum::GARPLY}); |
| } |
| |
| #if !CAPNP_LITE |
| |
| // Hack because as<>() is a template-parameter-dependent lookup everywhere below... |
| #define as template as |
| |
| Text::Reader name(DynamicEnum e) { |
| KJ_IF_MAYBE(schema, e.getEnumerant()) { |
| return schema->getProto().getName(); |
| } else { |
| return "(unknown enumerant)"; |
| } |
| } |
| |
| template <typename T> |
| void checkEnumList(T reader, std::initializer_list<const char*> expected) { |
| auto list = reader.as<DynamicList>(); |
| ASSERT_EQ(expected.size(), list.size()); |
| for (uint i = 0; i < expected.size(); i++) { |
| EXPECT_EQ(expected.begin()[i], name(list[i].as<DynamicEnum>())); |
| } |
| } |
| |
| template <typename Reader> |
| void dynamicCheckTestMessage(Reader reader) { |
| EXPECT_EQ(VOID, reader.get("voidField").as<Void>()); |
| EXPECT_EQ(true, reader.get("boolField").as<bool>()); |
| EXPECT_EQ(-123, reader.get("int8Field").as<int8_t>()); |
| EXPECT_EQ(-12345, reader.get("int16Field").as<int16_t>()); |
| EXPECT_EQ(-12345678, reader.get("int32Field").as<int32_t>()); |
| EXPECT_EQ(-123456789012345ll, reader.get("int64Field").as<int64_t>()); |
| EXPECT_EQ(234u, reader.get("uInt8Field").as<uint8_t>()); |
| EXPECT_EQ(45678u, reader.get("uInt16Field").as<uint16_t>()); |
| EXPECT_EQ(3456789012u, reader.get("uInt32Field").as<uint32_t>()); |
| EXPECT_EQ(12345678901234567890ull, reader.get("uInt64Field").as<uint64_t>()); |
| EXPECT_FLOAT_EQ(1234.5f, reader.get("float32Field").as<float>()); |
| EXPECT_DOUBLE_EQ(-123e45, reader.get("float64Field").as<double>()); |
| EXPECT_EQ("foo", reader.get("textField").as<Text>()); |
| EXPECT_EQ(data("bar"), reader.get("dataField").as<Data>()); |
| { |
| auto subReader = reader.get("structField").as<DynamicStruct>(); |
| EXPECT_EQ(VOID, subReader.get("voidField").as<Void>()); |
| EXPECT_EQ(true, subReader.get("boolField").as<bool>()); |
| EXPECT_EQ(-12, subReader.get("int8Field").as<int8_t>()); |
| EXPECT_EQ(3456, subReader.get("int16Field").as<int16_t>()); |
| EXPECT_EQ(-78901234, subReader.get("int32Field").as<int32_t>()); |
| EXPECT_EQ(56789012345678ll, subReader.get("int64Field").as<int64_t>()); |
| EXPECT_EQ(90u, subReader.get("uInt8Field").as<uint8_t>()); |
| EXPECT_EQ(1234u, subReader.get("uInt16Field").as<uint16_t>()); |
| EXPECT_EQ(56789012u, subReader.get("uInt32Field").as<uint32_t>()); |
| EXPECT_EQ(345678901234567890ull, subReader.get("uInt64Field").as<uint64_t>()); |
| EXPECT_FLOAT_EQ(-1.25e-10f, subReader.get("float32Field").as<float>()); |
| EXPECT_DOUBLE_EQ(345, subReader.get("float64Field").as<double>()); |
| EXPECT_EQ("baz", subReader.get("textField").as<Text>()); |
| EXPECT_EQ(data("qux"), subReader.get("dataField").as<Data>()); |
| { |
| auto subSubReader = subReader.get("structField").as<DynamicStruct>(); |
| EXPECT_EQ("nested", subSubReader.get("textField").as<Text>()); |
| EXPECT_EQ("really nested", subSubReader.get("structField").as<DynamicStruct>() |
| .get("textField").as<Text>()); |
| } |
| EXPECT_EQ("baz", name(subReader.get("enumField").as<DynamicEnum>())); |
| |
| checkList<Void>(subReader.get("voidList"), {VOID, VOID, VOID}); |
| checkList<bool>(subReader.get("boolList"), {false, true, false, true, true}); |
| checkList<int8_t>(subReader.get("int8List"), {12, -34, -0x80, 0x7f}); |
| checkList<int16_t>(subReader.get("int16List"), {1234, -5678, -0x8000, 0x7fff}); |
| // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1. |
| checkList<int32_t>(subReader.get("int32List"), {12345678, -90123456, -0x7fffffff-1, 0x7fffffff}); |
| checkList<int64_t>(subReader.get("int64List"), {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll}); |
| checkList<uint8_t>(subReader.get("uInt8List"), {12u, 34u, 0u, 0xffu}); |
| checkList<uint16_t>(subReader.get("uInt16List"), {1234u, 5678u, 0u, 0xffffu}); |
| checkList<uint32_t>(subReader.get("uInt32List"), {12345678u, 90123456u, 0u, 0xffffffffu}); |
| checkList<uint64_t>(subReader.get("uInt64List"), {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull}); |
| checkList<float>(subReader.get("float32List"), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f}); |
| checkList<double>(subReader.get("float64List"), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306}); |
| checkList<Text>(subReader.get("textList"), {"quux", "corge", "grault"}); |
| checkList<Data>(subReader.get("dataList"), {data("garply"), data("waldo"), data("fred")}); |
| { |
| auto listReader = subReader.get("structList").as<DynamicList>(); |
| ASSERT_EQ(3u, listReader.size()); |
| EXPECT_EQ("x structlist 1", listReader[0].as<DynamicStruct>().get("textField").as<Text>()); |
| EXPECT_EQ("x structlist 2", listReader[1].as<DynamicStruct>().get("textField").as<Text>()); |
| EXPECT_EQ("x structlist 3", listReader[2].as<DynamicStruct>().get("textField").as<Text>()); |
| } |
| checkEnumList(subReader.get("enumList"), {"qux", "bar", "grault"}); |
| } |
| EXPECT_EQ("corge", name(reader.get("enumField").as<DynamicEnum>())); |
| |
| EXPECT_EQ(6u, reader.get("voidList").as<DynamicList>().size()); |
| checkList<bool>(reader.get("boolList"), {true, false, false, true}); |
| checkList<int8_t>(reader.get("int8List"), {111, -111}); |
| checkList<int16_t>(reader.get("int16List"), {11111, -11111}); |
| checkList<int32_t>(reader.get("int32List"), {111111111, -111111111}); |
| checkList<int64_t>(reader.get("int64List"), {1111111111111111111ll, -1111111111111111111ll}); |
| checkList<uint8_t>(reader.get("uInt8List"), {111u, 222u}); |
| checkList<uint16_t>(reader.get("uInt16List"), {33333u, 44444u}); |
| checkList<uint32_t>(reader.get("uInt32List"), {3333333333u}); |
| checkList<uint64_t>(reader.get("uInt64List"), {11111111111111111111ull}); |
| { |
| auto listReader = reader.get("float32List").as<DynamicList>(); |
| ASSERT_EQ(4u, listReader.size()); |
| EXPECT_EQ(5555.5f, listReader[0].as<float>()); |
| EXPECT_EQ(kj::inf(), listReader[1].as<float>()); |
| EXPECT_EQ(-kj::inf(), listReader[2].as<float>()); |
| EXPECT_TRUE(isNaN(listReader[3].as<float>())); |
| } |
| { |
| auto listReader = reader.get("float64List").as<DynamicList>(); |
| ASSERT_EQ(4u, listReader.size()); |
| EXPECT_EQ(7777.75, listReader[0].as<double>()); |
| EXPECT_EQ(kj::inf(), listReader[1].as<double>()); |
| EXPECT_EQ(-kj::inf(), listReader[2].as<double>()); |
| EXPECT_TRUE(isNaN(listReader[3].as<double>())); |
| } |
| checkList<Text>(reader.get("textList"), {"plugh", "xyzzy", "thud"}); |
| checkList<Data>(reader.get("dataList"), {data("oops"), data("exhausted"), data("rfc3092")}); |
| { |
| auto listReader = reader.get("structList").as<DynamicList>(); |
| ASSERT_EQ(3u, listReader.size()); |
| EXPECT_EQ("structlist 1", listReader[0].as<DynamicStruct>().get("textField").as<Text>()); |
| EXPECT_EQ("structlist 2", listReader[1].as<DynamicStruct>().get("textField").as<Text>()); |
| EXPECT_EQ("structlist 3", listReader[2].as<DynamicStruct>().get("textField").as<Text>()); |
| } |
| checkEnumList(reader.get("enumList"), {"foo", "garply"}); |
| } |
| |
| #undef as |
| |
| #endif // !CAPNP_LITE |
| |
| template <typename Reader> |
| void genericCheckTestMessageAllZero(Reader reader) { |
| EXPECT_EQ(VOID, reader.getVoidField()); |
| EXPECT_EQ(false, reader.getBoolField()); |
| EXPECT_EQ(0, reader.getInt8Field()); |
| EXPECT_EQ(0, reader.getInt16Field()); |
| EXPECT_EQ(0, reader.getInt32Field()); |
| EXPECT_EQ(0, reader.getInt64Field()); |
| EXPECT_EQ(0u, reader.getUInt8Field()); |
| EXPECT_EQ(0u, reader.getUInt16Field()); |
| EXPECT_EQ(0u, reader.getUInt32Field()); |
| EXPECT_EQ(0u, reader.getUInt64Field()); |
| EXPECT_FLOAT_EQ(0, reader.getFloat32Field()); |
| EXPECT_DOUBLE_EQ(0, reader.getFloat64Field()); |
| EXPECT_EQ("", reader.getTextField()); |
| EXPECT_EQ(data(""), reader.getDataField()); |
| { |
| auto subReader = reader.getStructField(); |
| EXPECT_EQ(VOID, subReader.getVoidField()); |
| EXPECT_EQ(false, subReader.getBoolField()); |
| EXPECT_EQ(0, subReader.getInt8Field()); |
| EXPECT_EQ(0, subReader.getInt16Field()); |
| EXPECT_EQ(0, subReader.getInt32Field()); |
| EXPECT_EQ(0, subReader.getInt64Field()); |
| EXPECT_EQ(0u, subReader.getUInt8Field()); |
| EXPECT_EQ(0u, subReader.getUInt16Field()); |
| EXPECT_EQ(0u, subReader.getUInt32Field()); |
| EXPECT_EQ(0u, subReader.getUInt64Field()); |
| EXPECT_FLOAT_EQ(0, subReader.getFloat32Field()); |
| EXPECT_DOUBLE_EQ(0, subReader.getFloat64Field()); |
| EXPECT_EQ("", subReader.getTextField()); |
| EXPECT_EQ(data(""), subReader.getDataField()); |
| { |
| auto subSubReader = subReader.getStructField(); |
| EXPECT_EQ("", subSubReader.getTextField()); |
| EXPECT_EQ("", subSubReader.getStructField().getTextField()); |
| } |
| |
| EXPECT_EQ(0u, subReader.getVoidList().size()); |
| EXPECT_EQ(0u, subReader.getBoolList().size()); |
| EXPECT_EQ(0u, subReader.getInt8List().size()); |
| EXPECT_EQ(0u, subReader.getInt16List().size()); |
| EXPECT_EQ(0u, subReader.getInt32List().size()); |
| EXPECT_EQ(0u, subReader.getInt64List().size()); |
| EXPECT_EQ(0u, subReader.getUInt8List().size()); |
| EXPECT_EQ(0u, subReader.getUInt16List().size()); |
| EXPECT_EQ(0u, subReader.getUInt32List().size()); |
| EXPECT_EQ(0u, subReader.getUInt64List().size()); |
| EXPECT_EQ(0u, subReader.getFloat32List().size()); |
| EXPECT_EQ(0u, subReader.getFloat64List().size()); |
| EXPECT_EQ(0u, subReader.getTextList().size()); |
| EXPECT_EQ(0u, subReader.getDataList().size()); |
| EXPECT_EQ(0u, subReader.getStructList().size()); |
| } |
| |
| EXPECT_EQ(0u, reader.getVoidList().size()); |
| EXPECT_EQ(0u, reader.getBoolList().size()); |
| EXPECT_EQ(0u, reader.getInt8List().size()); |
| EXPECT_EQ(0u, reader.getInt16List().size()); |
| EXPECT_EQ(0u, reader.getInt32List().size()); |
| EXPECT_EQ(0u, reader.getInt64List().size()); |
| EXPECT_EQ(0u, reader.getUInt8List().size()); |
| EXPECT_EQ(0u, reader.getUInt16List().size()); |
| EXPECT_EQ(0u, reader.getUInt32List().size()); |
| EXPECT_EQ(0u, reader.getUInt64List().size()); |
| EXPECT_EQ(0u, reader.getFloat32List().size()); |
| EXPECT_EQ(0u, reader.getFloat64List().size()); |
| EXPECT_EQ(0u, reader.getTextList().size()); |
| EXPECT_EQ(0u, reader.getDataList().size()); |
| EXPECT_EQ(0u, reader.getStructList().size()); |
| } |
| |
| #if !CAPNP_LITE |
| |
| // Hack because as<>() is a template-parameter-dependent lookup everywhere below... |
| #define as template as |
| |
| template <typename Reader> |
| void dynamicCheckTestMessageAllZero(Reader reader) { |
| EXPECT_EQ(VOID, reader.get("voidField").as<Void>()); |
| EXPECT_EQ(false, reader.get("boolField").as<bool>()); |
| EXPECT_EQ(0, reader.get("int8Field").as<int8_t>()); |
| EXPECT_EQ(0, reader.get("int16Field").as<int16_t>()); |
| EXPECT_EQ(0, reader.get("int32Field").as<int32_t>()); |
| EXPECT_EQ(0, reader.get("int64Field").as<int64_t>()); |
| EXPECT_EQ(0u, reader.get("uInt8Field").as<uint8_t>()); |
| EXPECT_EQ(0u, reader.get("uInt16Field").as<uint16_t>()); |
| EXPECT_EQ(0u, reader.get("uInt32Field").as<uint32_t>()); |
| EXPECT_EQ(0u, reader.get("uInt64Field").as<uint64_t>()); |
| EXPECT_FLOAT_EQ(0, reader.get("float32Field").as<float>()); |
| EXPECT_DOUBLE_EQ(0, reader.get("float64Field").as<double>()); |
| EXPECT_EQ("", reader.get("textField").as<Text>()); |
| EXPECT_EQ(data(""), reader.get("dataField").as<Data>()); |
| { |
| auto subReader = reader.get("structField").as<DynamicStruct>(); |
| EXPECT_EQ(VOID, subReader.get("voidField").as<Void>()); |
| EXPECT_EQ(false, subReader.get("boolField").as<bool>()); |
| EXPECT_EQ(0, subReader.get("int8Field").as<int8_t>()); |
| EXPECT_EQ(0, subReader.get("int16Field").as<int16_t>()); |
| EXPECT_EQ(0, subReader.get("int32Field").as<int32_t>()); |
| EXPECT_EQ(0, subReader.get("int64Field").as<int64_t>()); |
| EXPECT_EQ(0u, subReader.get("uInt8Field").as<uint8_t>()); |
| EXPECT_EQ(0u, subReader.get("uInt16Field").as<uint16_t>()); |
| EXPECT_EQ(0u, subReader.get("uInt32Field").as<uint32_t>()); |
| EXPECT_EQ(0u, subReader.get("uInt64Field").as<uint64_t>()); |
| EXPECT_FLOAT_EQ(0, subReader.get("float32Field").as<float>()); |
| EXPECT_DOUBLE_EQ(0, subReader.get("float64Field").as<double>()); |
| EXPECT_EQ("", subReader.get("textField").as<Text>()); |
| EXPECT_EQ(data(""), subReader.get("dataField").as<Data>()); |
| { |
| auto subSubReader = subReader.get("structField").as<DynamicStruct>(); |
| EXPECT_EQ("", subSubReader.get("textField").as<Text>()); |
| EXPECT_EQ("", subSubReader.get("structField").as<DynamicStruct>() |
| .get("textField").as<Text>()); |
| } |
| |
| EXPECT_EQ(0u, subReader.get("voidList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("boolList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("int8List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("int16List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("int32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("int64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("uInt8List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("uInt16List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("uInt32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("uInt64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("float32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("float64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("textList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("dataList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, subReader.get("structList").as<DynamicList>().size()); |
| } |
| |
| EXPECT_EQ(0u, reader.get("voidList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("boolList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("int8List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("int16List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("int32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("int64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("uInt8List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("uInt16List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("uInt32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("uInt64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("float32List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("float64List").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("textList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("dataList").as<DynamicList>().size()); |
| EXPECT_EQ(0u, reader.get("structList").as<DynamicList>().size()); |
| } |
| |
| #undef as |
| |
| #endif // !CAPNP_LITE |
| |
| template <typename Builder> |
| void genericInitListDefaults(Builder builder) { |
| auto lists = builder.initLists(); |
| |
| lists.initList0(2); |
| lists.initList1(4); |
| lists.initList8(2); |
| lists.initList16(2); |
| lists.initList32(2); |
| lists.initList64(2); |
| lists.initListP(2); |
| |
| lists.getList0()[0].setF(VOID); |
| lists.getList0()[1].setF(VOID); |
| lists.getList1()[0].setF(true); |
| lists.getList1()[1].setF(false); |
| lists.getList1()[2].setF(true); |
| lists.getList1()[3].setF(true); |
| lists.getList8()[0].setF(123u); |
| lists.getList8()[1].setF(45u); |
| lists.getList16()[0].setF(12345u); |
| lists.getList16()[1].setF(6789u); |
| lists.getList32()[0].setF(123456789u); |
| lists.getList32()[1].setF(234567890u); |
| lists.getList64()[0].setF(1234567890123456u); |
| lists.getList64()[1].setF(2345678901234567u); |
| lists.getListP()[0].setF("foo"); |
| lists.getListP()[1].setF("bar"); |
| |
| { |
| auto l = lists.initInt32ListList(3); |
| l.set(0, {1, 2, 3}); |
| l.set(1, {4, 5}); |
| l.set(2, {12341234}); |
| } |
| |
| { |
| auto l = lists.initTextListList(3); |
| l.set(0, {"foo", "bar"}); |
| l.set(1, {"baz"}); |
| l.set(2, {"qux", "corge"}); |
| } |
| |
| { |
| auto l = lists.initStructListList(2); |
| auto e = l.init(0, 2); |
| e[0].setInt32Field(123); |
| e[1].setInt32Field(456); |
| e = l.init(1, 1); |
| e[0].setInt32Field(789); |
| } |
| } |
| |
| #if !CAPNP_LITE |
| |
| void dynamicInitListDefaults(DynamicStruct::Builder builder) { |
| auto lists = builder.init("lists").as<DynamicStruct>(); |
| |
| lists.init("list0", 2); |
| lists.init("list1", 4); |
| lists.init("list8", 2); |
| lists.init("list16", 2); |
| lists.init("list32", 2); |
| lists.init("list64", 2); |
| lists.init("listP", 2); |
| |
| lists.get("list0").as<DynamicList>()[0].as<DynamicStruct>().set("f", VOID); |
| lists.get("list0").as<DynamicList>()[1].as<DynamicStruct>().set("f", VOID); |
| lists.get("list1").as<DynamicList>()[0].as<DynamicStruct>().set("f", true); |
| lists.get("list1").as<DynamicList>()[1].as<DynamicStruct>().set("f", false); |
| lists.get("list1").as<DynamicList>()[2].as<DynamicStruct>().set("f", true); |
| lists.get("list1").as<DynamicList>()[3].as<DynamicStruct>().set("f", true); |
| lists.get("list8").as<DynamicList>()[0].as<DynamicStruct>().set("f", 123u); |
| lists.get("list8").as<DynamicList>()[1].as<DynamicStruct>().set("f", 45u); |
| lists.get("list16").as<DynamicList>()[0].as<DynamicStruct>().set("f", 12345u); |
| lists.get("list16").as<DynamicList>()[1].as<DynamicStruct>().set("f", 6789u); |
| lists.get("list32").as<DynamicList>()[0].as<DynamicStruct>().set("f", 123456789u); |
| lists.get("list32").as<DynamicList>()[1].as<DynamicStruct>().set("f", 234567890u); |
| lists.get("list64").as<DynamicList>()[0].as<DynamicStruct>().set("f", 1234567890123456u); |
| lists.get("list64").as<DynamicList>()[1].as<DynamicStruct>().set("f", 2345678901234567u); |
| lists.get("listP").as<DynamicList>()[0].as<DynamicStruct>().set("f", "foo"); |
| lists.get("listP").as<DynamicList>()[1].as<DynamicStruct>().set("f", "bar"); |
| |
| { |
| auto l = lists.init("int32ListList", 3).as<DynamicList>(); |
| l.init(0, 3).as<DynamicList>().copyFrom({1, 2, 3}); |
| l.init(1, 2).as<DynamicList>().copyFrom({4, 5}); |
| l.init(2, 1).as<DynamicList>().copyFrom({12341234}); |
| } |
| |
| { |
| auto l = lists.init("textListList", 3).as<DynamicList>(); |
| l.init(0, 2).as<DynamicList>().copyFrom({"foo", "bar"}); |
| l.init(1, 1).as<DynamicList>().copyFrom({"baz"}); |
| l.init(2, 2).as<DynamicList>().copyFrom({"qux", "corge"}); |
| } |
| |
| { |
| auto l = lists.init("structListList", 2).as<DynamicList>(); |
| auto e = l.init(0, 2).as<DynamicList>(); |
| e[0].as<TestAllTypes>().setInt32Field(123); |
| e[1].as<TestAllTypes>().setInt32Field(456); |
| e = l.init(1, 1).as<DynamicList>(); |
| e[0].as<TestAllTypes>().setInt32Field(789); |
| } |
| } |
| |
| #endif // !CAPNP_LITE |
| |
| template <typename Reader> |
| void genericCheckListDefaults(Reader reader) { |
| auto lists = reader.getLists(); |
| |
| ASSERT_EQ(2u, lists.getList0().size()); |
| ASSERT_EQ(4u, lists.getList1().size()); |
| ASSERT_EQ(2u, lists.getList8().size()); |
| ASSERT_EQ(2u, lists.getList16().size()); |
| ASSERT_EQ(2u, lists.getList32().size()); |
| ASSERT_EQ(2u, lists.getList64().size()); |
| ASSERT_EQ(2u, lists.getListP().size()); |
| |
| EXPECT_EQ(VOID, lists.getList0()[0].getF()); |
| EXPECT_EQ(VOID, lists.getList0()[1].getF()); |
| EXPECT_TRUE(lists.getList1()[0].getF()); |
| EXPECT_FALSE(lists.getList1()[1].getF()); |
| EXPECT_TRUE(lists.getList1()[2].getF()); |
| EXPECT_TRUE(lists.getList1()[3].getF()); |
| EXPECT_EQ(123u, lists.getList8()[0].getF()); |
| EXPECT_EQ(45u, lists.getList8()[1].getF()); |
| EXPECT_EQ(12345u, lists.getList16()[0].getF()); |
| EXPECT_EQ(6789u, lists.getList16()[1].getF()); |
| EXPECT_EQ(123456789u, lists.getList32()[0].getF()); |
| EXPECT_EQ(234567890u, lists.getList32()[1].getF()); |
| EXPECT_EQ(1234567890123456u, lists.getList64()[0].getF()); |
| EXPECT_EQ(2345678901234567u, lists.getList64()[1].getF()); |
| EXPECT_EQ("foo", lists.getListP()[0].getF()); |
| EXPECT_EQ("bar", lists.getListP()[1].getF()); |
| |
| { |
| auto l = lists.getInt32ListList(); |
| ASSERT_EQ(3u, l.size()); |
| checkList(l[0], {1, 2, 3}); |
| checkList(l[1], {4, 5}); |
| checkList(l[2], {12341234}); |
| } |
| |
| { |
| auto l = lists.getTextListList(); |
| ASSERT_EQ(3u, l.size()); |
| checkList(l[0], {"foo", "bar"}); |
| checkList(l[1], {"baz"}); |
| checkList(l[2], {"qux", "corge"}); |
| } |
| |
| { |
| auto l = lists.getStructListList(); |
| ASSERT_EQ(2u, l.size()); |
| auto e = l[0]; |
| ASSERT_EQ(2u, e.size()); |
| EXPECT_EQ(123, e[0].getInt32Field()); |
| EXPECT_EQ(456, e[1].getInt32Field()); |
| e = l[1]; |
| ASSERT_EQ(1u, e.size()); |
| EXPECT_EQ(789, e[0].getInt32Field()); |
| } |
| } |
| |
| #if !CAPNP_LITE |
| |
| // Hack because as<>() is a template-parameter-dependent lookup everywhere below... |
| #define as template as |
| |
| template <typename Reader> |
| void dynamicCheckListDefaults(Reader reader) { |
| auto lists = reader.get("lists").as<DynamicStruct>(); |
| |
| ASSERT_EQ(2u, lists.get("list0").as<DynamicList>().size()); |
| ASSERT_EQ(4u, lists.get("list1").as<DynamicList>().size()); |
| ASSERT_EQ(2u, lists.get("list8").as<DynamicList>().size()); |
| ASSERT_EQ(2u, lists.get("list16").as<DynamicList>().size()); |
| ASSERT_EQ(2u, lists.get("list32").as<DynamicList>().size()); |
| ASSERT_EQ(2u, lists.get("list64").as<DynamicList>().size()); |
| ASSERT_EQ(2u, lists.get("listP").as<DynamicList>().size()); |
| |
| EXPECT_EQ(VOID, lists.get("list0").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<Void>()); |
| EXPECT_EQ(VOID, lists.get("list0").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<Void>()); |
| EXPECT_TRUE(lists.get("list1").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<bool>()); |
| EXPECT_FALSE(lists.get("list1").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<bool>()); |
| EXPECT_TRUE(lists.get("list1").as<DynamicList>()[2].as<DynamicStruct>().get("f").as<bool>()); |
| EXPECT_TRUE(lists.get("list1").as<DynamicList>()[3].as<DynamicStruct>().get("f").as<bool>()); |
| EXPECT_EQ(123u, lists.get("list8").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint8_t>()); |
| EXPECT_EQ(45u, lists.get("list8").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint8_t>()); |
| EXPECT_EQ(12345u, lists.get("list16").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint16_t>()); |
| EXPECT_EQ(6789u, lists.get("list16").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint16_t>()); |
| EXPECT_EQ(123456789u, lists.get("list32").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint32_t>()); |
| EXPECT_EQ(234567890u, lists.get("list32").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint32_t>()); |
| EXPECT_EQ(1234567890123456u, lists.get("list64").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint64_t>()); |
| EXPECT_EQ(2345678901234567u, lists.get("list64").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint64_t>()); |
| EXPECT_EQ("foo", lists.get("listP").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<Text>()); |
| EXPECT_EQ("bar", lists.get("listP").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<Text>()); |
| |
| { |
| auto l = lists.get("int32ListList").as<DynamicList>(); |
| ASSERT_EQ(3u, l.size()); |
| checkList<int32_t>(l[0], {1, 2, 3}); |
| checkList<int32_t>(l[1], {4, 5}); |
| checkList<int32_t>(l[2], {12341234}); |
| } |
| |
| { |
| auto l = lists.get("textListList").as<DynamicList>(); |
| ASSERT_EQ(3u, l.size()); |
| checkList<Text>(l[0], {"foo", "bar"}); |
| checkList<Text>(l[1], {"baz"}); |
| checkList<Text>(l[2], {"qux", "corge"}); |
| } |
| |
| { |
| auto l = lists.get("structListList").as<DynamicList>(); |
| ASSERT_EQ(2u, l.size()); |
| auto e = l[0].as<DynamicList>(); |
| ASSERT_EQ(2u, e.size()); |
| EXPECT_EQ(123, e[0].as<TestAllTypes>().getInt32Field()); |
| EXPECT_EQ(456, e[1].as<TestAllTypes>().getInt32Field()); |
| e = l[1].as<DynamicList>(); |
| ASSERT_EQ(1u, e.size()); |
| EXPECT_EQ(789, e[0].as<TestAllTypes>().getInt32Field()); |
| } |
| } |
| |
| #undef as |
| |
| #endif // !CAPNP_LITE |
| |
| } // namespace |
| |
| void initTestMessage(TestAllTypes::Builder builder) { genericInitTestMessage(builder); } |
| void initTestMessage(TestDefaults::Builder builder) { genericInitTestMessage(builder); } |
| void initTestMessage(TestListDefaults::Builder builder) { genericInitListDefaults(builder); } |
| |
| void checkTestMessage(TestAllTypes::Builder builder) { genericCheckTestMessage(builder); } |
| void checkTestMessage(TestDefaults::Builder builder) { genericCheckTestMessage(builder); } |
| void checkTestMessage(TestListDefaults::Builder builder) { genericCheckListDefaults(builder); } |
| |
| void checkTestMessage(TestAllTypes::Reader reader) { genericCheckTestMessage(reader); } |
| void checkTestMessage(TestDefaults::Reader reader) { genericCheckTestMessage(reader); } |
| void checkTestMessage(TestListDefaults::Reader reader) { genericCheckListDefaults(reader); } |
| |
| void checkTestMessageAllZero(TestAllTypes::Builder builder) { |
| genericCheckTestMessageAllZero(builder); |
| } |
| void checkTestMessageAllZero(TestAllTypes::Reader reader) { |
| genericCheckTestMessageAllZero(reader); |
| } |
| |
| #if !CAPNP_LITE |
| |
| void initDynamicTestMessage(DynamicStruct::Builder builder) { |
| dynamicInitTestMessage(builder); |
| } |
| void initDynamicTestLists(DynamicStruct::Builder builder) { |
| dynamicInitListDefaults(builder); |
| } |
| void checkDynamicTestMessage(DynamicStruct::Builder builder) { |
| dynamicCheckTestMessage(builder); |
| } |
| void checkDynamicTestLists(DynamicStruct::Builder builder) { |
| dynamicCheckListDefaults(builder); |
| } |
| void checkDynamicTestMessage(DynamicStruct::Reader reader) { |
| dynamicCheckTestMessage(reader); |
| } |
| void checkDynamicTestLists(DynamicStruct::Reader reader) { |
| dynamicCheckListDefaults(reader); |
| } |
| void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder) { |
| dynamicCheckTestMessageAllZero(builder); |
| } |
| void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader) { |
| dynamicCheckTestMessageAllZero(reader); |
| } |
| |
| #endif // !CAPNP_LITE |
| |
| // ======================================================================================= |
| // Interface implementations. |
| |
| #if !CAPNP_LITE |
| |
| TestInterfaceImpl::TestInterfaceImpl(int& callCount): callCount(callCount) {} |
| |
| kj::Promise<void> TestInterfaceImpl::foo(FooContext context) { |
| ++callCount; |
| auto params = context.getParams(); |
| auto result = context.getResults(); |
| EXPECT_EQ(123, params.getI()); |
| EXPECT_TRUE(params.getJ()); |
| result.setX("foo"); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestInterfaceImpl::baz(BazContext context) { |
| ++callCount; |
| auto params = context.getParams(); |
| checkTestMessage(params.getS()); |
| context.releaseParams(); |
| EXPECT_ANY_THROW(context.getParams()); |
| |
| return kj::READY_NOW; |
| } |
| |
| TestExtendsImpl::TestExtendsImpl(int& callCount): callCount(callCount) {} |
| |
| kj::Promise<void> TestExtendsImpl::foo(FooContext context) { |
| ++callCount; |
| auto params = context.getParams(); |
| auto result = context.getResults(); |
| EXPECT_EQ(321, params.getI()); |
| EXPECT_FALSE(params.getJ()); |
| result.setX("bar"); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestExtendsImpl::grault(GraultContext context) { |
| ++callCount; |
| context.releaseParams(); |
| |
| initTestMessage(context.getResults()); |
| |
| return kj::READY_NOW; |
| } |
| |
| TestPipelineImpl::TestPipelineImpl(int& callCount): callCount(callCount) {} |
| |
| kj::Promise<void> TestPipelineImpl::getCap(GetCapContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| EXPECT_EQ(234, params.getN()); |
| |
| auto cap = params.getInCap(); |
| context.releaseParams(); |
| |
| auto request = cap.fooRequest(); |
| request.setI(123); |
| request.setJ(true); |
| |
| return request.send().then( |
| [this,KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable { |
| EXPECT_EQ("foo", response.getX()); |
| |
| auto result = context.getResults(); |
| result.setS("bar"); |
| result.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount)); |
| }); |
| } |
| |
| kj::Promise<void> TestPipelineImpl::getAnyCap(GetAnyCapContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| EXPECT_EQ(234, params.getN()); |
| |
| auto cap = params.getInCap(); |
| context.releaseParams(); |
| |
| auto request = cap.castAs<test::TestInterface>().fooRequest(); |
| request.setI(123); |
| request.setJ(true); |
| |
| return request.send().then( |
| [this,KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable { |
| EXPECT_EQ("foo", response.getX()); |
| |
| auto result = context.getResults(); |
| result.setS("bar"); |
| result.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount)); |
| }); |
| } |
| |
| kj::Promise<void> TestPipelineImpl::getCapPipelineOnly(GetCapPipelineOnlyContext context) { |
| ++callCount; |
| PipelineBuilder<GetCapPipelineOnlyResults> pb; |
| pb.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount)); |
| context.setPipeline(pb.build()); |
| return kj::NEVER_DONE; |
| } |
| |
| kj::Promise<void> TestCallOrderImpl::getCallSequence(GetCallSequenceContext context) { |
| auto result = context.getResults(); |
| result.setN(count++); |
| return kj::READY_NOW; |
| } |
| |
| TestTailCallerImpl::TestTailCallerImpl(int& callCount): callCount(callCount) {} |
| |
| kj::Promise<void> TestTailCallerImpl::foo(FooContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| auto tailRequest = params.getCallee().fooRequest(); |
| tailRequest.setI(params.getI()); |
| tailRequest.setT("from TestTailCaller"); |
| return context.tailCall(kj::mv(tailRequest)); |
| } |
| |
| TestTailCalleeImpl::TestTailCalleeImpl(int& callCount): callCount(callCount) {} |
| |
| kj::Promise<void> TestTailCalleeImpl::foo(FooContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| auto results = context.getResults(); |
| |
| results.setI(params.getI()); |
| results.setT(params.getT()); |
| results.setC(kj::heap<TestCallOrderImpl>()); |
| |
| return kj::READY_NOW; |
| } |
| |
| TestMoreStuffImpl::TestMoreStuffImpl(int& callCount, int& handleCount) |
| : callCount(callCount), handleCount(handleCount) {} |
| |
| kj::Promise<void> TestMoreStuffImpl::getCallSequence(GetCallSequenceContext context) { |
| auto result = context.getResults(); |
| result.setN(callCount++); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::callFoo(CallFooContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| auto cap = params.getCap(); |
| |
| auto request = cap.fooRequest(); |
| request.setI(123); |
| request.setJ(true); |
| |
| return request.send().then( |
| [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable { |
| EXPECT_EQ("foo", response.getX()); |
| context.getResults().setS("bar"); |
| }); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::callFooWhenResolved(CallFooWhenResolvedContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| auto cap = params.getCap(); |
| |
| return cap.whenResolved().then([KJ_CPCAP(cap),KJ_CPCAP(context)]() mutable { |
| auto request = cap.fooRequest(); |
| request.setI(123); |
| request.setJ(true); |
| |
| return request.send().then( |
| [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable { |
| EXPECT_EQ("foo", response.getX()); |
| context.getResults().setS("bar"); |
| }); |
| }); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::neverReturn(NeverReturnContext context) { |
| ++callCount; |
| |
| // Attach `cap` to the promise to make sure it is released. |
| auto promise = kj::Promise<void>(kj::NEVER_DONE).attach(context.getParams().getCap()); |
| |
| // Also attach `cap` to the result struct to make sure that is released. |
| context.getResults().setCapCopy(context.getParams().getCap()); |
| |
| context.allowCancellation(); |
| return kj::mv(promise); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::hold(HoldContext context) { |
| ++callCount; |
| |
| auto params = context.getParams(); |
| clientToHold = params.getCap(); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::callHeld(CallHeldContext context) { |
| ++callCount; |
| |
| auto request = clientToHold.fooRequest(); |
| request.setI(123); |
| request.setJ(true); |
| |
| return request.send().then( |
| [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable { |
| EXPECT_EQ("foo", response.getX()); |
| context.getResults().setS("bar"); |
| }); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::getHeld(GetHeldContext context) { |
| ++callCount; |
| auto result = context.getResults(); |
| result.setCap(clientToHold); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::echo(EchoContext context) { |
| ++callCount; |
| auto params = context.getParams(); |
| auto result = context.getResults(); |
| result.setCap(params.getCap()); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::expectCancel(ExpectCancelContext context) { |
| auto cap = context.getParams().getCap(); |
| context.allowCancellation(); |
| return loop(0, cap, context); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::loop(uint depth, test::TestInterface::Client cap, |
| ExpectCancelContext context) { |
| if (depth > 100) { |
| ADD_FAILURE() << "Looped too long, giving up."; |
| return kj::READY_NOW; |
| } else { |
| return kj::evalLater([this,depth,KJ_CPCAP(cap),KJ_CPCAP(context)]() mutable { |
| return loop(depth + 1, cap, context); |
| }); |
| } |
| } |
| |
| class HandleImpl final: public test::TestHandle::Server { |
| public: |
| HandleImpl(int& count): count(count) { ++count; } |
| ~HandleImpl() { --count; } |
| |
| private: |
| int& count; |
| }; |
| |
| kj::Promise<void> TestMoreStuffImpl::getHandle(GetHandleContext context) { |
| context.getResults().setHandle(kj::heap<HandleImpl>(handleCount)); |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::getNull(GetNullContext context) { |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::getEnormousString(GetEnormousStringContext context) { |
| context.getResults().initStr(100000000); // 100MB |
| return kj::READY_NOW; |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::writeToFd(WriteToFdContext context) { |
| auto params = context.getParams(); |
| |
| auto promises = kj::heapArrayBuilder<kj::Promise<void>>(2); |
| |
| promises.add(params.getFdCap1().getFd() |
| .then([](kj::Maybe<int> fd) { |
| kj::FdOutputStream(KJ_ASSERT_NONNULL(fd)).write("foo", 3); |
| })); |
| promises.add(params.getFdCap2().getFd() |
| .then([context](kj::Maybe<int> fd) mutable { |
| context.getResults().setSecondFdPresent(fd != nullptr); |
| KJ_IF_MAYBE(f, fd) { |
| kj::FdOutputStream(*f).write("bar", 3); |
| } |
| })); |
| |
| int pair[2]; |
| KJ_SYSCALL(kj::miniposix::pipe(pair)); |
| kj::AutoCloseFd in(pair[0]); |
| kj::AutoCloseFd out(pair[1]); |
| |
| kj::FdOutputStream(kj::mv(out)).write("baz", 3); |
| context.getResults().setFdCap3(kj::heap<TestFdCap>(kj::mv(in))); |
| |
| return kj::joinPromises(promises.finish()); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::throwException(ThrowExceptionContext context) { |
| return KJ_EXCEPTION(FAILED, "test exception"); |
| } |
| |
| kj::Promise<void> TestMoreStuffImpl::throwRemoteException(ThrowRemoteExceptionContext context) { |
| return KJ_EXCEPTION(FAILED, "remote exception: test exception"); |
| } |
| |
| #endif // !CAPNP_LITE |
| |
| } // namespace _ (private) |
| } // namespace capnp |