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

orphan-test.c++ (53642B)


      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 #include "message.h"
     23 #include <kj/debug.h>
     24 #include <kj/compat/gtest.h>
     25 #include "test-util.h"
     26 
     27 namespace capnp {
     28 namespace _ {  // private
     29 namespace {
     30 
     31 TEST(Orphans, Structs) {
     32   MallocMessageBuilder builder;
     33   auto root = builder.initRoot<TestAllTypes>();
     34 
     35   initTestMessage(root.initStructField());
     36   EXPECT_TRUE(root.hasStructField());
     37 
     38   Orphan<TestAllTypes> orphan = root.disownStructField();
     39   EXPECT_FALSE(orphan == nullptr);
     40 
     41   checkTestMessage(orphan.getReader());
     42   checkTestMessage(orphan.get());
     43   EXPECT_FALSE(root.hasStructField());
     44 
     45   root.adoptStructField(kj::mv(orphan));
     46   EXPECT_TRUE(orphan == nullptr);
     47   EXPECT_TRUE(root.hasStructField());
     48   checkTestMessage(root.asReader().getStructField());
     49 }
     50 
     51 TEST(Orphans, EmptyStruct) {
     52   MallocMessageBuilder builder;
     53   auto root = builder.initRoot<test::TestAnyPointer>();
     54   auto anyPointer = root.getAnyPointerField();
     55   EXPECT_TRUE(anyPointer.isNull());
     56   auto orphan = builder.getOrphanage().newOrphan<test::TestEmptyStruct>();
     57   anyPointer.adopt(kj::mv(orphan));
     58   EXPECT_EQ(0, anyPointer.targetSize().wordCount);
     59   EXPECT_FALSE(anyPointer.isNull());
     60 }
     61 
     62 TEST(Orphans, EmptyStructOverwrite) {
     63   MallocMessageBuilder builder;
     64   auto root = builder.initRoot<test::TestAnyPointer>();
     65   auto anyPointer = root.getAnyPointerField();
     66   EXPECT_TRUE(anyPointer.isNull());
     67   anyPointer.initAs<TestAllTypes>();
     68   auto orphan = builder.getOrphanage().newOrphan<test::TestEmptyStruct>();
     69   anyPointer.adopt(kj::mv(orphan));
     70   EXPECT_EQ(0, anyPointer.targetSize().wordCount);
     71   EXPECT_FALSE(anyPointer.isNull());
     72 }
     73 
     74 TEST(Orphans, AdoptNullStruct) {
     75   MallocMessageBuilder builder;
     76   auto root = builder.initRoot<test::TestAnyPointer>();
     77   auto anyPointer = root.getAnyPointerField();
     78   EXPECT_TRUE(anyPointer.isNull());
     79   anyPointer.initAs<TestAllTypes>();
     80   anyPointer.adopt(Orphan<test::TestEmptyStruct>());
     81   EXPECT_EQ(0, anyPointer.targetSize().wordCount);
     82   EXPECT_TRUE(anyPointer.isNull());
     83 }
     84 
     85 TEST(Orphans, Lists) {
     86   MallocMessageBuilder builder;
     87   auto root = builder.initRoot<TestAllTypes>();
     88 
     89   root.setUInt32List({12, 34, 56});
     90   EXPECT_TRUE(root.hasUInt32List());
     91 
     92   Orphan<List<uint32_t>> orphan = root.disownUInt32List();
     93   EXPECT_FALSE(orphan == nullptr);
     94 
     95   checkList(orphan.getReader(), {12u, 34u, 56u});
     96   checkList(orphan.get(), {12u, 34u, 56u});
     97   EXPECT_FALSE(root.hasUInt32List());
     98 
     99   root.adoptUInt32List(kj::mv(orphan));
    100   EXPECT_TRUE(orphan == nullptr);
    101   EXPECT_TRUE(root.hasUInt32List());
    102   checkList(root.asReader().getUInt32List(), {12u, 34u, 56u});
    103 }
    104 
    105 TEST(Orphans, StructLists) {
    106   MallocMessageBuilder builder;
    107   auto root = builder.initRoot<TestAllTypes>();
    108 
    109   auto list = root.initStructList(2);
    110   list[0].setTextField("foo");
    111   list[1].setTextField("bar");
    112   EXPECT_TRUE(root.hasStructList());
    113 
    114   Orphan<List<TestAllTypes>> orphan = root.disownStructList();
    115   EXPECT_FALSE(orphan == nullptr);
    116 
    117   ASSERT_EQ(2u, orphan.getReader().size());
    118   EXPECT_EQ("foo", orphan.getReader()[0].getTextField());
    119   EXPECT_EQ("bar", orphan.getReader()[1].getTextField());
    120   ASSERT_EQ(2u, orphan.get().size());
    121   EXPECT_EQ("foo", orphan.get()[0].getTextField());
    122   EXPECT_EQ("bar", orphan.get()[1].getTextField());
    123   EXPECT_FALSE(root.hasStructList());
    124 
    125   root.adoptStructList(kj::mv(orphan));
    126   EXPECT_TRUE(orphan == nullptr);
    127   EXPECT_TRUE(root.hasStructList());
    128   ASSERT_EQ(2u, root.asReader().getStructList().size());
    129   EXPECT_EQ("foo", root.asReader().getStructList()[0].getTextField());
    130   EXPECT_EQ("bar", root.asReader().getStructList()[1].getTextField());
    131 }
    132 
    133 TEST(Orphans, Text) {
    134   MallocMessageBuilder builder;
    135   auto root = builder.initRoot<TestAllTypes>();
    136 
    137   root.setTextField("foo");
    138   EXPECT_TRUE(root.hasTextField());
    139 
    140   Orphan<Text> orphan = root.disownTextField();
    141   EXPECT_FALSE(orphan == nullptr);
    142 
    143   EXPECT_EQ("foo", orphan.getReader());
    144   EXPECT_EQ("foo", orphan.get());
    145   EXPECT_FALSE(root.hasTextField());
    146 
    147   root.adoptTextField(kj::mv(orphan));
    148   EXPECT_TRUE(orphan == nullptr);
    149   EXPECT_TRUE(root.hasTextField());
    150   EXPECT_EQ("foo", root.getTextField());
    151 }
    152 
    153 TEST(Orphans, Data) {
    154   MallocMessageBuilder builder;
    155   auto root = builder.initRoot<TestAllTypes>();
    156 
    157   root.setDataField(data("foo"));
    158   EXPECT_TRUE(root.hasDataField());
    159 
    160   Orphan<Data> orphan = root.disownDataField();
    161   EXPECT_FALSE(orphan == nullptr);
    162 
    163   EXPECT_EQ(data("foo"), orphan.getReader());
    164   EXPECT_EQ(data("foo"), orphan.get());
    165   EXPECT_FALSE(root.hasDataField());
    166 
    167   root.adoptDataField(kj::mv(orphan));
    168   EXPECT_TRUE(orphan == nullptr);
    169   EXPECT_TRUE(root.hasDataField());
    170   EXPECT_EQ(data("foo"), root.getDataField());
    171 }
    172 
    173 TEST(Orphans, NoCrossMessageTransfers) {
    174   MallocMessageBuilder builder1;
    175   MallocMessageBuilder builder2;
    176   auto root1 = builder1.initRoot<TestAllTypes>();
    177   auto root2 = builder2.initRoot<TestAllTypes>();
    178 
    179   initTestMessage(root1.initStructField());
    180 
    181   EXPECT_ANY_THROW(root2.adoptStructField(root1.disownStructField()));
    182 }
    183 
    184 TEST(Orphans, OrphanageStruct) {
    185   MallocMessageBuilder builder;
    186 
    187   Orphan<TestAllTypes> orphan = builder.getOrphanage().newOrphan<TestAllTypes>();
    188   initTestMessage(orphan.get());
    189   checkTestMessage(orphan.getReader());
    190 
    191   auto root = builder.initRoot<TestAllTypes>();
    192   root.adoptStructField(kj::mv(orphan));
    193 }
    194 
    195 TEST(Orphans, OrphanageList) {
    196   MallocMessageBuilder builder;
    197 
    198   Orphan<List<uint32_t>> orphan = builder.getOrphanage().newOrphan<List<uint32_t>>(2);
    199   orphan.get().set(0, 123);
    200   orphan.get().set(1, 456);
    201 
    202   List<uint32_t>::Reader reader = orphan.getReader();
    203   ASSERT_EQ(2u, reader.size());
    204   EXPECT_EQ(123u, reader[0]);
    205   EXPECT_EQ(456u, reader[1]);
    206 
    207   auto root = builder.initRoot<TestAllTypes>();
    208   root.adoptUInt32List(kj::mv(orphan));
    209 }
    210 
    211 TEST(Orphans, OrphanageText) {
    212   MallocMessageBuilder builder;
    213 
    214   Orphan<Text> orphan = builder.getOrphanage().newOrphan<Text>(8);
    215   ASSERT_EQ(8u, orphan.get().size());
    216   memcpy(orphan.get().begin(), "12345678", 8);
    217 
    218   auto root = builder.initRoot<TestAllTypes>();
    219   root.adoptTextField(kj::mv(orphan));
    220   EXPECT_EQ("12345678", root.getTextField());
    221 }
    222 
    223 TEST(Orphans, OrphanageData) {
    224   MallocMessageBuilder builder;
    225 
    226   Orphan<Data> orphan = builder.getOrphanage().newOrphan<Data>(2);
    227   ASSERT_EQ(2u, orphan.get().size());
    228   orphan.get()[0] = 123;
    229   orphan.get()[1] = 45;
    230 
    231   auto root = builder.initRoot<TestAllTypes>();
    232   root.adoptDataField(kj::mv(orphan));
    233   ASSERT_EQ(2u, root.getDataField().size());
    234   EXPECT_EQ(123u, root.getDataField()[0]);
    235   EXPECT_EQ(45u, root.getDataField()[1]);
    236 }
    237 
    238 TEST(Orphans, OrphanageStructCopy) {
    239   MallocMessageBuilder builder1;
    240   MallocMessageBuilder builder2;
    241 
    242   auto root1 = builder1.initRoot<TestAllTypes>();
    243   initTestMessage(root1);
    244 
    245   Orphan<TestAllTypes> orphan = builder2.getOrphanage().newOrphanCopy(root1.asReader());
    246   checkTestMessage(orphan.getReader());
    247 
    248   auto root2 = builder2.initRoot<TestAllTypes>();
    249   root2.adoptStructField(kj::mv(orphan));
    250 }
    251 
    252 TEST(Orphans, OrphanageListCopy) {
    253   MallocMessageBuilder builder1;
    254   MallocMessageBuilder builder2;
    255 
    256   auto root1 = builder1.initRoot<TestAllTypes>();
    257   root1.setUInt32List({12, 34, 56});
    258 
    259   Orphan<List<uint32_t>> orphan = builder2.getOrphanage().newOrphanCopy(
    260       root1.asReader().getUInt32List());
    261   checkList(orphan.getReader(), {12u, 34u, 56u});
    262 
    263   auto root2 = builder2.initRoot<TestAllTypes>();
    264   root2.adoptUInt32List(kj::mv(orphan));
    265 }
    266 
    267 TEST(Orphans, OrphanageTextCopy) {
    268   MallocMessageBuilder builder;
    269 
    270   Orphan<Text> orphan = builder.getOrphanage().newOrphanCopy(Text::Reader("foobarba"));
    271   EXPECT_EQ("foobarba", orphan.getReader());
    272 
    273   auto root = builder.initRoot<TestAllTypes>();
    274   root.adoptTextField(kj::mv(orphan));
    275 }
    276 
    277 TEST(Orphans, OrphanageDataCopy) {
    278   MallocMessageBuilder builder;
    279 
    280   Orphan<Data> orphan = builder.getOrphanage().newOrphanCopy(data("foo"));
    281   EXPECT_EQ(data("foo"), orphan.getReader());
    282 
    283   auto root = builder.initRoot<TestAllTypes>();
    284   root.adoptDataField(kj::mv(orphan));
    285 }
    286 
    287 TEST(Orphans, ZeroOut) {
    288   MallocMessageBuilder builder;
    289   TestAllTypes::Reader orphanReader;
    290 
    291   {
    292     Orphan<TestAllTypes> orphan = builder.getOrphanage().newOrphan<TestAllTypes>();
    293     orphanReader = orphan.getReader();
    294     initTestMessage(orphan.get());
    295     checkTestMessage(orphan.getReader());
    296   }
    297 
    298   // Once the Orphan destructor is called, the message should be zero'd out.
    299   checkTestMessageAllZero(orphanReader);
    300 }
    301 
    302 TEST(Orphans, StructAnyPointer) {
    303   MallocMessageBuilder builder;
    304   auto root = builder.initRoot<test::TestAnyPointer>();
    305 
    306   initTestMessage(root.getAnyPointerField().initAs<TestAllTypes>());
    307   EXPECT_TRUE(root.hasAnyPointerField());
    308 
    309   Orphan<TestAllTypes> orphan = root.getAnyPointerField().disownAs<TestAllTypes>();
    310   EXPECT_FALSE(orphan == nullptr);
    311 
    312   checkTestMessage(orphan.getReader());
    313   EXPECT_FALSE(root.hasAnyPointerField());
    314 
    315   root.getAnyPointerField().adopt(kj::mv(orphan));
    316   EXPECT_TRUE(orphan == nullptr);
    317   EXPECT_TRUE(root.hasAnyPointerField());
    318   checkTestMessage(root.asReader().getAnyPointerField().getAs<TestAllTypes>());
    319 }
    320 
    321 TEST(Orphans, ListAnyPointer) {
    322   MallocMessageBuilder builder;
    323   auto root = builder.initRoot<test::TestAnyPointer>();
    324 
    325   root.getAnyPointerField().setAs<List<uint32_t>>({12, 34, 56});
    326   EXPECT_TRUE(root.hasAnyPointerField());
    327 
    328   Orphan<List<uint32_t>> orphan = root.getAnyPointerField().disownAs<List<uint32_t>>();
    329   EXPECT_FALSE(orphan == nullptr);
    330 
    331   checkList(orphan.getReader(), {12u, 34u, 56u});
    332   EXPECT_FALSE(root.hasAnyPointerField());
    333 
    334   root.getAnyPointerField().adopt(kj::mv(orphan));
    335   EXPECT_TRUE(orphan == nullptr);
    336   EXPECT_TRUE(root.hasAnyPointerField());
    337   checkList(root.asReader().getAnyPointerField().getAs<List<uint32_t>>(), {12u, 34u, 56u});
    338 }
    339 
    340 #if !CAPNP_LITE
    341 TEST(Orphans, DynamicStruct) {
    342   MallocMessageBuilder builder;
    343   auto root = builder.initRoot<test::TestAnyPointer>();
    344 
    345   initTestMessage(root.getAnyPointerField().initAs<TestAllTypes>());
    346   EXPECT_TRUE(root.hasAnyPointerField());
    347 
    348   Orphan<DynamicStruct> orphan =
    349       root.getAnyPointerField().disownAs<DynamicStruct>(Schema::from<TestAllTypes>());
    350   EXPECT_FALSE(orphan == nullptr);
    351 
    352   EXPECT_TRUE(orphan.get().getSchema() == Schema::from<TestAllTypes>());
    353   checkDynamicTestMessage(orphan.getReader());
    354   EXPECT_FALSE(root.hasAnyPointerField());
    355 
    356   root.getAnyPointerField().adopt(kj::mv(orphan));
    357   EXPECT_TRUE(orphan == nullptr);
    358   EXPECT_TRUE(root.hasAnyPointerField());
    359   checkTestMessage(root.asReader().getAnyPointerField().getAs<TestAllTypes>());
    360 
    361   Orphan<DynamicStruct> orphan2 = root.getAnyPointerField().disownAs<TestAllTypes>();
    362   EXPECT_FALSE(orphan2 == nullptr);
    363   EXPECT_TRUE(orphan2.get().getSchema() == Schema::from<TestAllTypes>());
    364   checkDynamicTestMessage(orphan2.getReader());
    365 }
    366 
    367 TEST(Orphans, DynamicList) {
    368   MallocMessageBuilder builder;
    369   auto root = builder.initRoot<test::TestAnyPointer>();
    370 
    371   root.getAnyPointerField().setAs<List<uint32_t>>({12, 34, 56});
    372   EXPECT_TRUE(root.hasAnyPointerField());
    373 
    374   Orphan<DynamicList> orphan =
    375       root.getAnyPointerField().disownAs<DynamicList>(Schema::from<List<uint32_t>>());
    376   EXPECT_FALSE(orphan == nullptr);
    377 
    378   checkList<uint32_t>(orphan.getReader(), {12, 34, 56});
    379   EXPECT_FALSE(root.hasAnyPointerField());
    380 
    381   root.getAnyPointerField().adopt(kj::mv(orphan));
    382   EXPECT_TRUE(orphan == nullptr);
    383   EXPECT_TRUE(root.hasAnyPointerField());
    384   checkList(root.asReader().getAnyPointerField().getAs<List<uint32_t>>(), {12u, 34u, 56u});
    385 
    386   Orphan<DynamicList> orphan2 = root.getAnyPointerField().disownAs<List<uint32_t>>();
    387   EXPECT_FALSE(orphan2 == nullptr);
    388   checkList<uint32_t>(orphan2.getReader(), {12, 34, 56});
    389 }
    390 
    391 TEST(Orphans, DynamicStructList) {
    392   MallocMessageBuilder builder;
    393   auto root = builder.initRoot<test::TestAnyPointer>();
    394 
    395   auto list = root.getAnyPointerField().initAs<List<TestAllTypes>>(2);
    396   list[0].setTextField("foo");
    397   list[1].setTextField("bar");
    398   EXPECT_TRUE(root.hasAnyPointerField());
    399 
    400   Orphan<DynamicList> orphan =
    401       root.getAnyPointerField().disownAs<DynamicList>(Schema::from<List<TestAllTypes>>());
    402   EXPECT_FALSE(orphan == nullptr);
    403 
    404   ASSERT_EQ(2u, orphan.get().size());
    405   EXPECT_EQ("foo", orphan.get()[0].as<TestAllTypes>().getTextField());
    406   EXPECT_EQ("bar", orphan.get()[1].as<TestAllTypes>().getTextField());
    407   EXPECT_FALSE(root.hasAnyPointerField());
    408 
    409   root.getAnyPointerField().adopt(kj::mv(orphan));
    410   EXPECT_TRUE(orphan == nullptr);
    411   EXPECT_TRUE(root.hasAnyPointerField());
    412   ASSERT_EQ(2u, root.asReader().getAnyPointerField().getAs<List<TestAllTypes>>().size());
    413   EXPECT_EQ("foo", root.asReader().getAnyPointerField()
    414                        .getAs<List<TestAllTypes>>()[0].getTextField());
    415   EXPECT_EQ("bar", root.asReader().getAnyPointerField()
    416                        .getAs<List<TestAllTypes>>()[1].getTextField());
    417 }
    418 
    419 TEST(Orphans, OrphanageDynamicStruct) {
    420   MallocMessageBuilder builder;
    421 
    422   Orphan<DynamicStruct> orphan = builder.getOrphanage().newOrphan(Schema::from<TestAllTypes>());
    423   initDynamicTestMessage(orphan.get());
    424   checkDynamicTestMessage(orphan.getReader());
    425 
    426   auto root = builder.initRoot<test::TestAnyPointer>();
    427   root.getAnyPointerField().adopt(kj::mv(orphan));
    428   checkTestMessage(root.asReader().getAnyPointerField().getAs<TestAllTypes>());
    429 }
    430 
    431 TEST(Orphans, OrphanageDynamicList) {
    432   MallocMessageBuilder builder;
    433 
    434   Orphan<DynamicList> orphan = builder.getOrphanage().newOrphan(Schema::from<List<uint32_t>>(), 2);
    435   orphan.get().set(0, 123);
    436   orphan.get().set(1, 456);
    437 
    438   checkList<uint32_t>(orphan.getReader(), {123, 456});
    439 
    440   auto root = builder.initRoot<test::TestAnyPointer>();
    441   root.getAnyPointerField().adopt(kj::mv(orphan));
    442   checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), {123u, 456u});
    443 }
    444 
    445 TEST(Orphans, OrphanageDynamicStructCopy) {
    446   MallocMessageBuilder builder1;
    447   MallocMessageBuilder builder2;
    448 
    449   auto root1 = builder1.initRoot<test::TestAnyPointer>();
    450   initTestMessage(root1.getAnyPointerField().initAs<TestAllTypes>());
    451 
    452   Orphan<DynamicStruct> orphan = builder2.getOrphanage().newOrphanCopy(
    453       root1.asReader().getAnyPointerField().getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
    454   checkDynamicTestMessage(orphan.getReader());
    455 
    456   auto root2 = builder2.initRoot<test::TestAnyPointer>();
    457   root2.getAnyPointerField().adopt(kj::mv(orphan));
    458   checkTestMessage(root2.asReader().getAnyPointerField().getAs<TestAllTypes>());
    459 }
    460 
    461 TEST(Orphans, OrphanageDynamicListCopy) {
    462   MallocMessageBuilder builder1;
    463   MallocMessageBuilder builder2;
    464 
    465   auto root1 = builder1.initRoot<test::TestAnyPointer>();
    466   root1.getAnyPointerField().setAs<List<uint32_t>>({12, 34, 56});
    467 
    468   Orphan<DynamicList> orphan = builder2.getOrphanage().newOrphanCopy(
    469       root1.asReader().getAnyPointerField().getAs<DynamicList>(Schema::from<List<uint32_t>>()));
    470   checkList<uint32_t>(orphan.getReader(), {12, 34, 56});
    471 
    472   auto root2 = builder2.initRoot<test::TestAnyPointer>();
    473   root2.getAnyPointerField().adopt(kj::mv(orphan));
    474   checkList(root2.getAnyPointerField().getAs<List<uint32_t>>(), {12u, 34u, 56u});
    475 }
    476 
    477 TEST(Orphans, DynamicStructAs) {
    478   MallocMessageBuilder builder;
    479   auto root = builder.initRoot<test::TestAnyPointer>();
    480 
    481   initTestMessage(root.getAnyPointerField().initAs<TestAllTypes>());
    482   EXPECT_TRUE(root.hasAnyPointerField());
    483 
    484   Orphan<DynamicValue> orphan =
    485       root.getAnyPointerField().disownAs<DynamicStruct>(Schema::from<TestAllTypes>());
    486   EXPECT_EQ(DynamicValue::STRUCT, orphan.getType());
    487 
    488   checkTestMessage(orphan.getReader().as<TestAllTypes>());
    489   checkTestMessage(orphan.get().as<TestAllTypes>());
    490 
    491   {
    492     Orphan<DynamicStruct> structOrphan = orphan.releaseAs<DynamicStruct>();
    493     EXPECT_EQ(DynamicValue::UNKNOWN, orphan.getType());
    494     EXPECT_FALSE(structOrphan == nullptr);
    495     checkDynamicTestMessage(structOrphan.getReader());
    496     checkDynamicTestMessage(structOrphan.get());
    497     checkTestMessage(structOrphan.getReader().as<TestAllTypes>());
    498     checkTestMessage(structOrphan.get().as<TestAllTypes>());
    499 
    500     {
    501       Orphan<TestAllTypes> typedOrphan = structOrphan.releaseAs<TestAllTypes>();
    502       EXPECT_TRUE(structOrphan == nullptr);
    503       EXPECT_FALSE(typedOrphan == nullptr);
    504       checkTestMessage(typedOrphan.getReader());
    505       checkTestMessage(typedOrphan.get());
    506       orphan = kj::mv(typedOrphan);
    507       EXPECT_EQ(DynamicValue::STRUCT, orphan.getType());
    508       EXPECT_TRUE(typedOrphan == nullptr);
    509     }
    510   }
    511 
    512   {
    513     Orphan<TestAllTypes> typedOrphan = orphan.releaseAs<TestAllTypes>();
    514     checkTestMessage(typedOrphan.getReader());
    515     checkTestMessage(typedOrphan.get());
    516   }
    517 }
    518 
    519 TEST(Orphans, DynamicListAs) {
    520   MallocMessageBuilder builder;
    521   auto root = builder.initRoot<test::TestAnyPointer>();
    522 
    523   root.getAnyPointerField().setAs<List<uint32_t>>({12, 34, 56});
    524   EXPECT_TRUE(root.hasAnyPointerField());
    525 
    526   Orphan<DynamicValue> orphan =
    527       root.getAnyPointerField().disownAs<DynamicList>(Schema::from<List<uint32_t>>());
    528   EXPECT_EQ(DynamicValue::LIST, orphan.getType());
    529 
    530   checkList(orphan.getReader().as<List<uint32_t>>(), {12, 34, 56});
    531   checkList(orphan.get().as<List<uint32_t>>(), {12, 34, 56});
    532 
    533   {
    534     Orphan<DynamicList> listOrphan = orphan.releaseAs<DynamicList>();
    535     EXPECT_EQ(DynamicValue::UNKNOWN, orphan.getType());
    536     EXPECT_FALSE(listOrphan == nullptr);
    537     checkList<uint32_t>(listOrphan.getReader(), {12, 34, 56});
    538     checkList<uint32_t>(listOrphan.get(), {12, 34, 56});
    539     checkList(listOrphan.getReader().as<List<uint32_t>>(), {12, 34, 56});
    540     checkList(listOrphan.get().as<List<uint32_t>>(), {12, 34, 56});
    541 
    542     {
    543       Orphan<List<uint32_t>> typedOrphan = listOrphan.releaseAs<List<uint32_t>>();
    544       EXPECT_TRUE(listOrphan == nullptr);
    545       EXPECT_FALSE(typedOrphan == nullptr);
    546       checkList(typedOrphan.getReader(), {12, 34, 56});
    547       checkList(typedOrphan.get(), {12, 34, 56});
    548       orphan = kj::mv(typedOrphan);
    549       EXPECT_EQ(DynamicValue::LIST, orphan.getType());
    550       EXPECT_TRUE(typedOrphan == nullptr);
    551     }
    552   }
    553 
    554   {
    555     Orphan<List<uint32_t>> typedOrphan = orphan.releaseAs<List<uint32_t>>();
    556     checkList(typedOrphan.getReader(), {12, 34, 56});
    557     checkList(typedOrphan.get(), {12, 34, 56});
    558   }
    559 }
    560 
    561 TEST(Orphans, DynamicAnyPointer) {
    562   MallocMessageBuilder builder;
    563   auto root = builder.initRoot<test::TestAnyPointer>();
    564 
    565   initTestMessage(root.getAnyPointerField().initAs<TestAllTypes>());
    566   EXPECT_TRUE(root.hasAnyPointerField());
    567 
    568   Orphan<DynamicValue> orphan = root.getAnyPointerField().disown();
    569   EXPECT_EQ(DynamicValue::ANY_POINTER, orphan.getType());
    570 
    571   Orphan<AnyPointer> objectOrphan = orphan.releaseAs<AnyPointer>();
    572   checkTestMessage(objectOrphan.getAs<TestAllTypes>());
    573   checkDynamicTestMessage(objectOrphan.getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
    574 }
    575 
    576 TEST(Orphans, DynamicDisown) {
    577   MallocMessageBuilder builder;
    578   auto root = builder.initRoot<TestAllTypes>();
    579   initTestMessage(root);
    580 
    581   Orphan<TestAllTypes> dstOrphan =
    582       Orphanage::getForMessageContaining(root).newOrphan<TestAllTypes>();
    583   auto dst = dstOrphan.get();
    584 
    585   DynamicStruct::Builder dynamic = root;
    586   DynamicStruct::Builder dynamicDst = dst;
    587 
    588   for (auto field: dynamic.getSchema().getFields()) {
    589     dynamicDst.adopt(field, dynamic.disown(field));
    590   }
    591 
    592   checkTestMessageAllZero(root.asReader());
    593   checkTestMessage(dst.asReader());
    594 
    595   for (auto field: dynamic.getSchema().getFields()) {
    596     dynamicDst.adopt(field, dynamic.disown(field));
    597   }
    598 
    599   checkTestMessageAllZero(root.asReader());
    600   checkTestMessageAllZero(dst.asReader());
    601 }
    602 
    603 TEST(Orphans, DynamicDisownGroup) {
    604   MallocMessageBuilder builder;
    605   auto root = builder.initRoot<test::TestGroups>();
    606 
    607   auto bar = root.initGroups().initBar();
    608   bar.setCorge(123);
    609   bar.setGrault("foo");
    610   bar.setGarply(9876543210987ll);
    611 
    612   Orphan<test::TestGroups> dstOrphan =
    613       Orphanage::getForMessageContaining(root).newOrphan<test::TestGroups>();
    614   auto dst = dstOrphan.get();
    615 
    616   toDynamic(dst).adopt("groups", toDynamic(root).disown("groups"));
    617 
    618   EXPECT_EQ(test::TestGroups::Groups::FOO, root.getGroups().which());
    619 
    620   EXPECT_EQ(test::TestGroups::Groups::BAR, dst.getGroups().which());
    621   auto newBar = dst.getGroups().getBar();
    622   EXPECT_EQ(123, newBar.getCorge());
    623   EXPECT_EQ("foo", newBar.getGrault());
    624   EXPECT_EQ(9876543210987ll, newBar.getGarply());
    625 }
    626 #endif  // !CAPNP_LITE
    627 
    628 TEST(Orphans, OrphanageFromBuilder) {
    629   MallocMessageBuilder builder;
    630   auto root = builder.initRoot<TestAllTypes>();
    631 
    632   {
    633     Orphanage orphanage = Orphanage::getForMessageContaining(root);
    634     Orphan<TestAllTypes> orphan = orphanage.newOrphan<TestAllTypes>();
    635     initTestMessage(orphan.get());
    636     root.adoptStructField(kj::mv(orphan));
    637     checkTestMessage(root.asReader().getStructField());
    638   }
    639 
    640   {
    641     Orphanage orphanage = Orphanage::getForMessageContaining(root.initBoolList(3));
    642     Orphan<TestAllTypes> orphan = orphanage.newOrphan<TestAllTypes>();
    643     initTestMessage(orphan.get());
    644     root.adoptStructField(kj::mv(orphan));
    645     checkTestMessage(root.asReader().getStructField());
    646   }
    647 
    648 #if !CAPNP_LITE
    649   {
    650     Orphanage orphanage = Orphanage::getForMessageContaining(toDynamic(root));
    651     Orphan<TestAllTypes> orphan = orphanage.newOrphan<TestAllTypes>();
    652     initTestMessage(orphan.get());
    653     root.adoptStructField(kj::mv(orphan));
    654     checkTestMessage(root.asReader().getStructField());
    655   }
    656 
    657   {
    658     Orphanage orphanage = Orphanage::getForMessageContaining(toDynamic(root.initBoolList(3)));
    659     Orphan<TestAllTypes> orphan = orphanage.newOrphan<TestAllTypes>();
    660     initTestMessage(orphan.get());
    661     root.adoptStructField(kj::mv(orphan));
    662     checkTestMessage(root.asReader().getStructField());
    663   }
    664 #endif  // !CAPNP_LITE
    665 }
    666 
    667 static bool allZero(const word* begin, const word* end) {
    668   for (const byte* pos = reinterpret_cast<const byte*>(begin);
    669        pos < reinterpret_cast<const byte*>(end); ++pos) {
    670     if (*pos != 0) return false;
    671   }
    672   return true;
    673 }
    674 
    675 TEST(Orphans, StructsZerodAfterUse) {
    676   MallocMessageBuilder builder;
    677   auto root = builder.initRoot<TestAllTypes>();
    678 
    679   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    680   initTestMessage(root.initStructField());
    681   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    682 
    683   root.setTextField("foo");  // guard against overruns
    684 
    685   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    686 
    687   root.disownStructField();
    688 
    689   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    690 
    691   EXPECT_EQ("foo", root.getTextField());
    692 }
    693 
    694 TEST(Orphans, ListsZerodAfterUse) {
    695   MallocMessageBuilder builder;
    696   auto root = builder.initRoot<TestAllTypes>();
    697 
    698   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    699   root.setUInt32List({12, 34, 56});
    700   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    701 
    702   root.setTextField("foo");  // guard against overruns
    703 
    704   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    705 
    706   root.disownUInt32List();
    707 
    708   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    709 
    710   EXPECT_EQ("foo", root.getTextField());
    711 }
    712 
    713 TEST(Orphans, EmptyListsZerodAfterUse) {
    714   MallocMessageBuilder builder;
    715   auto root = builder.initRoot<TestAllTypes>();
    716 
    717   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    718   root.initUInt32List(0);
    719   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    720 
    721   root.setTextField("foo");  // guard against overruns
    722 
    723   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    724 
    725   root.disownUInt32List();
    726 
    727   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    728 
    729   EXPECT_EQ("foo", root.getTextField());
    730 }
    731 
    732 TEST(Orphans, StructListsZerodAfterUse) {
    733   MallocMessageBuilder builder;
    734   auto root = builder.initRoot<TestAllTypes>();
    735 
    736   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    737   {
    738     auto list = root.initStructList(2);
    739     initTestMessage(list[0]);
    740     initTestMessage(list[1]);
    741   }
    742   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    743 
    744   root.setTextField("foo");  // guard against overruns
    745 
    746   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    747 
    748   root.disownStructList();
    749 
    750   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    751 
    752   EXPECT_EQ("foo", root.getTextField());
    753 }
    754 
    755 TEST(Orphans, EmptyStructListsZerodAfterUse) {
    756   MallocMessageBuilder builder;
    757   auto root = builder.initRoot<TestAllTypes>();
    758 
    759   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    760   root.initStructList(0);
    761   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    762 
    763   root.setTextField("foo");  // guard against overruns
    764 
    765   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    766 
    767   root.disownStructList();
    768 
    769   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    770 
    771   EXPECT_EQ("foo", root.getTextField());
    772 }
    773 
    774 TEST(Orphans, TextZerodAfterUse) {
    775   MallocMessageBuilder builder;
    776   auto root = builder.initRoot<TestAllTypes>();
    777 
    778   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    779   root.setTextField("abcd123");
    780   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    781 
    782   root.setDataField(data("foo"));  // guard against overruns
    783 
    784   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    785 
    786   root.disownTextField();
    787 
    788   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    789 
    790   EXPECT_EQ(data("foo"), root.getDataField());
    791 }
    792 
    793 TEST(Orphans, DataZerodAfterUse) {
    794   MallocMessageBuilder builder;
    795   auto root = builder.initRoot<TestAllTypes>();
    796 
    797   const word* zerosStart = builder.getSegmentsForOutput()[0].end();
    798   root.setDataField(data("abcd123"));
    799   const word* zerosEnd = builder.getSegmentsForOutput()[0].end();
    800 
    801   root.setTextField("foo");  // guard against overruns
    802 
    803   EXPECT_EQ(1u, builder.getSegmentsForOutput().size());  // otherwise test is invalid
    804 
    805   root.disownDataField();
    806 
    807   EXPECT_TRUE(allZero(zerosStart, zerosEnd));
    808 
    809   EXPECT_EQ("foo", root.getTextField());
    810 }
    811 
    812 TEST(Orphans, FarPointer) {
    813   MallocMessageBuilder builder(0, AllocationStrategy::FIXED_SIZE);
    814   auto root = builder.initRoot<TestAllTypes>();
    815   auto child = root.initStructField();
    816   initTestMessage(child);
    817 
    818   auto orphan = root.disownStructField();
    819   EXPECT_FALSE(root.hasStructField());
    820   EXPECT_TRUE(orphan != nullptr);
    821   EXPECT_FALSE(orphan == nullptr);
    822 
    823   checkTestMessage(orphan.getReader());
    824   checkTestMessage(orphan.get());
    825 }
    826 
    827 TEST(Orphans, UpgradeStruct) {
    828   MallocMessageBuilder builder;
    829   auto root = builder.initRoot<test::TestAnyPointer>();
    830 
    831   auto old = root.getAnyPointerField().initAs<test::TestOldVersion>();
    832   old.setOld1(1234);
    833   old.setOld2("foo");
    834 
    835   auto orphan = root.getAnyPointerField().disownAs<test::TestNewVersion>();
    836 
    837   // Relocation has not occurred yet.
    838   old.setOld1(12345);
    839   EXPECT_EQ(12345, orphan.getReader().getOld1());
    840   EXPECT_EQ("foo", old.getOld2());
    841 
    842   // This will relocate the struct.
    843   auto newVersion = orphan.get();
    844 
    845   EXPECT_EQ(0, old.getOld1());
    846   EXPECT_EQ("", old.getOld2());
    847 
    848   EXPECT_EQ(12345, newVersion.getOld1());
    849   EXPECT_EQ("foo", newVersion.getOld2());
    850 }
    851 
    852 TEST(Orphans, UpgradeStructList) {
    853   MallocMessageBuilder builder;
    854   auto root = builder.initRoot<test::TestAnyPointer>();
    855 
    856   auto old = root.getAnyPointerField().initAs<List<test::TestOldVersion>>(2);
    857   old[0].setOld1(1234);
    858   old[0].setOld2("foo");
    859   old[1].setOld1(4321);
    860   old[1].setOld2("bar");
    861 
    862   auto orphan = root.getAnyPointerField().disownAs<List<test::TestNewVersion>>();
    863 
    864   // Relocation has not occurred yet.
    865   old[0].setOld1(12345);
    866   EXPECT_EQ(12345, orphan.getReader()[0].getOld1());
    867   EXPECT_EQ("foo", old[0].getOld2());
    868 
    869   // This will relocate the struct.
    870   auto newVersion = orphan.get();
    871 
    872   EXPECT_EQ(0, old[0].getOld1());
    873   EXPECT_EQ("", old[0].getOld2());
    874 
    875   EXPECT_EQ(12345, newVersion[0].getOld1());
    876   EXPECT_EQ("foo", newVersion[0].getOld2());
    877   EXPECT_EQ(4321, newVersion[1].getOld1());
    878   EXPECT_EQ("bar", newVersion[1].getOld2());
    879 }
    880 
    881 TEST(Orphans, DisownNull) {
    882   MallocMessageBuilder builder;
    883   auto root = builder.initRoot<TestAllTypes>();
    884 
    885   {
    886     Orphan<TestAllTypes> orphan = root.disownStructField();
    887     EXPECT_TRUE(orphan == nullptr);
    888 
    889     checkTestMessageAllZero(orphan.getReader());
    890     EXPECT_TRUE(orphan == nullptr);
    891 
    892     // get()ing the orphan allocates an object, for security reasons.
    893     checkTestMessageAllZero(orphan.get());
    894     EXPECT_FALSE(orphan == nullptr);
    895   }
    896 
    897   {
    898     Orphan<List<int32_t>> orphan = root.disownInt32List();
    899     EXPECT_TRUE(orphan == nullptr);
    900 
    901     EXPECT_EQ(0, orphan.getReader().size());
    902     EXPECT_TRUE(orphan == nullptr);
    903 
    904     EXPECT_EQ(0, orphan.get().size());
    905     EXPECT_TRUE(orphan == nullptr);
    906   }
    907 
    908   {
    909     Orphan<List<TestAllTypes>> orphan = root.disownStructList();
    910     EXPECT_TRUE(orphan == nullptr);
    911 
    912     EXPECT_EQ(0, orphan.getReader().size());
    913     EXPECT_TRUE(orphan == nullptr);
    914 
    915     EXPECT_EQ(0, orphan.get().size());
    916     EXPECT_TRUE(orphan == nullptr);
    917   }
    918 }
    919 
    920 TEST(Orphans, ReferenceExternalData) {
    921   MallocMessageBuilder builder;
    922 
    923   union {
    924     word align;
    925     byte data[50];
    926   };
    927 
    928   memset(data, 0x55, sizeof(data));
    929 
    930   auto orphan = builder.getOrphanage().referenceExternalData(Data::Builder(data, sizeof(data)));
    931 
    932   // Data was added as a new segment.
    933   {
    934     auto segments = builder.getSegmentsForOutput();
    935     ASSERT_EQ(2, segments.size());
    936     EXPECT_EQ(data, segments[1].asBytes().begin());
    937     EXPECT_EQ((sizeof(data) + 7) / 8, segments[1].size());
    938   }
    939 
    940   // Can't get builder because it's read-only.
    941   EXPECT_ANY_THROW(orphan.get());
    942 
    943   // Can get reader.
    944   {
    945     auto reader = orphan.getReader();
    946     EXPECT_EQ(data, reader.begin());
    947     EXPECT_EQ(sizeof(data), reader.size());
    948   }
    949 
    950   // Adopt into message tree.
    951   auto root = builder.getRoot<TestAllTypes>();
    952   root.adoptDataField(kj::mv(orphan));
    953 
    954   // Can't get child builder.
    955   EXPECT_ANY_THROW(root.getDataField());
    956 
    957   // Can get child reader.
    958   {
    959     auto reader = root.asReader().getDataField();
    960     EXPECT_EQ(data, reader.begin());
    961     EXPECT_EQ(sizeof(data), reader.size());
    962   }
    963 
    964   // Back to orphan.
    965   orphan = root.disownDataField();
    966 
    967   // Now the orphan may be pointing to a far pointer landing pad, so check that it still does the
    968   // right things.
    969 
    970   // Can't get builder because it's read-only.
    971   EXPECT_ANY_THROW(orphan.get());
    972 
    973   // Can get reader.
    974   {
    975     auto reader = orphan.getReader();
    976     EXPECT_EQ(data, reader.begin());
    977     EXPECT_EQ(sizeof(data), reader.size());
    978   }
    979 
    980   // Finally, let's abandon the orphan and check that this doesn't zero out the data.
    981   orphan = Orphan<Data>();
    982 
    983   for (byte b: data) {
    984     EXPECT_EQ(0x55, b);
    985   }
    986 }
    987 
    988 TEST(Orphans, ReferenceExternalData_NoZeroOnSet) {
    989   // Verify that an external blob is not zeroed by setFoo().
    990 
    991   union {
    992     word align;
    993     byte data[50];
    994   };
    995 
    996   memset(data, 0x55, sizeof(data));
    997 
    998   MallocMessageBuilder builder;
    999   auto root = builder.getRoot<TestAllTypes>();
   1000   root.adoptDataField(builder.getOrphanage().referenceExternalData(
   1001       Data::Builder(data, sizeof(data))));
   1002 
   1003   root.setDataField(Data::Builder());
   1004 
   1005   for (byte b: data) {
   1006     EXPECT_EQ(0x55, b);
   1007   }
   1008 }
   1009 
   1010 TEST(Orphans, ReferenceExternalData_NoZeroImmediateAbandon) {
   1011   // Verify that an external blob is not zeroed when abandoned immediately, without ever being
   1012   // adopted.
   1013 
   1014   union {
   1015     word align;
   1016     byte data[50];
   1017   };
   1018 
   1019   memset(data, 0x55, sizeof(data));
   1020 
   1021   MallocMessageBuilder builder;
   1022   builder.getOrphanage().referenceExternalData(Data::Builder(data, sizeof(data)));
   1023 
   1024   for (byte b: data) {
   1025     EXPECT_EQ(0x55, b);
   1026   }
   1027 }
   1028 
   1029 TEST(Orphans, TruncateData) {
   1030   MallocMessageBuilder message;
   1031   auto orphan = message.getOrphanage().newOrphan<Data>(17);
   1032   auto builder = orphan.get();
   1033   memset(builder.begin(), 123, builder.size());
   1034 
   1035   EXPECT_EQ(4, message.getSegmentsForOutput()[0].size());
   1036   orphan.truncate(2);
   1037   EXPECT_EQ(2, message.getSegmentsForOutput()[0].size());
   1038 
   1039   auto reader = orphan.getReader();
   1040   EXPECT_EQ(2, reader.size());
   1041   EXPECT_EQ(builder.begin(), reader.begin());
   1042 
   1043   EXPECT_EQ(123, builder[0]);
   1044   EXPECT_EQ(123, builder[1]);
   1045   EXPECT_EQ(0, builder[2]);
   1046   EXPECT_EQ(0, builder[3]);
   1047   EXPECT_EQ(0, builder[16]);
   1048 }
   1049 
   1050 TEST(Orphans, ExtendData) {
   1051   MallocMessageBuilder message;
   1052   auto orphan = message.getOrphanage().newOrphan<Data>(17);
   1053   auto builder = orphan.get();
   1054   memset(builder.begin(), 123, builder.size());
   1055 
   1056   EXPECT_EQ(4, message.getSegmentsForOutput()[0].size());
   1057   orphan.truncate(27);
   1058   EXPECT_EQ(5, message.getSegmentsForOutput()[0].size());
   1059 
   1060   auto reader = orphan.getReader();
   1061   EXPECT_EQ(27, reader.size());
   1062   EXPECT_EQ(builder.begin(), reader.begin());
   1063 
   1064   for (uint i = 0; i < 17; i++) {
   1065     EXPECT_EQ(123, reader[i]);
   1066   }
   1067   for (uint i = 17; i < 27; i++) {
   1068     EXPECT_EQ(0, reader[i]);
   1069   }
   1070 }
   1071 
   1072 TEST(Orphans, ExtendDataCopy) {
   1073   MallocMessageBuilder message;
   1074   auto orphan = message.getOrphanage().newOrphan<Data>(17);
   1075   auto builder = orphan.get();
   1076   memset(builder.begin(), 123, builder.size());
   1077 
   1078   auto orphan2 = message.getOrphanage().newOrphan<Data>(1);
   1079   orphan2.get()[0] = 32;
   1080 
   1081   orphan.truncate(27);
   1082 
   1083   auto reader = orphan.getReader();
   1084   EXPECT_EQ(27, reader.size());
   1085   EXPECT_NE(builder.begin(), reader.begin());
   1086 
   1087   for (uint i = 0; i < 17; i++) {
   1088     EXPECT_EQ(123, reader[i]);
   1089     EXPECT_EQ(0, builder[i]);
   1090   }
   1091   for (uint i = 17; i < 27; i++) {
   1092     EXPECT_EQ(0, reader[i]);
   1093   }
   1094 
   1095   EXPECT_EQ(32, orphan2.getReader()[0]);
   1096 }
   1097 
   1098 TEST(Orphans, ExtendDataFromEmpty) {
   1099   MallocMessageBuilder message;
   1100 
   1101   auto orphan = message.initRoot<TestAllTypes>().disownDataField();
   1102   orphan.truncate(3);
   1103 
   1104   auto reader = orphan.getReader();
   1105   EXPECT_EQ(3, reader.size());
   1106 
   1107   for (uint i = 0; i < 3; i++) {
   1108     EXPECT_EQ(0, reader[i]);
   1109   }
   1110 }
   1111 
   1112 TEST(Orphans, TruncateText) {
   1113   MallocMessageBuilder message;
   1114   auto orphan = message.getOrphanage().newOrphan<Text>(17);
   1115   auto builder = orphan.get();
   1116   memset(builder.begin(), 'a', builder.size());
   1117 
   1118   EXPECT_EQ(4, message.getSegmentsForOutput()[0].size());
   1119   orphan.truncate(2);
   1120   EXPECT_EQ(2, message.getSegmentsForOutput()[0].size());
   1121 
   1122   auto reader = orphan.getReader();
   1123   EXPECT_EQ(2, reader.size());
   1124   EXPECT_EQ(builder.begin(), reader.begin());
   1125 
   1126   EXPECT_EQ('a', builder[0]);
   1127   EXPECT_EQ('a', builder[1]);
   1128   EXPECT_EQ('\0', builder[2]);
   1129   EXPECT_EQ('\0', builder[3]);
   1130   EXPECT_EQ('\0', builder[16]);
   1131 }
   1132 
   1133 TEST(Orphans, ExtendText) {
   1134   MallocMessageBuilder message;
   1135   auto orphan = message.getOrphanage().newOrphan<Text>(17);
   1136   auto builder = orphan.get();
   1137   memset(builder.begin(), 'a', builder.size());
   1138 
   1139   EXPECT_EQ(4, message.getSegmentsForOutput()[0].size());
   1140   orphan.truncate(27);
   1141   EXPECT_EQ(5, message.getSegmentsForOutput()[0].size());
   1142 
   1143   auto reader = orphan.getReader();
   1144   EXPECT_EQ(27, reader.size());
   1145   EXPECT_EQ(builder.begin(), reader.begin());
   1146 
   1147   for (uint i = 0; i < 17; i++) {
   1148     EXPECT_EQ('a', reader[i]);
   1149   }
   1150   for (uint i = 17; i < 27; i++) {
   1151     EXPECT_EQ('\0', reader[i]);
   1152   }
   1153 }
   1154 
   1155 TEST(Orphans, ExtendTextCopy) {
   1156   MallocMessageBuilder message;
   1157   auto orphan = message.getOrphanage().newOrphan<Text>(17);
   1158   auto builder = orphan.get();
   1159   memset(builder.begin(), 'a', builder.size());
   1160 
   1161   auto orphan2 = message.getOrphanage().newOrphan<Data>(1);
   1162   orphan2.get()[0] = 32;
   1163 
   1164   orphan.truncate(27);
   1165 
   1166   auto reader = orphan.getReader();
   1167   EXPECT_EQ(27, reader.size());
   1168   EXPECT_NE(builder.begin(), reader.begin());
   1169 
   1170   for (uint i = 0; i < 17; i++) {
   1171     EXPECT_EQ('a', reader[i]);
   1172     EXPECT_EQ('\0', builder[i]);
   1173   }
   1174   for (uint i = 17; i < 27; i++) {
   1175     EXPECT_EQ('\0', reader[i]);
   1176   }
   1177 
   1178   EXPECT_EQ(32, orphan2.getReader()[0]);
   1179 }
   1180 
   1181 TEST(Orphans, ExtendTextFromEmpty) {
   1182   MallocMessageBuilder message;
   1183 
   1184   auto orphan = message.initRoot<TestAllTypes>().disownTextField();
   1185   orphan.truncate(3);
   1186 
   1187   auto reader = orphan.getReader();
   1188   EXPECT_EQ(3, reader.size());
   1189 
   1190   for (uint i = 0; i < 3; i++) {
   1191     EXPECT_EQ('\0', reader[i]);
   1192   }
   1193 }
   1194 
   1195 TEST(Orphans, TruncatePrimitiveList) {
   1196   MallocMessageBuilder message;
   1197   auto orphan = message.getOrphanage().newOrphan<List<uint32_t>>(7);
   1198   auto builder = orphan.get();
   1199   for (uint i = 0; i < 7; i++) {
   1200     builder.set(i, 123456789 + i);
   1201   }
   1202 
   1203   EXPECT_EQ(5, message.getSegmentsForOutput()[0].size());
   1204   orphan.truncate(3);
   1205   EXPECT_EQ(3, message.getSegmentsForOutput()[0].size());
   1206 
   1207   auto reader = orphan.getReader();
   1208   EXPECT_EQ(3, reader.size());
   1209 
   1210   for (uint i = 0; i < 3; i++) {
   1211     EXPECT_EQ(123456789 + i, builder[i]);
   1212     EXPECT_EQ(123456789 + i, reader[i]);
   1213   }
   1214   for (uint i = 3; i < 7; i++) {
   1215     EXPECT_EQ(0, builder[i]);
   1216   }
   1217 
   1218   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1219   // the reader.
   1220   builder.set(0, 321);
   1221   EXPECT_EQ(321, reader[0]);
   1222 }
   1223 
   1224 TEST(Orphans, ExtendPrimitiveList) {
   1225   MallocMessageBuilder message;
   1226   auto orphan = message.getOrphanage().newOrphan<List<uint32_t>>(7);
   1227   auto builder = orphan.get();
   1228   for (uint i = 0; i < 7; i++) {
   1229     builder.set(i, 123456789 + i);
   1230   }
   1231 
   1232   EXPECT_EQ(5, message.getSegmentsForOutput()[0].size());
   1233   orphan.truncate(11);
   1234   EXPECT_EQ(7, message.getSegmentsForOutput()[0].size());
   1235 
   1236   auto reader = orphan.getReader();
   1237   EXPECT_EQ(11, reader.size());
   1238 
   1239   for (uint i = 0; i < 7; i++) {
   1240     EXPECT_EQ(123456789 + i, reader[i]);
   1241     EXPECT_EQ(123456789 + i, builder[i]);
   1242   }
   1243   for (uint i = 7; i < 11; i++) {
   1244     EXPECT_EQ(0, reader[i]);
   1245   }
   1246 
   1247   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1248   // the reader.
   1249   builder.set(0, 321);
   1250   EXPECT_EQ(321, reader[0]);
   1251 }
   1252 
   1253 TEST(Orphans, ExtendPrimitiveListCopy) {
   1254   MallocMessageBuilder message;
   1255   auto orphan = message.getOrphanage().newOrphan<List<uint32_t>>(7);
   1256   auto builder = orphan.get();
   1257   for (uint i = 0; i < 7; i++) {
   1258     builder.set(i, 123456789 + i);
   1259   }
   1260 
   1261   auto orphan2 = message.getOrphanage().newOrphan<Data>(1);
   1262   orphan2.get()[0] = 32;
   1263 
   1264   orphan.truncate(11);
   1265 
   1266   auto reader = orphan.getReader();
   1267   EXPECT_EQ(11, reader.size());
   1268 
   1269   for (uint i = 0; i < 7; i++) {
   1270     EXPECT_EQ(123456789 + i, reader[i]);
   1271     EXPECT_EQ(0, builder[i]);
   1272   }
   1273   for (uint i = 7; i < 11; i++) {
   1274     EXPECT_EQ(0, reader[i]);
   1275   }
   1276 
   1277   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1278   // the reader.
   1279   builder.set(0, 321);
   1280   EXPECT_EQ(123456789, reader[0]);
   1281 
   1282   EXPECT_EQ(32, orphan2.getReader()[0]);
   1283 }
   1284 
   1285 TEST(Orphans, ExtendPointerListFromEmpty) {
   1286   MallocMessageBuilder message;
   1287 
   1288   auto orphan = message.initRoot<TestAllTypes>().disownUInt32List();
   1289   orphan.truncate(3);
   1290 
   1291   auto reader = orphan.getReader();
   1292   EXPECT_EQ(3, reader.size());
   1293 
   1294   for (uint i = 0; i < 3; i++) {
   1295     EXPECT_EQ(0, reader[i]);
   1296   }
   1297 }
   1298 
   1299 TEST(Orphans, TruncatePointerList) {
   1300   MallocMessageBuilder message;
   1301 
   1302   // Allocate data in advance so that the list itself is at the end of the segment.
   1303   kj::Vector<Orphan<Text>> pointers(7);
   1304   for (uint i = 0; i < 7; i++) {
   1305     pointers.add(message.getOrphanage().newOrphanCopy(Text::Reader(kj::str("foo", i))));
   1306   }
   1307   size_t sizeBeforeList = message.getSegmentsForOutput()[0].size();
   1308 
   1309   auto orphan = message.getOrphanage().newOrphan<List<Text>>(7);
   1310   auto builder = orphan.get();
   1311   for (uint i = 0; i < 7; i++) {
   1312     builder.adopt(i, kj::mv(pointers[i]));
   1313   }
   1314 
   1315   EXPECT_EQ(sizeBeforeList + 7, message.getSegmentsForOutput()[0].size());
   1316   orphan.truncate(3);
   1317   EXPECT_EQ(sizeBeforeList + 3, message.getSegmentsForOutput()[0].size());
   1318 
   1319   auto reader = orphan.getReader();
   1320   EXPECT_EQ(3, reader.size());
   1321 
   1322   for (uint i = 0; i < 3; i++) {
   1323     EXPECT_EQ(kj::str("foo", i), builder[i]);
   1324     EXPECT_EQ(kj::str("foo", i), reader[i]);
   1325   }
   1326   for (uint i = 3; i < 7; i++) {
   1327     EXPECT_TRUE(builder[i] == nullptr);
   1328   }
   1329 
   1330   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1331   // the reader.
   1332   builder.set(0, "bar");
   1333   EXPECT_EQ("bar", reader[0]);
   1334 }
   1335 
   1336 TEST(Orphans, ExtendPointerList) {
   1337   MallocMessageBuilder message;
   1338 
   1339   // Allocate data in advance so that the list itself is at the end of the segment.
   1340   kj::Vector<Orphan<Text>> pointers(7);
   1341   for (uint i = 0; i < 7; i++) {
   1342     pointers.add(message.getOrphanage().newOrphanCopy(Text::Reader(kj::str("foo", i))));
   1343   }
   1344   size_t sizeBeforeList = message.getSegmentsForOutput()[0].size();
   1345 
   1346   auto orphan = message.getOrphanage().newOrphan<List<Text>>(7);
   1347   auto builder = orphan.get();
   1348   for (uint i = 0; i < 7; i++) {
   1349     builder.adopt(i, kj::mv(pointers[i]));
   1350   }
   1351 
   1352   EXPECT_EQ(sizeBeforeList + 7, message.getSegmentsForOutput()[0].size());
   1353   orphan.truncate(11);
   1354   EXPECT_EQ(sizeBeforeList + 11, message.getSegmentsForOutput()[0].size());
   1355 
   1356   auto reader = orphan.getReader();
   1357   EXPECT_EQ(11, reader.size());
   1358 
   1359   for (uint i = 0; i < 7; i++) {
   1360     EXPECT_EQ(kj::str("foo", i), reader[i]);
   1361     EXPECT_EQ(kj::str("foo", i), builder[i]);
   1362   }
   1363   for (uint i = 7; i < 11; i++) {
   1364     EXPECT_TRUE(reader[i] == nullptr);
   1365   }
   1366 
   1367   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1368   // the reader.
   1369   builder.set(0, "bar");
   1370   EXPECT_EQ("bar", reader[0]);
   1371 }
   1372 
   1373 TEST(Orphans, ExtendPointerListCopy) {
   1374   MallocMessageBuilder message;
   1375 
   1376   // Allocate data in advance so that the list itself is at the end of the segment.
   1377   kj::Vector<Orphan<Text>> pointers(7);
   1378   for (uint i = 0; i < 7; i++) {
   1379     pointers.add(message.getOrphanage().newOrphanCopy(Text::Reader(kj::str("foo", i))));
   1380   }
   1381 
   1382   auto orphan = message.getOrphanage().newOrphan<List<Text>>(7);
   1383   auto builder = orphan.get();
   1384   for (uint i = 0; i < 7; i++) {
   1385     builder.adopt(i, kj::mv(pointers[i]));
   1386   }
   1387 
   1388   auto orphan2 = message.getOrphanage().newOrphan<Data>(1);
   1389   orphan2.get()[0] = 32;
   1390 
   1391   orphan.truncate(11);
   1392 
   1393   auto reader = orphan.getReader();
   1394   EXPECT_EQ(11, reader.size());
   1395 
   1396   for (uint i = 0; i < 7; i++) {
   1397     EXPECT_EQ(kj::str("foo", i), reader[i]);
   1398     EXPECT_TRUE(builder[i] == nullptr);
   1399   }
   1400   for (uint i = 7; i < 11; i++) {
   1401     EXPECT_TRUE(reader[i] == nullptr);
   1402   }
   1403 
   1404   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1405   // the reader.
   1406   builder.set(0, "bar");
   1407   EXPECT_EQ("foo0", reader[0]);
   1408 
   1409   EXPECT_EQ(32, orphan2.getReader()[0]);
   1410 }
   1411 
   1412 TEST(Orphans, ExtendPointerListFromEmpty) {
   1413   MallocMessageBuilder message;
   1414 
   1415   auto orphan = message.initRoot<TestAllTypes>().disownTextList();
   1416   orphan.truncate(3);
   1417 
   1418   auto reader = orphan.getReader();
   1419   EXPECT_EQ(3, reader.size());
   1420 
   1421   for (uint i = 0; i < 3; i++) {
   1422     EXPECT_EQ("", reader[i]);
   1423   }
   1424 }
   1425 
   1426 TEST(Orphans, TruncateStructList) {
   1427   MallocMessageBuilder message;
   1428 
   1429   // Allocate data in advance so that the list itself is at the end of the segment.
   1430   kj::Vector<Orphan<TestAllTypes>> pointers(7);
   1431   for (uint i = 0; i < 7; i++) {
   1432     auto o = message.getOrphanage().newOrphan<TestAllTypes>();
   1433     auto b = o.get();
   1434     b.setUInt32Field(123456789 + i);
   1435     b.setTextField(kj::str("foo", i));
   1436     b.setUInt8List({123, 45});
   1437     pointers.add(kj::mv(o));
   1438   }
   1439 
   1440   auto orphan = message.getOrphanage().newOrphan<List<TestAllTypes>>(7);
   1441   auto builder = orphan.get();
   1442   for (uint i = 0; i < 7; i++) {
   1443     builder.adoptWithCaveats(i, kj::mv(pointers[i]));
   1444   }
   1445 
   1446   size_t sizeBeforeTruncate = message.getSegmentsForOutput()[0].size();
   1447   orphan.truncate(3);
   1448   EXPECT_LT(message.getSegmentsForOutput()[0].size(), sizeBeforeTruncate);
   1449 
   1450   auto reader = orphan.getReader();
   1451   EXPECT_EQ(3, reader.size());
   1452 
   1453   for (uint i = 0; i < 3; i++) {
   1454     EXPECT_EQ(123456789 + i, reader[i].getUInt32Field());
   1455     EXPECT_EQ(kj::str("foo", i), reader[i].getTextField());
   1456     checkList(reader[i].getUInt8List(), {123, 45});
   1457 
   1458     EXPECT_EQ(123456789 + i, builder[i].getUInt32Field());
   1459     EXPECT_EQ(kj::str("foo", i), builder[i].getTextField());
   1460     checkList(builder[i].getUInt8List(), {123, 45});
   1461   }
   1462   for (uint i = 3; i < 7; i++) {
   1463     checkTestMessageAllZero(builder[i]);
   1464   }
   1465 
   1466   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1467   // the reader.
   1468   builder[0].setUInt32Field(321);
   1469   EXPECT_EQ(321, reader[0].getUInt32Field());
   1470 }
   1471 
   1472 TEST(Orphans, ExtendStructList) {
   1473   MallocMessageBuilder message;
   1474 
   1475   // Allocate data in advance so that the list itself is at the end of the segment.
   1476   kj::Vector<Orphan<TestAllTypes>> pointers(7);
   1477   for (uint i = 0; i < 7; i++) {
   1478     auto o = message.getOrphanage().newOrphan<TestAllTypes>();
   1479     auto b = o.get();
   1480     b.setUInt32Field(123456789 + i);
   1481     b.setTextField(kj::str("foo", i));
   1482     b.setUInt8List({123, 45});
   1483     pointers.add(kj::mv(o));
   1484   }
   1485 
   1486   auto orphan = message.getOrphanage().newOrphan<List<TestAllTypes>>(7);
   1487   auto builder = orphan.get();
   1488   for (uint i = 0; i < 7; i++) {
   1489     builder.adoptWithCaveats(i, kj::mv(pointers[i]));
   1490   }
   1491 
   1492   orphan.truncate(11);
   1493 
   1494   auto reader = orphan.getReader();
   1495   EXPECT_EQ(11, reader.size());
   1496 
   1497   for (uint i = 0; i < 7; i++) {
   1498     EXPECT_EQ(123456789 + i, reader[i].getUInt32Field());
   1499     EXPECT_EQ(kj::str("foo", i), reader[i].getTextField());
   1500     checkList(reader[i].getUInt8List(), {123, 45});
   1501 
   1502     EXPECT_EQ(123456789 + i, builder[i].getUInt32Field());
   1503     EXPECT_EQ(kj::str("foo", i), builder[i].getTextField());
   1504     checkList(builder[i].getUInt8List(), {123, 45});
   1505   }
   1506   for (uint i = 7; i < 11; i++) {
   1507     checkTestMessageAllZero(reader[i]);
   1508   }
   1509 
   1510   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1511   // the reader.
   1512   builder[0].setUInt32Field(321);
   1513   EXPECT_EQ(321, reader[0].getUInt32Field());
   1514 }
   1515 
   1516 TEST(Orphans, ExtendStructListCopy) {
   1517   MallocMessageBuilder message;
   1518 
   1519   // Allocate data in advance so that the list itself is at the end of the segment.
   1520   kj::Vector<Orphan<TestAllTypes>> pointers(7);
   1521   for (uint i = 0; i < 7; i++) {
   1522     auto o = message.getOrphanage().newOrphan<TestAllTypes>();
   1523     auto b = o.get();
   1524     b.setUInt32Field(123456789 + i);
   1525     b.setTextField(kj::str("foo", i));
   1526     b.setUInt8List({123, 45});
   1527     pointers.add(kj::mv(o));
   1528   }
   1529 
   1530   auto orphan = message.getOrphanage().newOrphan<List<TestAllTypes>>(7);
   1531   auto builder = orphan.get();
   1532   for (uint i = 0; i < 7; i++) {
   1533     builder.adoptWithCaveats(i, kj::mv(pointers[i]));
   1534   }
   1535 
   1536   auto orphan2 = message.getOrphanage().newOrphan<Data>(1);
   1537   orphan2.get()[0] = 32;
   1538 
   1539   orphan.truncate(11);
   1540 
   1541   auto reader = orphan.getReader();
   1542   EXPECT_EQ(11, reader.size());
   1543 
   1544   for (uint i = 0; i < 7; i++) {
   1545     EXPECT_EQ(123456789 + i, reader[i].getUInt32Field());
   1546     EXPECT_EQ(kj::str("foo", i), reader[i].getTextField());
   1547     checkList(reader[i].getUInt8List(), {123, 45});
   1548 
   1549     checkTestMessageAllZero(builder[i]);
   1550   }
   1551   for (uint i = 7; i < 11; i++) {
   1552     checkTestMessageAllZero(reader[i]);
   1553   }
   1554 
   1555   // Can't compare pointers directly, but we can check if builder modifications are visible using
   1556   // the reader.
   1557   builder[0].setUInt32Field(321);
   1558   EXPECT_EQ(123456789, reader[0].getUInt32Field());
   1559 
   1560   EXPECT_EQ(32, orphan2.getReader()[0]);
   1561 }
   1562 
   1563 TEST(Orphans, ExtendStructListFromEmpty) {
   1564   MallocMessageBuilder message;
   1565 
   1566   auto orphan = message.initRoot<TestAllTypes>().disownStructList();
   1567   orphan.truncate(3);
   1568 
   1569   auto reader = orphan.getReader();
   1570   EXPECT_EQ(3, reader.size());
   1571 
   1572   for (uint i = 0; i < 3; i++) {
   1573     checkTestMessageAllZero(reader[i]);
   1574   }
   1575 }
   1576 
   1577 template <typename ListBuilder>
   1578 void initList(ListBuilder builder,
   1579     std::initializer_list<ReaderFor<ListElementType<FromBuilder<ListBuilder>>>> values) {
   1580   KJ_ASSERT(builder.size() == values.size());
   1581   size_t i = 0;
   1582   for (auto& value: values) {
   1583     builder.set(i++, value);
   1584   }
   1585 }
   1586 
   1587 TEST(Orphans, ConcatenatePrimitiveLists) {
   1588   MallocMessageBuilder message;
   1589   auto orphanage = message.getOrphanage();
   1590 
   1591   auto list1 = orphanage.newOrphan<List<uint32_t>>(3);
   1592   initList(list1.get(), {12, 34, 56});
   1593 
   1594   auto list2 = orphanage.newOrphan<List<uint32_t>>(2);
   1595   initList(list2.get(), {78, 90});
   1596 
   1597   auto list3 = orphanage.newOrphan<List<uint32_t>>(4);
   1598   initList(list3.get(), {23, 45, 67, 89});
   1599 
   1600   List<uint32_t>::Reader lists[] = { list1.getReader(), list2.getReader(), list3.getReader() };
   1601   kj::ArrayPtr<List<uint32_t>::Reader> array = lists;
   1602 
   1603   auto cat = message.getOrphanage().newOrphanConcat(array);
   1604 
   1605   checkList(cat.getReader(), {12, 34, 56, 78, 90, 23, 45, 67, 89});
   1606 }
   1607 
   1608 TEST(Orphans, ConcatenateBitLists) {
   1609   MallocMessageBuilder message;
   1610   auto orphanage = message.getOrphanage();
   1611 
   1612   auto list1 = orphanage.newOrphan<List<bool>>(3);
   1613   initList(list1.get(), {true, true, false});
   1614 
   1615   auto list2 = orphanage.newOrphan<List<bool>>(2);
   1616   initList(list2.get(), {false, true});
   1617 
   1618   auto list3 = orphanage.newOrphan<List<bool>>(4);
   1619   initList(list3.get(), {false, false, true, false});
   1620 
   1621   List<bool>::Reader lists[] = { list1.getReader(), list2.getReader(), list3.getReader() };
   1622   kj::ArrayPtr<List<bool>::Reader> array = lists;
   1623 
   1624   auto cat = message.getOrphanage().newOrphanConcat(array);
   1625 
   1626   checkList(cat.getReader(), {true, true, false, false, true, false, false, true, false});
   1627 }
   1628 
   1629 TEST(Orphans, ConcatenatePointerLists) {
   1630   MallocMessageBuilder message;
   1631   auto orphanage = message.getOrphanage();
   1632 
   1633   auto list1 = orphanage.newOrphan<List<Text>>(3);
   1634   initList(list1.get(), {"foo", "bar", "baz"});
   1635 
   1636   auto list2 = orphanage.newOrphan<List<Text>>(2);
   1637   initList(list2.get(), {"qux", "corge"});
   1638 
   1639   auto list3 = orphanage.newOrphan<List<Text>>(4);
   1640   initList(list3.get(), {"grault", "garply", "waldo", "fred"});
   1641 
   1642   List<Text>::Reader lists[] = { list1.getReader(), list2.getReader(), list3.getReader() };
   1643   kj::ArrayPtr<List<Text>::Reader> array = lists;
   1644 
   1645   auto cat = message.getOrphanage().newOrphanConcat(array);
   1646 
   1647   checkList(cat.getReader(), {
   1648       "foo", "bar", "baz", "qux", "corge", "grault", "garply", "waldo", "fred"});
   1649 }
   1650 
   1651 TEST(Orphans, ConcatenateStructLists) {
   1652   // In this test, we not only concatenate two struct lists, but we concatenate in a list that
   1653   // contains a newer-than-expected version of the struct with extra fields, in order to verify
   1654   // that the new fields aren't lost.
   1655 
   1656   MallocMessageBuilder message;
   1657   auto orphanage = message.getOrphanage();
   1658 
   1659   auto orphan1 = orphanage.newOrphan<List<test::TestOldVersion>>(2);
   1660   auto list1 = orphan1.get();
   1661   list1[0].setOld1(12);
   1662   list1[0].setOld2("foo");
   1663   list1[1].setOld1(34);
   1664   list1[1].setOld2("bar");
   1665 
   1666   auto orphan2 = orphanage.newOrphan<test::TestAnyPointer>();
   1667   auto list2 = orphan2.get().getAnyPointerField().initAs<List<test::TestNewVersion>>(2);
   1668   list2[0].setOld1(56);
   1669   list2[0].setOld2("baz");
   1670   list2[0].setNew1(123);
   1671   list2[0].setNew2("corge");
   1672   list2[1].setOld1(78);
   1673   list2[1].setOld2("qux");
   1674   list2[1].setNew1(456);
   1675   list2[1].setNew2("grault");
   1676 
   1677   List<test::TestOldVersion>::Reader lists[] = {
   1678     orphan1.getReader(),
   1679     orphan2.getReader().getAnyPointerField().getAs<List<test::TestOldVersion>>()
   1680   };
   1681   kj::ArrayPtr<List<test::TestOldVersion>::Reader> array = lists;
   1682 
   1683   auto orphan3 = orphanage.newOrphan<test::TestAnyPointer>();
   1684   orphan3.get().getAnyPointerField().adopt(message.getOrphanage().newOrphanConcat(array));
   1685 
   1686   auto cat = orphan3.getReader().getAnyPointerField().getAs<List<test::TestNewVersion>>();
   1687   ASSERT_EQ(4, cat.size());
   1688 
   1689   EXPECT_EQ(12, cat[0].getOld1());
   1690   EXPECT_EQ("foo", cat[0].getOld2());
   1691   EXPECT_EQ(987, cat[0].getNew1());
   1692   EXPECT_FALSE(cat[0].hasNew2());
   1693 
   1694   EXPECT_EQ(34, cat[1].getOld1());
   1695   EXPECT_EQ("bar", cat[1].getOld2());
   1696   EXPECT_EQ(987, cat[1].getNew1());
   1697   EXPECT_FALSE(cat[1].hasNew2());
   1698 
   1699   EXPECT_EQ(56, cat[2].getOld1());
   1700   EXPECT_EQ("baz", cat[2].getOld2());
   1701   EXPECT_EQ(123, cat[2].getNew1());
   1702   EXPECT_EQ("corge", cat[2].getNew2());
   1703 
   1704   EXPECT_EQ(78, cat[3].getOld1());
   1705   EXPECT_EQ("qux", cat[3].getOld2());
   1706   EXPECT_EQ(456, cat[3].getNew1());
   1707   EXPECT_EQ("grault", cat[3].getNew2());
   1708 }
   1709 
   1710 TEST(Orphans, ConcatenateStructListsUpgradeFromPrimitive) {
   1711   // Like above, but we're "upgrading" a primitive list to a struct list.
   1712 
   1713   MallocMessageBuilder message;
   1714   auto orphanage = message.getOrphanage();
   1715 
   1716   auto orphan1 = orphanage.newOrphan<List<test::TestOldVersion>>(2);
   1717   auto list1 = orphan1.get();
   1718   list1[0].setOld1(12);
   1719   list1[0].setOld2("foo");
   1720   list1[1].setOld1(34);
   1721   list1[1].setOld2("bar");
   1722 
   1723   auto orphan2 = orphanage.newOrphan<test::TestAnyPointer>();
   1724   auto list2 = orphan2.get().getAnyPointerField().initAs<List<uint64_t>>(2);
   1725   initList(list2, {12345, 67890});
   1726 
   1727   List<test::TestOldVersion>::Reader lists[] = {
   1728     orphan1.getReader(),
   1729     orphan2.getReader().getAnyPointerField().getAs<List<test::TestOldVersion>>()
   1730   };
   1731   kj::ArrayPtr<List<test::TestOldVersion>::Reader> array = lists;
   1732 
   1733   auto orphan3 = message.getOrphanage().newOrphanConcat(array);
   1734   auto cat = orphan3.getReader();
   1735   ASSERT_EQ(4, cat.size());
   1736 
   1737   EXPECT_EQ(12, cat[0].getOld1());
   1738   EXPECT_EQ("foo", cat[0].getOld2());
   1739 
   1740   EXPECT_EQ(34, cat[1].getOld1());
   1741   EXPECT_EQ("bar", cat[1].getOld2());
   1742 
   1743   EXPECT_EQ(12345, cat[2].getOld1());
   1744   EXPECT_FALSE(cat[2].hasOld2());
   1745 
   1746   EXPECT_EQ(67890, cat[3].getOld1());
   1747   EXPECT_FALSE(cat[3].hasOld2());
   1748 }
   1749 
   1750 }  // namespace
   1751 }  // namespace _ (private)
   1752 }  // namespace capnp