capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

test-util.c++ (48956B)


      1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 #ifndef _GNU_SOURCE
     23 #define _GNU_SOURCE
     24 #endif
     25 
     26 #include "test-util.h"
     27 #include <kj/debug.h>
     28 #include <kj/compat/gtest.h>
     29 #include <kj/io.h>
     30 #include <kj/miniposix.h>
     31 
     32 namespace capnp {
     33 namespace _ {  // private
     34 namespace {
     35 
     36 template <typename Builder>
     37 void genericInitTestMessage(Builder builder) {
     38   builder.setVoidField(VOID);
     39   builder.setVoidField();  // Means the same as above.
     40   builder.setBoolField(true);
     41   builder.setInt8Field(-123);
     42   builder.setInt16Field(-12345);
     43   builder.setInt32Field(-12345678);
     44   builder.setInt64Field(-123456789012345ll);
     45   builder.setUInt8Field(234u);
     46   builder.setUInt16Field(45678u);
     47   builder.setUInt32Field(3456789012u);
     48   builder.setUInt64Field(12345678901234567890ull);
     49   builder.setFloat32Field(1234.5);
     50   builder.setFloat64Field(-123e45);
     51   builder.setTextField("foo");
     52   builder.setDataField(data("bar"));
     53   {
     54     auto subBuilder = builder.initStructField();
     55     subBuilder.setVoidField(VOID);
     56     subBuilder.setBoolField(true);
     57     subBuilder.setInt8Field(-12);
     58     subBuilder.setInt16Field(3456);
     59     subBuilder.setInt32Field(-78901234);
     60     subBuilder.setInt64Field(56789012345678ll);
     61     subBuilder.setUInt8Field(90u);
     62     subBuilder.setUInt16Field(1234u);
     63     subBuilder.setUInt32Field(56789012u);
     64     subBuilder.setUInt64Field(345678901234567890ull);
     65     subBuilder.setFloat32Field(-1.25e-10f);
     66     subBuilder.setFloat64Field(345);
     67     subBuilder.setTextField("baz");
     68     subBuilder.setDataField(data("qux"));
     69     {
     70       auto subSubBuilder = subBuilder.initStructField();
     71       subSubBuilder.setTextField("nested");
     72       subSubBuilder.initStructField().setTextField("really nested");
     73     }
     74     subBuilder.setEnumField(TestEnum::BAZ);
     75 
     76     subBuilder.setVoidList({VOID, VOID, VOID});
     77     subBuilder.setBoolList({false, true, false, true, true});
     78     subBuilder.setInt8List({12, -34, -0x80, 0x7f});
     79     subBuilder.setInt16List({1234, -5678, -0x8000, 0x7fff});
     80     // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1.
     81     subBuilder.setInt32List({12345678, -90123456, -0x7fffffff - 1, 0x7fffffff});
     82     subBuilder.setInt64List({123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll});
     83     subBuilder.setUInt8List({12u, 34u, 0u, 0xffu});
     84     subBuilder.setUInt16List({1234u, 5678u, 0u, 0xffffu});
     85     subBuilder.setUInt32List({12345678u, 90123456u, 0u, 0xffffffffu});
     86     subBuilder.setUInt64List({123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull});
     87     subBuilder.setFloat32List({0, 1234567, 1e37f, -1e37f, 1e-37f, -1e-37f});
     88     subBuilder.setFloat64List({0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306});
     89     subBuilder.setTextList({"quux", "corge", "grault"});
     90     subBuilder.setDataList({data("garply"), data("waldo"), data("fred")});
     91     {
     92       auto listBuilder = subBuilder.initStructList(3);
     93       listBuilder[0].setTextField("x structlist 1");
     94       listBuilder[1].setTextField("x structlist 2");
     95       listBuilder[2].setTextField("x structlist 3");
     96     }
     97     subBuilder.setEnumList({TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT});
     98   }
     99   builder.setEnumField(TestEnum::CORGE);
    100 
    101   builder.initVoidList(6);
    102   builder.setBoolList({true, false, false, true});
    103   builder.setInt8List({111, -111});
    104   builder.setInt16List({11111, -11111});
    105   builder.setInt32List({111111111, -111111111});
    106   builder.setInt64List({1111111111111111111ll, -1111111111111111111ll});
    107   builder.setUInt8List({111u, 222u});
    108   builder.setUInt16List({33333u, 44444u});
    109   builder.setUInt32List({3333333333u});
    110   builder.setUInt64List({11111111111111111111ull});
    111   builder.setFloat32List({5555.5, kj::inf(), -kj::inf(), kj::nan()});
    112   builder.setFloat64List({7777.75, kj::inf(), -kj::inf(), kj::nan()});
    113   builder.setTextList({"plugh", "xyzzy", "thud"});
    114   builder.setDataList({data("oops"), data("exhausted"), data("rfc3092")});
    115   {
    116     auto listBuilder = builder.initStructList(3);
    117     listBuilder[0].setTextField("structlist 1");
    118     listBuilder[1].setTextField("structlist 2");
    119     listBuilder[2].setTextField("structlist 3");
    120   }
    121   builder.setEnumList({TestEnum::FOO, TestEnum::GARPLY});
    122 }
    123 
    124 #if !CAPNP_LITE
    125 
    126 void dynamicInitTestMessage(DynamicStruct::Builder builder) {
    127   builder.set("voidField", VOID);
    128   builder.set("boolField", true);
    129   builder.set("int8Field", -123);
    130   builder.set("int16Field", -12345);
    131   builder.set("int32Field", -12345678);
    132   builder.set("int64Field", -123456789012345ll);
    133   builder.set("uInt8Field", 234u);
    134   builder.set("uInt16Field", 45678u);
    135   builder.set("uInt32Field", 3456789012u);
    136   builder.set("uInt64Field", 12345678901234567890ull);
    137   builder.set("float32Field", 1234.5);
    138   builder.set("float64Field", -123e45);
    139   builder.set("textField", "foo");
    140   builder.set("dataField", data("bar"));
    141   {
    142     auto subBuilder = builder.init("structField").as<DynamicStruct>();
    143     subBuilder.set("voidField", VOID);
    144     subBuilder.set("boolField", true);
    145     subBuilder.set("int8Field", -12);
    146     subBuilder.set("int16Field", 3456);
    147     subBuilder.set("int32Field", -78901234);
    148     subBuilder.set("int64Field", 56789012345678ll);
    149     subBuilder.set("uInt8Field", 90u);
    150     subBuilder.set("uInt16Field", 1234u);
    151     subBuilder.set("uInt32Field", 56789012u);
    152     subBuilder.set("uInt64Field", 345678901234567890ull);
    153     subBuilder.set("float32Field", -1.25e-10);
    154     subBuilder.set("float64Field", 345);
    155     subBuilder.set("textField", "baz");
    156     subBuilder.set("dataField", data("qux"));
    157     {
    158       auto subSubBuilder = subBuilder.init("structField").as<DynamicStruct>();
    159       subSubBuilder.set("textField", "nested");
    160       subSubBuilder.init("structField").as<DynamicStruct>().set("textField", "really nested");
    161     }
    162     subBuilder.set("enumField", "baz");
    163 
    164     subBuilder.set("voidList", {VOID, VOID, VOID});
    165     subBuilder.set("boolList", {false, true, false, true, true});
    166     subBuilder.set("int8List", {12, -34, -0x80, 0x7f});
    167     subBuilder.set("int16List", {1234, -5678, -0x8000, 0x7fff});
    168     // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1.
    169     subBuilder.set("int32List", {12345678, -90123456, -0x7fffffff - 1, 0x7fffffff});
    170     subBuilder.set("int64List", {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll});
    171     subBuilder.set("uInt8List", {12u, 34u, 0u, 0xffu});
    172     subBuilder.set("uInt16List", {1234u, 5678u, 0u, 0xffffu});
    173     subBuilder.set("uInt32List", {12345678u, 90123456u, 0u, 0xffffffffu});
    174     subBuilder.set("uInt64List", {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull});
    175     subBuilder.set("float32List", {0, 1234567, 1e37, -1e37, 1e-37, -1e-37});
    176     subBuilder.set("float64List", {0, 123456789012345, 1e306, -1e306, 1e-306, -1e-306});
    177     subBuilder.set("textList", {"quux", "corge", "grault"});
    178     subBuilder.set("dataList", {data("garply"), data("waldo"), data("fred")});
    179     {
    180       auto listBuilder = subBuilder.init("structList", 3).as<DynamicList>();
    181       listBuilder[0].as<DynamicStruct>().set("textField", "x structlist 1");
    182       listBuilder[1].as<DynamicStruct>().set("textField", "x structlist 2");
    183       listBuilder[2].as<DynamicStruct>().set("textField", "x structlist 3");
    184     }
    185     subBuilder.set("enumList", {"qux", "bar", "grault"});
    186   }
    187   builder.set("enumField", "corge");
    188 
    189   builder.init("voidList", 6);
    190   builder.set("boolList", {true, false, false, true});
    191   builder.set("int8List", {111, -111});
    192   builder.set("int16List", {11111, -11111});
    193   builder.set("int32List", {111111111, -111111111});
    194   builder.set("int64List", {1111111111111111111ll, -1111111111111111111ll});
    195   builder.set("uInt8List", {111u, 222u});
    196   builder.set("uInt16List", {33333u, 44444u});
    197   builder.set("uInt32List", {3333333333u});
    198   builder.set("uInt64List", {11111111111111111111ull});
    199   builder.set("float32List", {5555.5, kj::inf(), -kj::inf(), kj::nan()});
    200   builder.set("float64List", {7777.75, kj::inf(), -kj::inf(), kj::nan()});
    201   builder.set("textList", {"plugh", "xyzzy", "thud"});
    202   builder.set("dataList", {data("oops"), data("exhausted"), data("rfc3092")});
    203   {
    204     auto listBuilder = builder.init("structList", 3).as<DynamicList>();
    205     listBuilder[0].as<DynamicStruct>().set("textField", "structlist 1");
    206     listBuilder[1].as<DynamicStruct>().set("textField", "structlist 2");
    207     listBuilder[2].as<DynamicStruct>().set("textField", "structlist 3");
    208   }
    209   builder.set("enumList", {"foo", "garply"});
    210 }
    211 
    212 #endif  // !CAPNP_LITE
    213 
    214 inline bool isNaN(float f) { return f != f; }
    215 inline bool isNaN(double f) { return f != f; }
    216 
    217 template <typename Reader>
    218 void genericCheckTestMessage(Reader reader) {
    219   EXPECT_EQ(VOID, reader.getVoidField());
    220   EXPECT_EQ(true, reader.getBoolField());
    221   EXPECT_EQ(-123, reader.getInt8Field());
    222   EXPECT_EQ(-12345, reader.getInt16Field());
    223   EXPECT_EQ(-12345678, reader.getInt32Field());
    224   EXPECT_EQ(-123456789012345ll, reader.getInt64Field());
    225   EXPECT_EQ(234u, reader.getUInt8Field());
    226   EXPECT_EQ(45678u, reader.getUInt16Field());
    227   EXPECT_EQ(3456789012u, reader.getUInt32Field());
    228   EXPECT_EQ(12345678901234567890ull, reader.getUInt64Field());
    229   EXPECT_FLOAT_EQ(1234.5f, reader.getFloat32Field());
    230   EXPECT_DOUBLE_EQ(-123e45, reader.getFloat64Field());
    231   EXPECT_EQ("foo", reader.getTextField());
    232   EXPECT_EQ(data("bar"), reader.getDataField());
    233   {
    234     auto subReader = reader.getStructField();
    235     EXPECT_EQ(VOID, subReader.getVoidField());
    236     EXPECT_EQ(true, subReader.getBoolField());
    237     EXPECT_EQ(-12, subReader.getInt8Field());
    238     EXPECT_EQ(3456, subReader.getInt16Field());
    239     EXPECT_EQ(-78901234, subReader.getInt32Field());
    240     EXPECT_EQ(56789012345678ll, subReader.getInt64Field());
    241     EXPECT_EQ(90u, subReader.getUInt8Field());
    242     EXPECT_EQ(1234u, subReader.getUInt16Field());
    243     EXPECT_EQ(56789012u, subReader.getUInt32Field());
    244     EXPECT_EQ(345678901234567890ull, subReader.getUInt64Field());
    245     EXPECT_FLOAT_EQ(-1.25e-10f, subReader.getFloat32Field());
    246     EXPECT_DOUBLE_EQ(345, subReader.getFloat64Field());
    247     EXPECT_EQ("baz", subReader.getTextField());
    248     EXPECT_EQ(data("qux"), subReader.getDataField());
    249     {
    250       auto subSubReader = subReader.getStructField();
    251       EXPECT_EQ("nested", subSubReader.getTextField());
    252       EXPECT_EQ("really nested", subSubReader.getStructField().getTextField());
    253     }
    254     EXPECT_EQ(TestEnum::BAZ, subReader.getEnumField());
    255 
    256     checkList(subReader.getVoidList(), {VOID, VOID, VOID});
    257     checkList(subReader.getBoolList(), {false, true, false, true, true});
    258     checkList(subReader.getInt8List(), {12, -34, -0x80, 0x7f});
    259     checkList(subReader.getInt16List(), {1234, -5678, -0x8000, 0x7fff});
    260     // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1.
    261     checkList(subReader.getInt32List(), {12345678, -90123456, -0x7fffffff - 1, 0x7fffffff});
    262     checkList(subReader.getInt64List(), {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll});
    263     checkList(subReader.getUInt8List(), {12u, 34u, 0u, 0xffu});
    264     checkList(subReader.getUInt16List(), {1234u, 5678u, 0u, 0xffffu});
    265     checkList(subReader.getUInt32List(), {12345678u, 90123456u, 0u, 0xffffffffu});
    266     checkList(subReader.getUInt64List(), {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull});
    267     checkList(subReader.getFloat32List(), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f});
    268     checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306});
    269     checkList(subReader.getTextList(), {"quux", "corge", "grault"});
    270     checkList(subReader.getDataList(), {data("garply"), data("waldo"), data("fred")});
    271     {
    272       auto listReader = subReader.getStructList();
    273       ASSERT_EQ(3u, listReader.size());
    274       EXPECT_EQ("x structlist 1", listReader[0].getTextField());
    275       EXPECT_EQ("x structlist 2", listReader[1].getTextField());
    276       EXPECT_EQ("x structlist 3", listReader[2].getTextField());
    277     }
    278     checkList(subReader.getEnumList(), {TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT});
    279   }
    280   EXPECT_EQ(TestEnum::CORGE, reader.getEnumField());
    281 
    282   EXPECT_EQ(6u, reader.getVoidList().size());
    283   checkList(reader.getBoolList(), {true, false, false, true});
    284   checkList(reader.getInt8List(), {111, -111});
    285   checkList(reader.getInt16List(), {11111, -11111});
    286   checkList(reader.getInt32List(), {111111111, -111111111});
    287   checkList(reader.getInt64List(), {1111111111111111111ll, -1111111111111111111ll});
    288   checkList(reader.getUInt8List(), {111u, 222u});
    289   checkList(reader.getUInt16List(), {33333u, 44444u});
    290   checkList(reader.getUInt32List(), {3333333333u});
    291   checkList(reader.getUInt64List(), {11111111111111111111ull});
    292   {
    293     auto listReader = reader.getFloat32List();
    294     ASSERT_EQ(4u, listReader.size());
    295     EXPECT_EQ(5555.5f, listReader[0]);
    296     EXPECT_EQ(kj::inf(), listReader[1]);
    297     EXPECT_EQ(-kj::inf(), listReader[2]);
    298     EXPECT_TRUE(isNaN(listReader[3]));
    299   }
    300   {
    301     auto listReader = reader.getFloat64List();
    302     ASSERT_EQ(4u, listReader.size());
    303     EXPECT_EQ(7777.75, listReader[0]);
    304     EXPECT_EQ(kj::inf(), listReader[1]);
    305     EXPECT_EQ(-kj::inf(), listReader[2]);
    306     EXPECT_TRUE(isNaN(listReader[3]));
    307   }
    308   checkList(reader.getTextList(), {"plugh", "xyzzy", "thud"});
    309   checkList(reader.getDataList(), {data("oops"), data("exhausted"), data("rfc3092")});
    310   {
    311     auto listReader = reader.getStructList();
    312     ASSERT_EQ(3u, listReader.size());
    313     EXPECT_EQ("structlist 1", listReader[0].getTextField());
    314     EXPECT_EQ("structlist 2", listReader[1].getTextField());
    315     EXPECT_EQ("structlist 3", listReader[2].getTextField());
    316   }
    317   checkList(reader.getEnumList(), {TestEnum::FOO, TestEnum::GARPLY});
    318 }
    319 
    320 #if !CAPNP_LITE
    321 
    322 // Hack because as<>() is a template-parameter-dependent lookup everywhere below...
    323 #define as template as
    324 
    325 Text::Reader name(DynamicEnum e) {
    326   KJ_IF_MAYBE(schema, e.getEnumerant()) {
    327     return schema->getProto().getName();
    328   } else {
    329     return "(unknown enumerant)";
    330   }
    331 }
    332 
    333 template <typename T>
    334 void checkEnumList(T reader, std::initializer_list<const char*> expected) {
    335   auto list = reader.as<DynamicList>();
    336   ASSERT_EQ(expected.size(), list.size());
    337   for (uint i = 0; i < expected.size(); i++) {
    338     EXPECT_EQ(expected.begin()[i], name(list[i].as<DynamicEnum>()));
    339   }
    340 }
    341 
    342 template <typename Reader>
    343 void dynamicCheckTestMessage(Reader reader) {
    344   EXPECT_EQ(VOID, reader.get("voidField").as<Void>());
    345   EXPECT_EQ(true, reader.get("boolField").as<bool>());
    346   EXPECT_EQ(-123, reader.get("int8Field").as<int8_t>());
    347   EXPECT_EQ(-12345, reader.get("int16Field").as<int16_t>());
    348   EXPECT_EQ(-12345678, reader.get("int32Field").as<int32_t>());
    349   EXPECT_EQ(-123456789012345ll, reader.get("int64Field").as<int64_t>());
    350   EXPECT_EQ(234u, reader.get("uInt8Field").as<uint8_t>());
    351   EXPECT_EQ(45678u, reader.get("uInt16Field").as<uint16_t>());
    352   EXPECT_EQ(3456789012u, reader.get("uInt32Field").as<uint32_t>());
    353   EXPECT_EQ(12345678901234567890ull, reader.get("uInt64Field").as<uint64_t>());
    354   EXPECT_FLOAT_EQ(1234.5f, reader.get("float32Field").as<float>());
    355   EXPECT_DOUBLE_EQ(-123e45, reader.get("float64Field").as<double>());
    356   EXPECT_EQ("foo", reader.get("textField").as<Text>());
    357   EXPECT_EQ(data("bar"), reader.get("dataField").as<Data>());
    358   {
    359     auto subReader = reader.get("structField").as<DynamicStruct>();
    360     EXPECT_EQ(VOID, subReader.get("voidField").as<Void>());
    361     EXPECT_EQ(true, subReader.get("boolField").as<bool>());
    362     EXPECT_EQ(-12, subReader.get("int8Field").as<int8_t>());
    363     EXPECT_EQ(3456, subReader.get("int16Field").as<int16_t>());
    364     EXPECT_EQ(-78901234, subReader.get("int32Field").as<int32_t>());
    365     EXPECT_EQ(56789012345678ll, subReader.get("int64Field").as<int64_t>());
    366     EXPECT_EQ(90u, subReader.get("uInt8Field").as<uint8_t>());
    367     EXPECT_EQ(1234u, subReader.get("uInt16Field").as<uint16_t>());
    368     EXPECT_EQ(56789012u, subReader.get("uInt32Field").as<uint32_t>());
    369     EXPECT_EQ(345678901234567890ull, subReader.get("uInt64Field").as<uint64_t>());
    370     EXPECT_FLOAT_EQ(-1.25e-10f, subReader.get("float32Field").as<float>());
    371     EXPECT_DOUBLE_EQ(345, subReader.get("float64Field").as<double>());
    372     EXPECT_EQ("baz", subReader.get("textField").as<Text>());
    373     EXPECT_EQ(data("qux"), subReader.get("dataField").as<Data>());
    374     {
    375       auto subSubReader = subReader.get("structField").as<DynamicStruct>();
    376       EXPECT_EQ("nested", subSubReader.get("textField").as<Text>());
    377       EXPECT_EQ("really nested", subSubReader.get("structField").as<DynamicStruct>()
    378                                              .get("textField").as<Text>());
    379     }
    380     EXPECT_EQ("baz", name(subReader.get("enumField").as<DynamicEnum>()));
    381 
    382     checkList<Void>(subReader.get("voidList"), {VOID, VOID, VOID});
    383     checkList<bool>(subReader.get("boolList"), {false, true, false, true, true});
    384     checkList<int8_t>(subReader.get("int8List"), {12, -34, -0x80, 0x7f});
    385     checkList<int16_t>(subReader.get("int16List"), {1234, -5678, -0x8000, 0x7fff});
    386     // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1.
    387     checkList<int32_t>(subReader.get("int32List"), {12345678, -90123456, -0x7fffffff-1, 0x7fffffff});
    388     checkList<int64_t>(subReader.get("int64List"), {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll});
    389     checkList<uint8_t>(subReader.get("uInt8List"), {12u, 34u, 0u, 0xffu});
    390     checkList<uint16_t>(subReader.get("uInt16List"), {1234u, 5678u, 0u, 0xffffu});
    391     checkList<uint32_t>(subReader.get("uInt32List"), {12345678u, 90123456u, 0u, 0xffffffffu});
    392     checkList<uint64_t>(subReader.get("uInt64List"), {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull});
    393     checkList<float>(subReader.get("float32List"), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f});
    394     checkList<double>(subReader.get("float64List"), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306});
    395     checkList<Text>(subReader.get("textList"), {"quux", "corge", "grault"});
    396     checkList<Data>(subReader.get("dataList"), {data("garply"), data("waldo"), data("fred")});
    397     {
    398       auto listReader = subReader.get("structList").as<DynamicList>();
    399       ASSERT_EQ(3u, listReader.size());
    400       EXPECT_EQ("x structlist 1", listReader[0].as<DynamicStruct>().get("textField").as<Text>());
    401       EXPECT_EQ("x structlist 2", listReader[1].as<DynamicStruct>().get("textField").as<Text>());
    402       EXPECT_EQ("x structlist 3", listReader[2].as<DynamicStruct>().get("textField").as<Text>());
    403     }
    404     checkEnumList(subReader.get("enumList"), {"qux", "bar", "grault"});
    405   }
    406   EXPECT_EQ("corge", name(reader.get("enumField").as<DynamicEnum>()));
    407 
    408   EXPECT_EQ(6u, reader.get("voidList").as<DynamicList>().size());
    409   checkList<bool>(reader.get("boolList"), {true, false, false, true});
    410   checkList<int8_t>(reader.get("int8List"), {111, -111});
    411   checkList<int16_t>(reader.get("int16List"), {11111, -11111});
    412   checkList<int32_t>(reader.get("int32List"), {111111111, -111111111});
    413   checkList<int64_t>(reader.get("int64List"), {1111111111111111111ll, -1111111111111111111ll});
    414   checkList<uint8_t>(reader.get("uInt8List"), {111u, 222u});
    415   checkList<uint16_t>(reader.get("uInt16List"), {33333u, 44444u});
    416   checkList<uint32_t>(reader.get("uInt32List"), {3333333333u});
    417   checkList<uint64_t>(reader.get("uInt64List"), {11111111111111111111ull});
    418   {
    419     auto listReader = reader.get("float32List").as<DynamicList>();
    420     ASSERT_EQ(4u, listReader.size());
    421     EXPECT_EQ(5555.5f, listReader[0].as<float>());
    422     EXPECT_EQ(kj::inf(), listReader[1].as<float>());
    423     EXPECT_EQ(-kj::inf(), listReader[2].as<float>());
    424     EXPECT_TRUE(isNaN(listReader[3].as<float>()));
    425   }
    426   {
    427     auto listReader = reader.get("float64List").as<DynamicList>();
    428     ASSERT_EQ(4u, listReader.size());
    429     EXPECT_EQ(7777.75, listReader[0].as<double>());
    430     EXPECT_EQ(kj::inf(), listReader[1].as<double>());
    431     EXPECT_EQ(-kj::inf(), listReader[2].as<double>());
    432     EXPECT_TRUE(isNaN(listReader[3].as<double>()));
    433   }
    434   checkList<Text>(reader.get("textList"), {"plugh", "xyzzy", "thud"});
    435   checkList<Data>(reader.get("dataList"), {data("oops"), data("exhausted"), data("rfc3092")});
    436   {
    437     auto listReader = reader.get("structList").as<DynamicList>();
    438     ASSERT_EQ(3u, listReader.size());
    439     EXPECT_EQ("structlist 1", listReader[0].as<DynamicStruct>().get("textField").as<Text>());
    440     EXPECT_EQ("structlist 2", listReader[1].as<DynamicStruct>().get("textField").as<Text>());
    441     EXPECT_EQ("structlist 3", listReader[2].as<DynamicStruct>().get("textField").as<Text>());
    442   }
    443   checkEnumList(reader.get("enumList"), {"foo", "garply"});
    444 }
    445 
    446 #undef as
    447 
    448 #endif  // !CAPNP_LITE
    449 
    450 template <typename Reader>
    451 void genericCheckTestMessageAllZero(Reader reader) {
    452   EXPECT_EQ(VOID, reader.getVoidField());
    453   EXPECT_EQ(false, reader.getBoolField());
    454   EXPECT_EQ(0, reader.getInt8Field());
    455   EXPECT_EQ(0, reader.getInt16Field());
    456   EXPECT_EQ(0, reader.getInt32Field());
    457   EXPECT_EQ(0, reader.getInt64Field());
    458   EXPECT_EQ(0u, reader.getUInt8Field());
    459   EXPECT_EQ(0u, reader.getUInt16Field());
    460   EXPECT_EQ(0u, reader.getUInt32Field());
    461   EXPECT_EQ(0u, reader.getUInt64Field());
    462   EXPECT_FLOAT_EQ(0, reader.getFloat32Field());
    463   EXPECT_DOUBLE_EQ(0, reader.getFloat64Field());
    464   EXPECT_EQ("", reader.getTextField());
    465   EXPECT_EQ(data(""), reader.getDataField());
    466   {
    467     auto subReader = reader.getStructField();
    468     EXPECT_EQ(VOID, subReader.getVoidField());
    469     EXPECT_EQ(false, subReader.getBoolField());
    470     EXPECT_EQ(0, subReader.getInt8Field());
    471     EXPECT_EQ(0, subReader.getInt16Field());
    472     EXPECT_EQ(0, subReader.getInt32Field());
    473     EXPECT_EQ(0, subReader.getInt64Field());
    474     EXPECT_EQ(0u, subReader.getUInt8Field());
    475     EXPECT_EQ(0u, subReader.getUInt16Field());
    476     EXPECT_EQ(0u, subReader.getUInt32Field());
    477     EXPECT_EQ(0u, subReader.getUInt64Field());
    478     EXPECT_FLOAT_EQ(0, subReader.getFloat32Field());
    479     EXPECT_DOUBLE_EQ(0, subReader.getFloat64Field());
    480     EXPECT_EQ("", subReader.getTextField());
    481     EXPECT_EQ(data(""), subReader.getDataField());
    482     {
    483       auto subSubReader = subReader.getStructField();
    484       EXPECT_EQ("", subSubReader.getTextField());
    485       EXPECT_EQ("", subSubReader.getStructField().getTextField());
    486     }
    487 
    488     EXPECT_EQ(0u, subReader.getVoidList().size());
    489     EXPECT_EQ(0u, subReader.getBoolList().size());
    490     EXPECT_EQ(0u, subReader.getInt8List().size());
    491     EXPECT_EQ(0u, subReader.getInt16List().size());
    492     EXPECT_EQ(0u, subReader.getInt32List().size());
    493     EXPECT_EQ(0u, subReader.getInt64List().size());
    494     EXPECT_EQ(0u, subReader.getUInt8List().size());
    495     EXPECT_EQ(0u, subReader.getUInt16List().size());
    496     EXPECT_EQ(0u, subReader.getUInt32List().size());
    497     EXPECT_EQ(0u, subReader.getUInt64List().size());
    498     EXPECT_EQ(0u, subReader.getFloat32List().size());
    499     EXPECT_EQ(0u, subReader.getFloat64List().size());
    500     EXPECT_EQ(0u, subReader.getTextList().size());
    501     EXPECT_EQ(0u, subReader.getDataList().size());
    502     EXPECT_EQ(0u, subReader.getStructList().size());
    503   }
    504 
    505   EXPECT_EQ(0u, reader.getVoidList().size());
    506   EXPECT_EQ(0u, reader.getBoolList().size());
    507   EXPECT_EQ(0u, reader.getInt8List().size());
    508   EXPECT_EQ(0u, reader.getInt16List().size());
    509   EXPECT_EQ(0u, reader.getInt32List().size());
    510   EXPECT_EQ(0u, reader.getInt64List().size());
    511   EXPECT_EQ(0u, reader.getUInt8List().size());
    512   EXPECT_EQ(0u, reader.getUInt16List().size());
    513   EXPECT_EQ(0u, reader.getUInt32List().size());
    514   EXPECT_EQ(0u, reader.getUInt64List().size());
    515   EXPECT_EQ(0u, reader.getFloat32List().size());
    516   EXPECT_EQ(0u, reader.getFloat64List().size());
    517   EXPECT_EQ(0u, reader.getTextList().size());
    518   EXPECT_EQ(0u, reader.getDataList().size());
    519   EXPECT_EQ(0u, reader.getStructList().size());
    520 }
    521 
    522 #if !CAPNP_LITE
    523 
    524 // Hack because as<>() is a template-parameter-dependent lookup everywhere below...
    525 #define as template as
    526 
    527 template <typename Reader>
    528 void dynamicCheckTestMessageAllZero(Reader reader) {
    529   EXPECT_EQ(VOID, reader.get("voidField").as<Void>());
    530   EXPECT_EQ(false, reader.get("boolField").as<bool>());
    531   EXPECT_EQ(0, reader.get("int8Field").as<int8_t>());
    532   EXPECT_EQ(0, reader.get("int16Field").as<int16_t>());
    533   EXPECT_EQ(0, reader.get("int32Field").as<int32_t>());
    534   EXPECT_EQ(0, reader.get("int64Field").as<int64_t>());
    535   EXPECT_EQ(0u, reader.get("uInt8Field").as<uint8_t>());
    536   EXPECT_EQ(0u, reader.get("uInt16Field").as<uint16_t>());
    537   EXPECT_EQ(0u, reader.get("uInt32Field").as<uint32_t>());
    538   EXPECT_EQ(0u, reader.get("uInt64Field").as<uint64_t>());
    539   EXPECT_FLOAT_EQ(0, reader.get("float32Field").as<float>());
    540   EXPECT_DOUBLE_EQ(0, reader.get("float64Field").as<double>());
    541   EXPECT_EQ("", reader.get("textField").as<Text>());
    542   EXPECT_EQ(data(""), reader.get("dataField").as<Data>());
    543   {
    544     auto subReader = reader.get("structField").as<DynamicStruct>();
    545     EXPECT_EQ(VOID, subReader.get("voidField").as<Void>());
    546     EXPECT_EQ(false, subReader.get("boolField").as<bool>());
    547     EXPECT_EQ(0, subReader.get("int8Field").as<int8_t>());
    548     EXPECT_EQ(0, subReader.get("int16Field").as<int16_t>());
    549     EXPECT_EQ(0, subReader.get("int32Field").as<int32_t>());
    550     EXPECT_EQ(0, subReader.get("int64Field").as<int64_t>());
    551     EXPECT_EQ(0u, subReader.get("uInt8Field").as<uint8_t>());
    552     EXPECT_EQ(0u, subReader.get("uInt16Field").as<uint16_t>());
    553     EXPECT_EQ(0u, subReader.get("uInt32Field").as<uint32_t>());
    554     EXPECT_EQ(0u, subReader.get("uInt64Field").as<uint64_t>());
    555     EXPECT_FLOAT_EQ(0, subReader.get("float32Field").as<float>());
    556     EXPECT_DOUBLE_EQ(0, subReader.get("float64Field").as<double>());
    557     EXPECT_EQ("", subReader.get("textField").as<Text>());
    558     EXPECT_EQ(data(""), subReader.get("dataField").as<Data>());
    559     {
    560       auto subSubReader = subReader.get("structField").as<DynamicStruct>();
    561       EXPECT_EQ("", subSubReader.get("textField").as<Text>());
    562       EXPECT_EQ("", subSubReader.get("structField").as<DynamicStruct>()
    563                                 .get("textField").as<Text>());
    564     }
    565 
    566     EXPECT_EQ(0u, subReader.get("voidList").as<DynamicList>().size());
    567     EXPECT_EQ(0u, subReader.get("boolList").as<DynamicList>().size());
    568     EXPECT_EQ(0u, subReader.get("int8List").as<DynamicList>().size());
    569     EXPECT_EQ(0u, subReader.get("int16List").as<DynamicList>().size());
    570     EXPECT_EQ(0u, subReader.get("int32List").as<DynamicList>().size());
    571     EXPECT_EQ(0u, subReader.get("int64List").as<DynamicList>().size());
    572     EXPECT_EQ(0u, subReader.get("uInt8List").as<DynamicList>().size());
    573     EXPECT_EQ(0u, subReader.get("uInt16List").as<DynamicList>().size());
    574     EXPECT_EQ(0u, subReader.get("uInt32List").as<DynamicList>().size());
    575     EXPECT_EQ(0u, subReader.get("uInt64List").as<DynamicList>().size());
    576     EXPECT_EQ(0u, subReader.get("float32List").as<DynamicList>().size());
    577     EXPECT_EQ(0u, subReader.get("float64List").as<DynamicList>().size());
    578     EXPECT_EQ(0u, subReader.get("textList").as<DynamicList>().size());
    579     EXPECT_EQ(0u, subReader.get("dataList").as<DynamicList>().size());
    580     EXPECT_EQ(0u, subReader.get("structList").as<DynamicList>().size());
    581   }
    582 
    583   EXPECT_EQ(0u, reader.get("voidList").as<DynamicList>().size());
    584   EXPECT_EQ(0u, reader.get("boolList").as<DynamicList>().size());
    585   EXPECT_EQ(0u, reader.get("int8List").as<DynamicList>().size());
    586   EXPECT_EQ(0u, reader.get("int16List").as<DynamicList>().size());
    587   EXPECT_EQ(0u, reader.get("int32List").as<DynamicList>().size());
    588   EXPECT_EQ(0u, reader.get("int64List").as<DynamicList>().size());
    589   EXPECT_EQ(0u, reader.get("uInt8List").as<DynamicList>().size());
    590   EXPECT_EQ(0u, reader.get("uInt16List").as<DynamicList>().size());
    591   EXPECT_EQ(0u, reader.get("uInt32List").as<DynamicList>().size());
    592   EXPECT_EQ(0u, reader.get("uInt64List").as<DynamicList>().size());
    593   EXPECT_EQ(0u, reader.get("float32List").as<DynamicList>().size());
    594   EXPECT_EQ(0u, reader.get("float64List").as<DynamicList>().size());
    595   EXPECT_EQ(0u, reader.get("textList").as<DynamicList>().size());
    596   EXPECT_EQ(0u, reader.get("dataList").as<DynamicList>().size());
    597   EXPECT_EQ(0u, reader.get("structList").as<DynamicList>().size());
    598 }
    599 
    600 #undef as
    601 
    602 #endif  // !CAPNP_LITE
    603 
    604 template <typename Builder>
    605 void genericInitListDefaults(Builder builder) {
    606   auto lists = builder.initLists();
    607 
    608   lists.initList0(2);
    609   lists.initList1(4);
    610   lists.initList8(2);
    611   lists.initList16(2);
    612   lists.initList32(2);
    613   lists.initList64(2);
    614   lists.initListP(2);
    615 
    616   lists.getList0()[0].setF(VOID);
    617   lists.getList0()[1].setF(VOID);
    618   lists.getList1()[0].setF(true);
    619   lists.getList1()[1].setF(false);
    620   lists.getList1()[2].setF(true);
    621   lists.getList1()[3].setF(true);
    622   lists.getList8()[0].setF(123u);
    623   lists.getList8()[1].setF(45u);
    624   lists.getList16()[0].setF(12345u);
    625   lists.getList16()[1].setF(6789u);
    626   lists.getList32()[0].setF(123456789u);
    627   lists.getList32()[1].setF(234567890u);
    628   lists.getList64()[0].setF(1234567890123456u);
    629   lists.getList64()[1].setF(2345678901234567u);
    630   lists.getListP()[0].setF("foo");
    631   lists.getListP()[1].setF("bar");
    632 
    633   {
    634     auto l = lists.initInt32ListList(3);
    635     l.set(0, {1, 2, 3});
    636     l.set(1, {4, 5});
    637     l.set(2, {12341234});
    638   }
    639 
    640   {
    641     auto l = lists.initTextListList(3);
    642     l.set(0, {"foo", "bar"});
    643     l.set(1, {"baz"});
    644     l.set(2, {"qux", "corge"});
    645   }
    646 
    647   {
    648     auto l = lists.initStructListList(2);
    649     auto e = l.init(0, 2);
    650     e[0].setInt32Field(123);
    651     e[1].setInt32Field(456);
    652     e = l.init(1, 1);
    653     e[0].setInt32Field(789);
    654   }
    655 }
    656 
    657 #if !CAPNP_LITE
    658 
    659 void dynamicInitListDefaults(DynamicStruct::Builder builder) {
    660   auto lists = builder.init("lists").as<DynamicStruct>();
    661 
    662   lists.init("list0", 2);
    663   lists.init("list1", 4);
    664   lists.init("list8", 2);
    665   lists.init("list16", 2);
    666   lists.init("list32", 2);
    667   lists.init("list64", 2);
    668   lists.init("listP", 2);
    669 
    670   lists.get("list0").as<DynamicList>()[0].as<DynamicStruct>().set("f", VOID);
    671   lists.get("list0").as<DynamicList>()[1].as<DynamicStruct>().set("f", VOID);
    672   lists.get("list1").as<DynamicList>()[0].as<DynamicStruct>().set("f", true);
    673   lists.get("list1").as<DynamicList>()[1].as<DynamicStruct>().set("f", false);
    674   lists.get("list1").as<DynamicList>()[2].as<DynamicStruct>().set("f", true);
    675   lists.get("list1").as<DynamicList>()[3].as<DynamicStruct>().set("f", true);
    676   lists.get("list8").as<DynamicList>()[0].as<DynamicStruct>().set("f", 123u);
    677   lists.get("list8").as<DynamicList>()[1].as<DynamicStruct>().set("f", 45u);
    678   lists.get("list16").as<DynamicList>()[0].as<DynamicStruct>().set("f", 12345u);
    679   lists.get("list16").as<DynamicList>()[1].as<DynamicStruct>().set("f", 6789u);
    680   lists.get("list32").as<DynamicList>()[0].as<DynamicStruct>().set("f", 123456789u);
    681   lists.get("list32").as<DynamicList>()[1].as<DynamicStruct>().set("f", 234567890u);
    682   lists.get("list64").as<DynamicList>()[0].as<DynamicStruct>().set("f", 1234567890123456u);
    683   lists.get("list64").as<DynamicList>()[1].as<DynamicStruct>().set("f", 2345678901234567u);
    684   lists.get("listP").as<DynamicList>()[0].as<DynamicStruct>().set("f", "foo");
    685   lists.get("listP").as<DynamicList>()[1].as<DynamicStruct>().set("f", "bar");
    686 
    687   {
    688     auto l = lists.init("int32ListList", 3).as<DynamicList>();
    689     l.init(0, 3).as<DynamicList>().copyFrom({1, 2, 3});
    690     l.init(1, 2).as<DynamicList>().copyFrom({4, 5});
    691     l.init(2, 1).as<DynamicList>().copyFrom({12341234});
    692   }
    693 
    694   {
    695     auto l = lists.init("textListList", 3).as<DynamicList>();
    696     l.init(0, 2).as<DynamicList>().copyFrom({"foo", "bar"});
    697     l.init(1, 1).as<DynamicList>().copyFrom({"baz"});
    698     l.init(2, 2).as<DynamicList>().copyFrom({"qux", "corge"});
    699   }
    700 
    701   {
    702     auto l = lists.init("structListList", 2).as<DynamicList>();
    703     auto e = l.init(0, 2).as<DynamicList>();
    704     e[0].as<TestAllTypes>().setInt32Field(123);
    705     e[1].as<TestAllTypes>().setInt32Field(456);
    706     e = l.init(1, 1).as<DynamicList>();
    707     e[0].as<TestAllTypes>().setInt32Field(789);
    708   }
    709 }
    710 
    711 #endif  // !CAPNP_LITE
    712 
    713 template <typename Reader>
    714 void genericCheckListDefaults(Reader reader) {
    715   auto lists = reader.getLists();
    716 
    717   ASSERT_EQ(2u, lists.getList0().size());
    718   ASSERT_EQ(4u, lists.getList1().size());
    719   ASSERT_EQ(2u, lists.getList8().size());
    720   ASSERT_EQ(2u, lists.getList16().size());
    721   ASSERT_EQ(2u, lists.getList32().size());
    722   ASSERT_EQ(2u, lists.getList64().size());
    723   ASSERT_EQ(2u, lists.getListP().size());
    724 
    725   EXPECT_EQ(VOID, lists.getList0()[0].getF());
    726   EXPECT_EQ(VOID, lists.getList0()[1].getF());
    727   EXPECT_TRUE(lists.getList1()[0].getF());
    728   EXPECT_FALSE(lists.getList1()[1].getF());
    729   EXPECT_TRUE(lists.getList1()[2].getF());
    730   EXPECT_TRUE(lists.getList1()[3].getF());
    731   EXPECT_EQ(123u, lists.getList8()[0].getF());
    732   EXPECT_EQ(45u, lists.getList8()[1].getF());
    733   EXPECT_EQ(12345u, lists.getList16()[0].getF());
    734   EXPECT_EQ(6789u, lists.getList16()[1].getF());
    735   EXPECT_EQ(123456789u, lists.getList32()[0].getF());
    736   EXPECT_EQ(234567890u, lists.getList32()[1].getF());
    737   EXPECT_EQ(1234567890123456u, lists.getList64()[0].getF());
    738   EXPECT_EQ(2345678901234567u, lists.getList64()[1].getF());
    739   EXPECT_EQ("foo", lists.getListP()[0].getF());
    740   EXPECT_EQ("bar", lists.getListP()[1].getF());
    741 
    742   {
    743     auto l = lists.getInt32ListList();
    744     ASSERT_EQ(3u, l.size());
    745     checkList(l[0], {1, 2, 3});
    746     checkList(l[1], {4, 5});
    747     checkList(l[2], {12341234});
    748   }
    749 
    750   {
    751     auto l = lists.getTextListList();
    752     ASSERT_EQ(3u, l.size());
    753     checkList(l[0], {"foo", "bar"});
    754     checkList(l[1], {"baz"});
    755     checkList(l[2], {"qux", "corge"});
    756   }
    757 
    758   {
    759     auto l = lists.getStructListList();
    760     ASSERT_EQ(2u, l.size());
    761     auto e = l[0];
    762     ASSERT_EQ(2u, e.size());
    763     EXPECT_EQ(123, e[0].getInt32Field());
    764     EXPECT_EQ(456, e[1].getInt32Field());
    765     e = l[1];
    766     ASSERT_EQ(1u, e.size());
    767     EXPECT_EQ(789, e[0].getInt32Field());
    768   }
    769 }
    770 
    771 #if !CAPNP_LITE
    772 
    773 // Hack because as<>() is a template-parameter-dependent lookup everywhere below...
    774 #define as template as
    775 
    776 template <typename Reader>
    777 void dynamicCheckListDefaults(Reader reader) {
    778   auto lists = reader.get("lists").as<DynamicStruct>();
    779 
    780   ASSERT_EQ(2u, lists.get("list0").as<DynamicList>().size());
    781   ASSERT_EQ(4u, lists.get("list1").as<DynamicList>().size());
    782   ASSERT_EQ(2u, lists.get("list8").as<DynamicList>().size());
    783   ASSERT_EQ(2u, lists.get("list16").as<DynamicList>().size());
    784   ASSERT_EQ(2u, lists.get("list32").as<DynamicList>().size());
    785   ASSERT_EQ(2u, lists.get("list64").as<DynamicList>().size());
    786   ASSERT_EQ(2u, lists.get("listP").as<DynamicList>().size());
    787 
    788   EXPECT_EQ(VOID, lists.get("list0").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<Void>());
    789   EXPECT_EQ(VOID, lists.get("list0").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<Void>());
    790   EXPECT_TRUE(lists.get("list1").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<bool>());
    791   EXPECT_FALSE(lists.get("list1").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<bool>());
    792   EXPECT_TRUE(lists.get("list1").as<DynamicList>()[2].as<DynamicStruct>().get("f").as<bool>());
    793   EXPECT_TRUE(lists.get("list1").as<DynamicList>()[3].as<DynamicStruct>().get("f").as<bool>());
    794   EXPECT_EQ(123u, lists.get("list8").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint8_t>());
    795   EXPECT_EQ(45u, lists.get("list8").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint8_t>());
    796   EXPECT_EQ(12345u, lists.get("list16").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint16_t>());
    797   EXPECT_EQ(6789u, lists.get("list16").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint16_t>());
    798   EXPECT_EQ(123456789u, lists.get("list32").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint32_t>());
    799   EXPECT_EQ(234567890u, lists.get("list32").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint32_t>());
    800   EXPECT_EQ(1234567890123456u, lists.get("list64").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<uint64_t>());
    801   EXPECT_EQ(2345678901234567u, lists.get("list64").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<uint64_t>());
    802   EXPECT_EQ("foo", lists.get("listP").as<DynamicList>()[0].as<DynamicStruct>().get("f").as<Text>());
    803   EXPECT_EQ("bar", lists.get("listP").as<DynamicList>()[1].as<DynamicStruct>().get("f").as<Text>());
    804 
    805   {
    806     auto l = lists.get("int32ListList").as<DynamicList>();
    807     ASSERT_EQ(3u, l.size());
    808     checkList<int32_t>(l[0], {1, 2, 3});
    809     checkList<int32_t>(l[1], {4, 5});
    810     checkList<int32_t>(l[2], {12341234});
    811   }
    812 
    813   {
    814     auto l = lists.get("textListList").as<DynamicList>();
    815     ASSERT_EQ(3u, l.size());
    816     checkList<Text>(l[0], {"foo", "bar"});
    817     checkList<Text>(l[1], {"baz"});
    818     checkList<Text>(l[2], {"qux", "corge"});
    819   }
    820 
    821   {
    822     auto l = lists.get("structListList").as<DynamicList>();
    823     ASSERT_EQ(2u, l.size());
    824     auto e = l[0].as<DynamicList>();
    825     ASSERT_EQ(2u, e.size());
    826     EXPECT_EQ(123, e[0].as<TestAllTypes>().getInt32Field());
    827     EXPECT_EQ(456, e[1].as<TestAllTypes>().getInt32Field());
    828     e = l[1].as<DynamicList>();
    829     ASSERT_EQ(1u, e.size());
    830     EXPECT_EQ(789, e[0].as<TestAllTypes>().getInt32Field());
    831   }
    832 }
    833 
    834 #undef as
    835 
    836 #endif  // !CAPNP_LITE
    837 
    838 }  // namespace
    839 
    840 void initTestMessage(TestAllTypes::Builder builder) { genericInitTestMessage(builder); }
    841 void initTestMessage(TestDefaults::Builder builder) { genericInitTestMessage(builder); }
    842 void initTestMessage(TestListDefaults::Builder builder) { genericInitListDefaults(builder); }
    843 
    844 void checkTestMessage(TestAllTypes::Builder builder) { genericCheckTestMessage(builder); }
    845 void checkTestMessage(TestDefaults::Builder builder) { genericCheckTestMessage(builder); }
    846 void checkTestMessage(TestListDefaults::Builder builder) { genericCheckListDefaults(builder); }
    847 
    848 void checkTestMessage(TestAllTypes::Reader reader) { genericCheckTestMessage(reader); }
    849 void checkTestMessage(TestDefaults::Reader reader) { genericCheckTestMessage(reader); }
    850 void checkTestMessage(TestListDefaults::Reader reader) { genericCheckListDefaults(reader); }
    851 
    852 void checkTestMessageAllZero(TestAllTypes::Builder builder) {
    853   genericCheckTestMessageAllZero(builder);
    854 }
    855 void checkTestMessageAllZero(TestAllTypes::Reader reader) {
    856   genericCheckTestMessageAllZero(reader);
    857 }
    858 
    859 #if !CAPNP_LITE
    860 
    861 void initDynamicTestMessage(DynamicStruct::Builder builder) {
    862   dynamicInitTestMessage(builder);
    863 }
    864 void initDynamicTestLists(DynamicStruct::Builder builder) {
    865   dynamicInitListDefaults(builder);
    866 }
    867 void checkDynamicTestMessage(DynamicStruct::Builder builder) {
    868   dynamicCheckTestMessage(builder);
    869 }
    870 void checkDynamicTestLists(DynamicStruct::Builder builder) {
    871   dynamicCheckListDefaults(builder);
    872 }
    873 void checkDynamicTestMessage(DynamicStruct::Reader reader) {
    874   dynamicCheckTestMessage(reader);
    875 }
    876 void checkDynamicTestLists(DynamicStruct::Reader reader) {
    877   dynamicCheckListDefaults(reader);
    878 }
    879 void checkDynamicTestMessageAllZero(DynamicStruct::Builder builder) {
    880   dynamicCheckTestMessageAllZero(builder);
    881 }
    882 void checkDynamicTestMessageAllZero(DynamicStruct::Reader reader) {
    883   dynamicCheckTestMessageAllZero(reader);
    884 }
    885 
    886 #endif  // !CAPNP_LITE
    887 
    888 // =======================================================================================
    889 // Interface implementations.
    890 
    891 #if !CAPNP_LITE
    892 
    893 TestInterfaceImpl::TestInterfaceImpl(int& callCount): callCount(callCount) {}
    894 
    895 kj::Promise<void> TestInterfaceImpl::foo(FooContext context) {
    896   ++callCount;
    897   auto params = context.getParams();
    898   auto result = context.getResults();
    899   EXPECT_EQ(123, params.getI());
    900   EXPECT_TRUE(params.getJ());
    901   result.setX("foo");
    902   return kj::READY_NOW;
    903 }
    904 
    905 kj::Promise<void> TestInterfaceImpl::baz(BazContext context) {
    906   ++callCount;
    907   auto params = context.getParams();
    908   checkTestMessage(params.getS());
    909   context.releaseParams();
    910   EXPECT_ANY_THROW(context.getParams());
    911 
    912   return kj::READY_NOW;
    913 }
    914 
    915 TestExtendsImpl::TestExtendsImpl(int& callCount): callCount(callCount) {}
    916 
    917 kj::Promise<void> TestExtendsImpl::foo(FooContext context) {
    918   ++callCount;
    919   auto params = context.getParams();
    920   auto result = context.getResults();
    921   EXPECT_EQ(321, params.getI());
    922   EXPECT_FALSE(params.getJ());
    923   result.setX("bar");
    924   return kj::READY_NOW;
    925 }
    926 
    927 kj::Promise<void> TestExtendsImpl::grault(GraultContext context) {
    928   ++callCount;
    929   context.releaseParams();
    930 
    931   initTestMessage(context.getResults());
    932 
    933   return kj::READY_NOW;
    934 }
    935 
    936 TestPipelineImpl::TestPipelineImpl(int& callCount): callCount(callCount) {}
    937 
    938 kj::Promise<void> TestPipelineImpl::getCap(GetCapContext context) {
    939   ++callCount;
    940 
    941   auto params = context.getParams();
    942   EXPECT_EQ(234, params.getN());
    943 
    944   auto cap = params.getInCap();
    945   context.releaseParams();
    946 
    947   auto request = cap.fooRequest();
    948   request.setI(123);
    949   request.setJ(true);
    950 
    951   return request.send().then(
    952       [this,KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable {
    953         EXPECT_EQ("foo", response.getX());
    954 
    955         auto result = context.getResults();
    956         result.setS("bar");
    957         result.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount));
    958       });
    959 }
    960 
    961 kj::Promise<void> TestPipelineImpl::getAnyCap(GetAnyCapContext context) {
    962   ++callCount;
    963 
    964   auto params = context.getParams();
    965   EXPECT_EQ(234, params.getN());
    966 
    967   auto cap = params.getInCap();
    968   context.releaseParams();
    969 
    970   auto request = cap.castAs<test::TestInterface>().fooRequest();
    971   request.setI(123);
    972   request.setJ(true);
    973 
    974   return request.send().then(
    975       [this,KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable {
    976         EXPECT_EQ("foo", response.getX());
    977 
    978         auto result = context.getResults();
    979         result.setS("bar");
    980         result.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount));
    981       });
    982 }
    983 
    984 kj::Promise<void> TestPipelineImpl::getCapPipelineOnly(GetCapPipelineOnlyContext context) {
    985   ++callCount;
    986   PipelineBuilder<GetCapPipelineOnlyResults> pb;
    987   pb.initOutBox().setCap(kj::heap<TestExtendsImpl>(callCount));
    988   context.setPipeline(pb.build());
    989   return kj::NEVER_DONE;
    990 }
    991 
    992 kj::Promise<void> TestCallOrderImpl::getCallSequence(GetCallSequenceContext context) {
    993   auto result = context.getResults();
    994   result.setN(count++);
    995   return kj::READY_NOW;
    996 }
    997 
    998 TestTailCallerImpl::TestTailCallerImpl(int& callCount): callCount(callCount) {}
    999 
   1000 kj::Promise<void> TestTailCallerImpl::foo(FooContext context) {
   1001   ++callCount;
   1002 
   1003   auto params = context.getParams();
   1004   auto tailRequest = params.getCallee().fooRequest();
   1005   tailRequest.setI(params.getI());
   1006   tailRequest.setT("from TestTailCaller");
   1007   return context.tailCall(kj::mv(tailRequest));
   1008 }
   1009 
   1010 TestTailCalleeImpl::TestTailCalleeImpl(int& callCount): callCount(callCount) {}
   1011 
   1012 kj::Promise<void> TestTailCalleeImpl::foo(FooContext context) {
   1013   ++callCount;
   1014 
   1015   auto params = context.getParams();
   1016   auto results = context.getResults();
   1017 
   1018   results.setI(params.getI());
   1019   results.setT(params.getT());
   1020   results.setC(kj::heap<TestCallOrderImpl>());
   1021 
   1022   return kj::READY_NOW;
   1023 }
   1024 
   1025 TestMoreStuffImpl::TestMoreStuffImpl(int& callCount, int& handleCount)
   1026     : callCount(callCount), handleCount(handleCount) {}
   1027 
   1028 kj::Promise<void> TestMoreStuffImpl::getCallSequence(GetCallSequenceContext context) {
   1029   auto result = context.getResults();
   1030   result.setN(callCount++);
   1031   return kj::READY_NOW;
   1032 }
   1033 
   1034 kj::Promise<void> TestMoreStuffImpl::callFoo(CallFooContext context) {
   1035   ++callCount;
   1036 
   1037   auto params = context.getParams();
   1038   auto cap = params.getCap();
   1039 
   1040   auto request = cap.fooRequest();
   1041   request.setI(123);
   1042   request.setJ(true);
   1043 
   1044   return request.send().then(
   1045       [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable {
   1046         EXPECT_EQ("foo", response.getX());
   1047         context.getResults().setS("bar");
   1048       });
   1049 }
   1050 
   1051 kj::Promise<void> TestMoreStuffImpl::callFooWhenResolved(CallFooWhenResolvedContext context) {
   1052   ++callCount;
   1053 
   1054   auto params = context.getParams();
   1055   auto cap = params.getCap();
   1056 
   1057   return cap.whenResolved().then([KJ_CPCAP(cap),KJ_CPCAP(context)]() mutable {
   1058     auto request = cap.fooRequest();
   1059     request.setI(123);
   1060     request.setJ(true);
   1061 
   1062     return request.send().then(
   1063         [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable {
   1064           EXPECT_EQ("foo", response.getX());
   1065           context.getResults().setS("bar");
   1066         });
   1067   });
   1068 }
   1069 
   1070 kj::Promise<void> TestMoreStuffImpl::neverReturn(NeverReturnContext context) {
   1071   ++callCount;
   1072 
   1073   // Attach `cap` to the promise to make sure it is released.
   1074   auto promise = kj::Promise<void>(kj::NEVER_DONE).attach(context.getParams().getCap());
   1075 
   1076   // Also attach `cap` to the result struct to make sure that is released.
   1077   context.getResults().setCapCopy(context.getParams().getCap());
   1078 
   1079   context.allowCancellation();
   1080   return kj::mv(promise);
   1081 }
   1082 
   1083 kj::Promise<void> TestMoreStuffImpl::hold(HoldContext context) {
   1084   ++callCount;
   1085 
   1086   auto params = context.getParams();
   1087   clientToHold = params.getCap();
   1088   return kj::READY_NOW;
   1089 }
   1090 
   1091 kj::Promise<void> TestMoreStuffImpl::callHeld(CallHeldContext context) {
   1092   ++callCount;
   1093 
   1094   auto request = clientToHold.fooRequest();
   1095   request.setI(123);
   1096   request.setJ(true);
   1097 
   1098   return request.send().then(
   1099       [KJ_CPCAP(context)](Response<test::TestInterface::FooResults>&& response) mutable {
   1100         EXPECT_EQ("foo", response.getX());
   1101         context.getResults().setS("bar");
   1102       });
   1103 }
   1104 
   1105 kj::Promise<void> TestMoreStuffImpl::getHeld(GetHeldContext context) {
   1106   ++callCount;
   1107   auto result = context.getResults();
   1108   result.setCap(clientToHold);
   1109   return kj::READY_NOW;
   1110 }
   1111 
   1112 kj::Promise<void> TestMoreStuffImpl::echo(EchoContext context) {
   1113   ++callCount;
   1114   auto params = context.getParams();
   1115   auto result = context.getResults();
   1116   result.setCap(params.getCap());
   1117   return kj::READY_NOW;
   1118 }
   1119 
   1120 kj::Promise<void> TestMoreStuffImpl::expectCancel(ExpectCancelContext context) {
   1121   auto cap = context.getParams().getCap();
   1122   context.allowCancellation();
   1123   return loop(0, cap, context);
   1124 }
   1125 
   1126 kj::Promise<void> TestMoreStuffImpl::loop(uint depth, test::TestInterface::Client cap,
   1127                                           ExpectCancelContext context) {
   1128   if (depth > 100) {
   1129     ADD_FAILURE() << "Looped too long, giving up.";
   1130     return kj::READY_NOW;
   1131   } else {
   1132     return kj::evalLater([this,depth,KJ_CPCAP(cap),KJ_CPCAP(context)]() mutable {
   1133       return loop(depth + 1, cap, context);
   1134     });
   1135   }
   1136 }
   1137 
   1138 class HandleImpl final: public test::TestHandle::Server {
   1139 public:
   1140   HandleImpl(int& count): count(count) { ++count; }
   1141   ~HandleImpl() { --count; }
   1142 
   1143 private:
   1144   int& count;
   1145 };
   1146 
   1147 kj::Promise<void> TestMoreStuffImpl::getHandle(GetHandleContext context) {
   1148   context.getResults().setHandle(kj::heap<HandleImpl>(handleCount));
   1149   return kj::READY_NOW;
   1150 }
   1151 
   1152 kj::Promise<void> TestMoreStuffImpl::getNull(GetNullContext context) {
   1153   return kj::READY_NOW;
   1154 }
   1155 
   1156 kj::Promise<void> TestMoreStuffImpl::getEnormousString(GetEnormousStringContext context) {
   1157   context.getResults().initStr(100000000);  // 100MB
   1158   return kj::READY_NOW;
   1159 }
   1160 
   1161 kj::Promise<void> TestMoreStuffImpl::writeToFd(WriteToFdContext context) {
   1162   auto params = context.getParams();
   1163 
   1164   auto promises = kj::heapArrayBuilder<kj::Promise<void>>(2);
   1165 
   1166   promises.add(params.getFdCap1().getFd()
   1167       .then([](kj::Maybe<int> fd) {
   1168     kj::FdOutputStream(KJ_ASSERT_NONNULL(fd)).write("foo", 3);
   1169   }));
   1170   promises.add(params.getFdCap2().getFd()
   1171       .then([context](kj::Maybe<int> fd) mutable {
   1172     context.getResults().setSecondFdPresent(fd != nullptr);
   1173     KJ_IF_MAYBE(f, fd) {
   1174       kj::FdOutputStream(*f).write("bar", 3);
   1175     }
   1176   }));
   1177 
   1178   int pair[2];
   1179   KJ_SYSCALL(kj::miniposix::pipe(pair));
   1180   kj::AutoCloseFd in(pair[0]);
   1181   kj::AutoCloseFd out(pair[1]);
   1182 
   1183   kj::FdOutputStream(kj::mv(out)).write("baz", 3);
   1184   context.getResults().setFdCap3(kj::heap<TestFdCap>(kj::mv(in)));
   1185 
   1186   return kj::joinPromises(promises.finish());
   1187 }
   1188 
   1189 kj::Promise<void> TestMoreStuffImpl::throwException(ThrowExceptionContext context) {
   1190   return KJ_EXCEPTION(FAILED, "test exception");
   1191 }
   1192 
   1193 kj::Promise<void> TestMoreStuffImpl::throwRemoteException(ThrowRemoteExceptionContext context) {
   1194   return KJ_EXCEPTION(FAILED, "remote exception: test exception");
   1195 }
   1196 
   1197 #endif  // !CAPNP_LITE
   1198 
   1199 }  // namespace _ (private)
   1200 }  // namespace capnp