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