encoding-test.c++ (74943B)
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 <capnp/test-import.capnp.h> 23 #include <capnp/test-import2.capnp.h> 24 #include "message.h" 25 #include <kj/debug.h> 26 #include <kj/compat/gtest.h> 27 #include "test-util.h" 28 #include "schema-lite.h" 29 #include "serialize-packed.h" 30 31 namespace capnp { 32 namespace _ { // private 33 namespace { 34 35 TEST(Encoding, AllTypes) { 36 MallocMessageBuilder builder; 37 38 initTestMessage(builder.initRoot<TestAllTypes>()); 39 checkTestMessage(builder.getRoot<TestAllTypes>()); 40 checkTestMessage(builder.getRoot<TestAllTypes>().asReader()); 41 42 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 43 44 checkTestMessage(reader.getRoot<TestAllTypes>()); 45 46 ASSERT_EQ(1u, builder.getSegmentsForOutput().size()); 47 48 checkTestMessage(readMessageUnchecked<TestAllTypes>(builder.getSegmentsForOutput()[0].begin())); 49 50 EXPECT_EQ(builder.getSegmentsForOutput()[0].size() - 1, // -1 for root pointer 51 reader.getRoot<TestAllTypes>().totalSize().wordCount); 52 } 53 54 TEST(Encoding, AllTypesMultiSegment) { 55 MallocMessageBuilder builder(0, AllocationStrategy::FIXED_SIZE); 56 57 initTestMessage(builder.initRoot<TestAllTypes>()); 58 checkTestMessage(builder.getRoot<TestAllTypes>()); 59 checkTestMessage(builder.getRoot<TestAllTypes>().asReader()); 60 61 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 62 63 checkTestMessage(reader.getRoot<TestAllTypes>()); 64 } 65 66 TEST(Encoding, Defaults) { 67 AlignedData<1> nullRoot = {{0, 0, 0, 0, 0, 0, 0, 0}}; 68 kj::ArrayPtr<const word> segments[1] = {kj::arrayPtr(nullRoot.words, 1)}; 69 SegmentArrayMessageReader reader(kj::arrayPtr(segments, 1)); 70 71 checkTestMessage(reader.getRoot<TestDefaults>()); 72 checkTestMessage(readMessageUnchecked<TestDefaults>(nullRoot.words)); 73 74 checkTestMessage(TestDefaults::Reader()); 75 } 76 77 TEST(Encoding, DefaultInitialization) { 78 MallocMessageBuilder builder; 79 80 checkTestMessage(builder.getRoot<TestDefaults>()); // first pass initializes to defaults 81 checkTestMessage(builder.getRoot<TestDefaults>().asReader()); 82 83 checkTestMessage(builder.getRoot<TestDefaults>()); // second pass just reads the initialized structure 84 checkTestMessage(builder.getRoot<TestDefaults>().asReader()); 85 86 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 87 88 checkTestMessage(reader.getRoot<TestDefaults>()); 89 } 90 91 TEST(Encoding, DefaultInitializationMultiSegment) { 92 MallocMessageBuilder builder(0, AllocationStrategy::FIXED_SIZE); 93 94 // first pass initializes to defaults 95 checkTestMessage(builder.getRoot<TestDefaults>()); 96 checkTestMessage(builder.getRoot<TestDefaults>().asReader()); 97 98 // second pass just reads the initialized structure 99 checkTestMessage(builder.getRoot<TestDefaults>()); 100 checkTestMessage(builder.getRoot<TestDefaults>().asReader()); 101 102 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 103 104 checkTestMessage(reader.getRoot<TestDefaults>()); 105 } 106 107 TEST(Encoding, DefaultsFromEmptyMessage) { 108 AlignedData<1> emptyMessage = {{0, 0, 0, 0, 0, 0, 0, 0}}; 109 110 kj::ArrayPtr<const word> segments[1] = {kj::arrayPtr(emptyMessage.words, 1)}; 111 SegmentArrayMessageReader reader(kj::arrayPtr(segments, 1)); 112 113 checkTestMessage(reader.getRoot<TestDefaults>()); 114 checkTestMessage(readMessageUnchecked<TestDefaults>(emptyMessage.words)); 115 } 116 117 TEST(Encoding, Unions) { 118 MallocMessageBuilder builder; 119 TestUnion::Builder root = builder.getRoot<TestUnion>(); 120 121 EXPECT_EQ(TestUnion::Union0::U0F0S0, root.getUnion0().which()); 122 EXPECT_EQ(VOID, root.getUnion0().getU0f0s0()); 123 EXPECT_DEBUG_ANY_THROW(root.getUnion0().getU0f0s1()); 124 125 root.getUnion0().setU0f0s1(true); 126 EXPECT_EQ(TestUnion::Union0::U0F0S1, root.getUnion0().which()); 127 EXPECT_TRUE(root.getUnion0().getU0f0s1()); 128 EXPECT_DEBUG_ANY_THROW(root.getUnion0().getU0f0s0()); 129 130 root.getUnion0().setU0f0s8(123); 131 EXPECT_EQ(TestUnion::Union0::U0F0S8, root.getUnion0().which()); 132 EXPECT_EQ(123, root.getUnion0().getU0f0s8()); 133 EXPECT_DEBUG_ANY_THROW(root.getUnion0().getU0f0s1()); 134 } 135 136 struct UnionState { 137 uint discriminants[4]; 138 int dataOffset; 139 140 UnionState(std::initializer_list<uint> discriminants, int dataOffset) 141 : dataOffset(dataOffset) { 142 memcpy(this->discriminants, discriminants.begin(), sizeof(this->discriminants)); 143 } 144 145 bool operator==(const UnionState& other) const { 146 for (uint i = 0; i < 4; i++) { 147 if (discriminants[i] != other.discriminants[i]) { 148 return false; 149 } 150 } 151 152 return dataOffset == other.dataOffset; 153 } 154 }; 155 156 kj::String KJ_STRINGIFY(const UnionState& us) { 157 return kj::str("UnionState({", kj::strArray(us.discriminants, ", "), "}, ", us.dataOffset, ")"); 158 } 159 160 template <typename StructType, typename Func> 161 UnionState initUnion(Func&& initializer) { 162 // Use the given setter to initialize the given union field and then return a struct indicating 163 // the location of the data that was written as well as the values of the four union 164 // discriminants. 165 166 MallocMessageBuilder builder; 167 initializer(builder.getRoot<StructType>()); 168 kj::ArrayPtr<const word> segment = builder.getSegmentsForOutput()[0]; 169 170 KJ_ASSERT(segment.size() > 2, segment.size()); 171 172 // Find the offset of the first set bit after the union discriminants. 173 int offset = 0; 174 for (const uint8_t* p = reinterpret_cast<const uint8_t*>(segment.begin() + 2); 175 p < reinterpret_cast<const uint8_t*>(segment.end()); p++) { 176 if (*p != 0) { 177 uint8_t bits = *p; 178 while ((bits & 1) == 0) { 179 ++offset; 180 bits >>= 1; 181 } 182 goto found; 183 } 184 offset += 8; 185 } 186 offset = -1; 187 188 found: 189 const uint8_t* discriminants = reinterpret_cast<const uint8_t*>(segment.begin() + 1); 190 return UnionState({discriminants[0], discriminants[2], discriminants[4], discriminants[6]}, 191 offset); 192 } 193 194 TEST(Encoding, UnionLayout) { 195 #define INIT_UNION(setter) \ 196 initUnion<TestUnion>([](TestUnion::Builder b) {b.setter;}) 197 198 EXPECT_EQ(UnionState({ 0,0,0,0}, -1), INIT_UNION(getUnion0().setU0f0s0(VOID))); 199 EXPECT_EQ(UnionState({ 1,0,0,0}, 0), INIT_UNION(getUnion0().setU0f0s1(1))); 200 EXPECT_EQ(UnionState({ 2,0,0,0}, 0), INIT_UNION(getUnion0().setU0f0s8(1))); 201 EXPECT_EQ(UnionState({ 3,0,0,0}, 0), INIT_UNION(getUnion0().setU0f0s16(1))); 202 EXPECT_EQ(UnionState({ 4,0,0,0}, 0), INIT_UNION(getUnion0().setU0f0s32(1))); 203 EXPECT_EQ(UnionState({ 5,0,0,0}, 0), INIT_UNION(getUnion0().setU0f0s64(1))); 204 EXPECT_EQ(UnionState({ 6,0,0,0}, 448), INIT_UNION(getUnion0().setU0f0sp("1"))); 205 206 EXPECT_EQ(UnionState({ 7,0,0,0}, -1), INIT_UNION(getUnion0().setU0f1s0(VOID))); 207 EXPECT_EQ(UnionState({ 8,0,0,0}, 0), INIT_UNION(getUnion0().setU0f1s1(1))); 208 EXPECT_EQ(UnionState({ 9,0,0,0}, 0), INIT_UNION(getUnion0().setU0f1s8(1))); 209 EXPECT_EQ(UnionState({10,0,0,0}, 0), INIT_UNION(getUnion0().setU0f1s16(1))); 210 EXPECT_EQ(UnionState({11,0,0,0}, 0), INIT_UNION(getUnion0().setU0f1s32(1))); 211 EXPECT_EQ(UnionState({12,0,0,0}, 0), INIT_UNION(getUnion0().setU0f1s64(1))); 212 EXPECT_EQ(UnionState({13,0,0,0}, 448), INIT_UNION(getUnion0().setU0f1sp("1"))); 213 214 EXPECT_EQ(UnionState({0, 0,0,0}, -1), INIT_UNION(getUnion1().setU1f0s0(VOID))); 215 EXPECT_EQ(UnionState({0, 1,0,0}, 65), INIT_UNION(getUnion1().setU1f0s1(1))); 216 EXPECT_EQ(UnionState({0, 2,0,0}, 65), INIT_UNION(getUnion1().setU1f1s1(1))); 217 EXPECT_EQ(UnionState({0, 3,0,0}, 72), INIT_UNION(getUnion1().setU1f0s8(1))); 218 EXPECT_EQ(UnionState({0, 4,0,0}, 72), INIT_UNION(getUnion1().setU1f1s8(1))); 219 EXPECT_EQ(UnionState({0, 5,0,0}, 80), INIT_UNION(getUnion1().setU1f0s16(1))); 220 EXPECT_EQ(UnionState({0, 6,0,0}, 80), INIT_UNION(getUnion1().setU1f1s16(1))); 221 EXPECT_EQ(UnionState({0, 7,0,0}, 96), INIT_UNION(getUnion1().setU1f0s32(1))); 222 EXPECT_EQ(UnionState({0, 8,0,0}, 96), INIT_UNION(getUnion1().setU1f1s32(1))); 223 EXPECT_EQ(UnionState({0, 9,0,0}, 128), INIT_UNION(getUnion1().setU1f0s64(1))); 224 EXPECT_EQ(UnionState({0,10,0,0}, 128), INIT_UNION(getUnion1().setU1f1s64(1))); 225 EXPECT_EQ(UnionState({0,11,0,0}, 512), INIT_UNION(getUnion1().setU1f0sp("1"))); 226 EXPECT_EQ(UnionState({0,12,0,0}, 512), INIT_UNION(getUnion1().setU1f1sp("1"))); 227 228 EXPECT_EQ(UnionState({0,13,0,0}, -1), INIT_UNION(getUnion1().setU1f2s0(VOID))); 229 EXPECT_EQ(UnionState({0,14,0,0}, 65), INIT_UNION(getUnion1().setU1f2s1(1))); 230 EXPECT_EQ(UnionState({0,15,0,0}, 72), INIT_UNION(getUnion1().setU1f2s8(1))); 231 EXPECT_EQ(UnionState({0,16,0,0}, 80), INIT_UNION(getUnion1().setU1f2s16(1))); 232 EXPECT_EQ(UnionState({0,17,0,0}, 96), INIT_UNION(getUnion1().setU1f2s32(1))); 233 EXPECT_EQ(UnionState({0,18,0,0}, 128), INIT_UNION(getUnion1().setU1f2s64(1))); 234 EXPECT_EQ(UnionState({0,19,0,0}, 512), INIT_UNION(getUnion1().setU1f2sp("1"))); 235 236 EXPECT_EQ(UnionState({0,0,0,0}, 192), INIT_UNION(getUnion2().setU2f0s1(1))); 237 EXPECT_EQ(UnionState({0,0,0,0}, 193), INIT_UNION(getUnion3().setU3f0s1(1))); 238 EXPECT_EQ(UnionState({0,0,1,0}, 200), INIT_UNION(getUnion2().setU2f0s8(1))); 239 EXPECT_EQ(UnionState({0,0,0,1}, 208), INIT_UNION(getUnion3().setU3f0s8(1))); 240 EXPECT_EQ(UnionState({0,0,2,0}, 224), INIT_UNION(getUnion2().setU2f0s16(1))); 241 EXPECT_EQ(UnionState({0,0,0,2}, 240), INIT_UNION(getUnion3().setU3f0s16(1))); 242 EXPECT_EQ(UnionState({0,0,3,0}, 256), INIT_UNION(getUnion2().setU2f0s32(1))); 243 EXPECT_EQ(UnionState({0,0,0,3}, 288), INIT_UNION(getUnion3().setU3f0s32(1))); 244 EXPECT_EQ(UnionState({0,0,4,0}, 320), INIT_UNION(getUnion2().setU2f0s64(1))); 245 EXPECT_EQ(UnionState({0,0,0,4}, 384), INIT_UNION(getUnion3().setU3f0s64(1))); 246 247 #undef INIT_UNION 248 } 249 250 TEST(Encoding, UnnamedUnion) { 251 MallocMessageBuilder builder; 252 auto root = builder.initRoot<test::TestUnnamedUnion>(); 253 EXPECT_EQ(test::TestUnnamedUnion::FOO, root.which()); 254 255 root.setBar(321); 256 EXPECT_EQ(test::TestUnnamedUnion::BAR, root.which()); 257 EXPECT_EQ(test::TestUnnamedUnion::BAR, root.asReader().which()); 258 EXPECT_EQ(321u, root.getBar()); 259 EXPECT_EQ(321u, root.asReader().getBar()); 260 EXPECT_DEBUG_ANY_THROW(root.getFoo()); 261 EXPECT_DEBUG_ANY_THROW(root.asReader().getFoo()); 262 263 root.setFoo(123); 264 EXPECT_EQ(test::TestUnnamedUnion::FOO, root.which()); 265 EXPECT_EQ(test::TestUnnamedUnion::FOO, root.asReader().which()); 266 EXPECT_EQ(123u, root.getFoo()); 267 EXPECT_EQ(123u, root.asReader().getFoo()); 268 EXPECT_DEBUG_ANY_THROW(root.getBar()); 269 EXPECT_DEBUG_ANY_THROW(root.asReader().getBar()); 270 271 #if !CAPNP_LITE 272 StructSchema schema = Schema::from<test::TestUnnamedUnion>(); 273 274 // The discriminant is allocated just before allocating "bar". 275 EXPECT_EQ(2u, schema.getProto().getStruct().getDiscriminantOffset()); 276 EXPECT_EQ(0u, schema.getFieldByName("foo").getProto().getSlot().getOffset()); 277 EXPECT_EQ(2u, schema.getFieldByName("bar").getProto().getSlot().getOffset()); 278 #endif // !CAPNP_LITE 279 } 280 281 TEST(Encoding, Groups) { 282 MallocMessageBuilder builder; 283 auto root = builder.initRoot<test::TestGroups>(); 284 285 { 286 auto foo = root.getGroups().initFoo(); 287 foo.setCorge(12345678); 288 foo.setGrault(123456789012345ll); 289 foo.setGarply("foobar"); 290 291 EXPECT_EQ(12345678, foo.getCorge()); 292 EXPECT_EQ(123456789012345ll, foo.getGrault()); 293 EXPECT_EQ("foobar", foo.getGarply()); 294 } 295 296 { 297 auto bar = root.getGroups().initBar(); 298 bar.setCorge(23456789); 299 bar.setGrault("barbaz"); 300 bar.setGarply(234567890123456ll); 301 302 EXPECT_EQ(23456789, bar.getCorge()); 303 EXPECT_EQ("barbaz", bar.getGrault()); 304 EXPECT_EQ(234567890123456ll, bar.getGarply()); 305 } 306 307 { 308 auto baz = root.getGroups().initBaz(); 309 baz.setCorge(34567890); 310 baz.setGrault("bazqux"); 311 baz.setGarply("quxquux"); 312 313 EXPECT_EQ(34567890, baz.getCorge()); 314 EXPECT_EQ("bazqux", baz.getGrault()); 315 EXPECT_EQ("quxquux", baz.getGarply()); 316 } 317 } 318 319 TEST(Encoding, InterleavedGroups) { 320 MallocMessageBuilder builder; 321 auto root = builder.initRoot<test::TestInterleavedGroups>(); 322 323 // Init both groups to different values. 324 { 325 auto group = root.getGroup1(); 326 group.setFoo(12345678u); 327 group.setBar(123456789012345llu); 328 auto corge = group.initCorge(); 329 corge.setGrault(987654321098765llu); 330 corge.setGarply(12345u); 331 corge.setPlugh("plugh"); 332 corge.setXyzzy("xyzzy"); 333 group.setWaldo("waldo"); 334 } 335 336 { 337 auto group = root.getGroup2(); 338 group.setFoo(23456789u); 339 group.setBar(234567890123456llu); 340 auto corge = group.initCorge(); 341 corge.setGrault(876543210987654llu); 342 corge.setGarply(23456u); 343 corge.setPlugh("hgulp"); 344 corge.setXyzzy("yzzyx"); 345 group.setWaldo("odlaw"); 346 } 347 348 // Check group1 is still set correctly. 349 { 350 auto group = root.asReader().getGroup1(); 351 EXPECT_EQ(12345678u, group.getFoo()); 352 EXPECT_EQ(123456789012345llu, group.getBar()); 353 auto corge = group.getCorge(); 354 EXPECT_EQ(987654321098765llu, corge.getGrault()); 355 EXPECT_EQ(12345u, corge.getGarply()); 356 EXPECT_EQ("plugh", corge.getPlugh()); 357 EXPECT_EQ("xyzzy", corge.getXyzzy()); 358 EXPECT_EQ("waldo", group.getWaldo()); 359 } 360 361 // Zero out group 1 and see if it is zero'd. 362 { 363 auto group = root.initGroup1().asReader(); 364 EXPECT_EQ(0u, group.getFoo()); 365 EXPECT_EQ(0u, group.getBar()); 366 EXPECT_EQ(test::TestInterleavedGroups::Group1::QUX, group.which()); 367 EXPECT_EQ(0u, group.getQux()); 368 EXPECT_FALSE(group.hasWaldo()); 369 } 370 371 // Group 2 should not have been touched. 372 { 373 auto group = root.asReader().getGroup2(); 374 EXPECT_EQ(23456789u, group.getFoo()); 375 EXPECT_EQ(234567890123456llu, group.getBar()); 376 auto corge = group.getCorge(); 377 EXPECT_EQ(876543210987654llu, corge.getGrault()); 378 EXPECT_EQ(23456u, corge.getGarply()); 379 EXPECT_EQ("hgulp", corge.getPlugh()); 380 EXPECT_EQ("yzzyx", corge.getXyzzy()); 381 EXPECT_EQ("odlaw", group.getWaldo()); 382 } 383 } 384 385 TEST(Encoding, UnionDefault) { 386 MallocMessageBuilder builder; 387 TestUnionDefaults::Reader reader = builder.getRoot<TestUnionDefaults>().asReader(); 388 389 { 390 auto field = reader.getS16s8s64s8Set(); 391 EXPECT_EQ(TestUnion::Union0::U0F0S16, field.getUnion0().which()); 392 EXPECT_EQ(TestUnion::Union1::U1F0S8 , field.getUnion1().which()); 393 EXPECT_EQ(TestUnion::Union2::U2F0S64, field.getUnion2().which()); 394 EXPECT_EQ(TestUnion::Union3::U3F0S8 , field.getUnion3().which()); 395 EXPECT_EQ(321, field.getUnion0().getU0f0s16()); 396 EXPECT_EQ(123, field.getUnion1().getU1f0s8()); 397 EXPECT_EQ(12345678901234567ll, field.getUnion2().getU2f0s64()); 398 EXPECT_EQ(55, field.getUnion3().getU3f0s8()); 399 } 400 401 { 402 auto field = reader.getS0sps1s32Set(); 403 EXPECT_EQ(TestUnion::Union0::U0F1S0 , field.getUnion0().which()); 404 EXPECT_EQ(TestUnion::Union1::U1F0SP , field.getUnion1().which()); 405 EXPECT_EQ(TestUnion::Union2::U2F0S1 , field.getUnion2().which()); 406 EXPECT_EQ(TestUnion::Union3::U3F0S32, field.getUnion3().which()); 407 EXPECT_EQ(VOID, field.getUnion0().getU0f1s0()); 408 EXPECT_EQ("foo", field.getUnion1().getU1f0sp()); 409 EXPECT_EQ(true, field.getUnion2().getU2f0s1()); 410 EXPECT_EQ(12345678, field.getUnion3().getU3f0s32()); 411 } 412 413 { 414 auto field = reader.getUnnamed1(); 415 EXPECT_EQ(test::TestUnnamedUnion::FOO, field.which()); 416 EXPECT_EQ(123u, field.getFoo()); 417 EXPECT_FALSE(field.hasBefore()); 418 EXPECT_FALSE(field.hasAfter()); 419 } 420 421 { 422 auto field = reader.getUnnamed2(); 423 EXPECT_EQ(test::TestUnnamedUnion::BAR, field.which()); 424 EXPECT_EQ(321u, field.getBar()); 425 EXPECT_EQ("foo", field.getBefore()); 426 EXPECT_EQ("bar", field.getAfter()); 427 } 428 } 429 430 // ======================================================================================= 431 432 TEST(Encoding, ListDefaults) { 433 MallocMessageBuilder builder; 434 TestListDefaults::Builder root = builder.getRoot<TestListDefaults>(); 435 436 checkTestMessage(root.asReader()); 437 checkTestMessage(root); 438 checkTestMessage(root.asReader()); 439 } 440 441 TEST(Encoding, BuildListDefaults) { 442 MallocMessageBuilder builder; 443 TestListDefaults::Builder root = builder.getRoot<TestListDefaults>(); 444 445 initTestMessage(root); 446 checkTestMessage(root.asReader()); 447 checkTestMessage(root); 448 checkTestMessage(root.asReader()); 449 } 450 451 TEST(Encoding, SmallStructLists) { 452 // In this test, we will manually initialize TestListDefaults.lists to match the default 453 // value and verify that we end up with the same encoding that the compiler produces. 454 455 MallocMessageBuilder builder; 456 auto root = builder.getRoot<TestListDefaults>(); 457 auto sl = root.initLists(); 458 459 // Verify that all the lists are actually empty. 460 EXPECT_EQ(0u, sl.getList0 ().size()); 461 EXPECT_EQ(0u, sl.getList1 ().size()); 462 EXPECT_EQ(0u, sl.getList8 ().size()); 463 EXPECT_EQ(0u, sl.getList16().size()); 464 EXPECT_EQ(0u, sl.getList32().size()); 465 EXPECT_EQ(0u, sl.getList64().size()); 466 EXPECT_EQ(0u, sl.getListP ().size()); 467 EXPECT_EQ(0u, sl.getInt32ListList().size()); 468 EXPECT_EQ(0u, sl.getTextListList().size()); 469 EXPECT_EQ(0u, sl.getStructListList().size()); 470 471 { auto l = sl.initList0 (2); l[0].setF(VOID); l[1].setF(VOID); } 472 { auto l = sl.initList1 (4); l[0].setF(true); l[1].setF(false); 473 l[2].setF(true); l[3].setF(true); } 474 { auto l = sl.initList8 (2); l[0].setF(123u); l[1].setF(45u); } 475 { auto l = sl.initList16(2); l[0].setF(12345u); l[1].setF(6789u); } 476 { auto l = sl.initList32(2); l[0].setF(123456789u); l[1].setF(234567890u); } 477 { auto l = sl.initList64(2); l[0].setF(1234567890123456u); l[1].setF(2345678901234567u); } 478 { auto l = sl.initListP (2); l[0].setF("foo"); l[1].setF("bar"); } 479 480 { 481 auto l = sl.initInt32ListList(3); 482 l.set(0, {1, 2, 3}); 483 l.set(1, {4, 5}); 484 l.set(2, {12341234}); 485 } 486 487 { 488 auto l = sl.initTextListList(3); 489 l.set(0, {"foo", "bar"}); 490 l.set(1, {"baz"}); 491 l.set(2, {"qux", "corge"}); 492 } 493 494 { 495 auto l = sl.initStructListList(2); 496 l.init(0, 2); 497 l.init(1, 1); 498 499 l[0][0].setInt32Field(123); 500 l[0][1].setInt32Field(456); 501 l[1][0].setInt32Field(789); 502 } 503 504 kj::ArrayPtr<const word> segment = builder.getSegmentsForOutput()[0]; 505 506 // Initialize another message such that it copies the default value for that field. 507 MallocMessageBuilder defaultBuilder; 508 defaultBuilder.getRoot<TestListDefaults>().getLists(); 509 kj::ArrayPtr<const word> defaultSegment = defaultBuilder.getSegmentsForOutput()[0]; 510 511 // Should match... 512 EXPECT_EQ(defaultSegment.size(), segment.size()); 513 514 for (size_t i = 0; i < kj::min(segment.size(), defaultSegment.size()); i++) { 515 EXPECT_EQ(reinterpret_cast<const uint64_t*>(defaultSegment.begin())[i], 516 reinterpret_cast<const uint64_t*>(segment.begin())[i]); 517 } 518 } 519 520 TEST(Encoding, SetListToEmpty) { 521 // Test initializing list fields from various ways of constructing zero-sized lists. 522 // At one point this would often fail because the lists would have ElementSize::VOID which is 523 // incompatible with other list sizes. 524 525 #define ALL_LIST_TYPES(MACRO) \ 526 MACRO(Void, Void) \ 527 MACRO(Bool, bool) \ 528 MACRO(UInt8, uint8_t) \ 529 MACRO(UInt16, uint16_t) \ 530 MACRO(UInt32, uint32_t) \ 531 MACRO(UInt64, uint64_t) \ 532 MACRO(Int8, int8_t) \ 533 MACRO(Int16, int16_t) \ 534 MACRO(Int32, int32_t) \ 535 MACRO(Int64, int64_t) \ 536 MACRO(Float32, float) \ 537 MACRO(Float64, double) \ 538 MACRO(Text, Text) \ 539 MACRO(Data, Data) \ 540 MACRO(Struct, TestAllTypes) 541 542 #define SET_FROM_READER_ACCESSOR(name, type) \ 543 root.set##name##List(reader.get##name##List()); 544 545 #define SET_FROM_BUILDER_ACCESSOR(name, type) \ 546 root.set##name##List(root.get##name##List()); 547 548 #define SET_FROM_READER_CONSTRUCTOR(name, type) \ 549 root.set##name##List(List<type>::Reader()); 550 551 #define SET_FROM_BUILDER_CONSTRUCTOR(name, type) \ 552 root.set##name##List(List<type>::Builder()); 553 554 #define CHECK_EMPTY_NONNULL(name, type) \ 555 EXPECT_TRUE(root.has##name##List()); \ 556 EXPECT_EQ(0, root.get##name##List().size()); 557 558 { 559 MallocMessageBuilder builder; 560 auto root = builder.initRoot<test::TestAllTypes>(); 561 auto reader = root.asReader(); 562 ALL_LIST_TYPES(SET_FROM_READER_ACCESSOR) 563 ALL_LIST_TYPES(CHECK_EMPTY_NONNULL) 564 } 565 566 { 567 MallocMessageBuilder builder; 568 auto root = builder.initRoot<test::TestAllTypes>(); 569 ALL_LIST_TYPES(SET_FROM_BUILDER_ACCESSOR) 570 ALL_LIST_TYPES(CHECK_EMPTY_NONNULL) 571 } 572 573 { 574 MallocMessageBuilder builder; 575 auto root = builder.initRoot<test::TestAllTypes>(); 576 ALL_LIST_TYPES(SET_FROM_READER_CONSTRUCTOR) 577 ALL_LIST_TYPES(CHECK_EMPTY_NONNULL) 578 } 579 580 { 581 MallocMessageBuilder builder; 582 auto root = builder.initRoot<test::TestAllTypes>(); 583 ALL_LIST_TYPES(SET_FROM_BUILDER_CONSTRUCTOR) 584 ALL_LIST_TYPES(CHECK_EMPTY_NONNULL) 585 } 586 587 #undef SET_FROM_READER_ACCESSOR 588 #undef SET_FROM_BUILDER_ACCESSOR 589 #undef SET_FROM_READER_CONSTRUCTOR 590 #undef SET_FROM_BUILDER_CONSTRUCTOR 591 #undef CHECK_EMPTY_NONNULL 592 } 593 594 #if CAPNP_EXPENSIVE_TESTS 595 TEST(Encoding, LongList) { 596 // This test allocates 512MB of contiguous memory and takes several seconds, so we usually don't 597 // run it. It is run before release, though. 598 599 MallocMessageBuilder builder; 600 601 auto root = builder.initRoot<TestAllTypes>(); 602 uint length = 1 << 27; 603 auto list = root.initUInt64List(length); 604 for (uint ii = 0; ii < length; ++ii) { 605 list.set(ii, ii); 606 } 607 for (uint ii = 0; ii < length; ++ii) { 608 ASSERT_EQ(list[ii], ii); 609 } 610 } 611 #endif 612 613 // ======================================================================================= 614 615 TEST(Encoding, ListUpgrade) { 616 MallocMessageBuilder builder; 617 auto root = builder.initRoot<test::TestAnyPointer>(); 618 619 root.getAnyPointerField().setAs<List<uint16_t>>({12, 34, 56}); 620 621 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {12, 34, 56}); 622 623 { 624 auto l = root.getAnyPointerField().getAs<List<test::TestLists::Struct8>>(); 625 ASSERT_EQ(3u, l.size()); 626 EXPECT_EQ(12u, l[0].getF()); 627 EXPECT_EQ(34u, l[1].getF()); 628 EXPECT_EQ(56u, l[2].getF()); 629 } 630 631 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {12, 34, 56}); 632 633 auto reader = root.asReader(); 634 635 checkList(reader.getAnyPointerField().getAs<List<uint8_t>>(), {12, 34, 56}); 636 637 { 638 auto l = reader.getAnyPointerField().getAs<List<test::TestLists::Struct8>>(); 639 ASSERT_EQ(3u, l.size()); 640 EXPECT_EQ(12u, l[0].getF()); 641 EXPECT_EQ(34u, l[1].getF()); 642 EXPECT_EQ(56u, l[2].getF()); 643 } 644 645 root.getAnyPointerField().setAs<List<uint16_t>>({12, 34, 56}); 646 647 { 648 kj::Maybe<kj::Exception> e = kj::runCatchingExceptions([&]() { 649 reader.getAnyPointerField().getAs<List<uint32_t>>(); 650 #if !KJ_NO_EXCEPTIONS 651 ADD_FAILURE() << "Should have thrown an exception."; 652 #endif 653 }); 654 655 KJ_EXPECT(e != nullptr, "Should have thrown an exception."); 656 } 657 658 { 659 auto l = reader.getAnyPointerField().getAs<List<test::TestLists::Struct32>>(); 660 ASSERT_EQ(3u, l.size()); 661 662 // These should return default values because the structs aren't big enough. 663 EXPECT_EQ(0u, l[0].getF()); 664 EXPECT_EQ(0u, l[1].getF()); 665 EXPECT_EQ(0u, l[2].getF()); 666 } 667 668 checkList(reader.getAnyPointerField().getAs<List<uint16_t>>(), {12, 34, 56}); 669 } 670 671 TEST(Encoding, BitListDowngrade) { 672 // NO LONGER SUPPORTED -- We check for exceptions thrown. 673 674 MallocMessageBuilder builder; 675 auto root = builder.initRoot<test::TestAnyPointer>(); 676 677 root.getAnyPointerField().setAs<List<uint16_t>>({0x1201u, 0x3400u, 0x5601u, 0x7801u}); 678 679 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 680 681 { 682 auto l = root.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 683 ASSERT_EQ(4u, l.size()); 684 EXPECT_TRUE(l[0].getF()); 685 EXPECT_FALSE(l[1].getF()); 686 EXPECT_TRUE(l[2].getF()); 687 EXPECT_TRUE(l[3].getF()); 688 } 689 690 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), 691 {0x1201u, 0x3400u, 0x5601u, 0x7801u}); 692 693 auto reader = root.asReader(); 694 695 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 696 697 { 698 auto l = reader.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 699 ASSERT_EQ(4u, l.size()); 700 EXPECT_TRUE(l[0].getF()); 701 EXPECT_FALSE(l[1].getF()); 702 EXPECT_TRUE(l[2].getF()); 703 EXPECT_TRUE(l[3].getF()); 704 } 705 706 checkList(reader.getAnyPointerField().getAs<List<uint16_t>>(), 707 {0x1201u, 0x3400u, 0x5601u, 0x7801u}); 708 } 709 710 TEST(Encoding, BitListDowngradeFromStruct) { 711 MallocMessageBuilder builder; 712 auto root = builder.initRoot<test::TestAnyPointer>(); 713 714 { 715 auto list = root.getAnyPointerField().initAs<List<test::TestLists::Struct1c>>(4); 716 list[0].setF(true); 717 list[1].setF(false); 718 list[2].setF(true); 719 list[3].setF(true); 720 } 721 722 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 723 724 { 725 auto l = root.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 726 ASSERT_EQ(4u, l.size()); 727 EXPECT_TRUE(l[0].getF()); 728 EXPECT_FALSE(l[1].getF()); 729 EXPECT_TRUE(l[2].getF()); 730 EXPECT_TRUE(l[3].getF()); 731 } 732 733 auto reader = root.asReader(); 734 735 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 736 737 { 738 auto l = reader.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 739 ASSERT_EQ(4u, l.size()); 740 EXPECT_TRUE(l[0].getF()); 741 EXPECT_FALSE(l[1].getF()); 742 EXPECT_TRUE(l[2].getF()); 743 EXPECT_TRUE(l[3].getF()); 744 } 745 } 746 747 TEST(Encoding, BitListUpgrade) { 748 // No longer supported! 749 750 MallocMessageBuilder builder; 751 auto root = builder.initRoot<test::TestAnyPointer>(); 752 753 root.getAnyPointerField().setAs<List<bool>>({true, false, true, true}); 754 755 { 756 kj::Maybe<kj::Exception> e = kj::runCatchingExceptions([&]() { 757 root.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 758 #if !KJ_NO_EXCEPTIONS 759 ADD_FAILURE() << "Should have thrown an exception."; 760 #endif 761 }); 762 763 KJ_EXPECT(e != nullptr, "Should have thrown an exception."); 764 } 765 766 auto reader = root.asReader(); 767 768 { 769 kj::Maybe<kj::Exception> e = kj::runCatchingExceptions([&]() { 770 reader.getAnyPointerField().getAs<List<test::TestLists::Struct1>>(); 771 #if !KJ_NO_EXCEPTIONS 772 ADD_FAILURE() << "Should have thrown an exception."; 773 #endif 774 }); 775 776 KJ_EXPECT(e != nullptr, "Should have thrown an exception."); 777 } 778 } 779 780 TEST(Encoding, UpgradeStructInBuilder) { 781 MallocMessageBuilder builder; 782 auto root = builder.initRoot<test::TestAnyPointer>(); 783 784 test::TestOldVersion::Reader oldReader; 785 786 { 787 auto oldVersion = root.getAnyPointerField().initAs<test::TestOldVersion>(); 788 oldVersion.setOld1(123); 789 oldVersion.setOld2("foo"); 790 auto sub = oldVersion.initOld3(); 791 sub.setOld1(456); 792 sub.setOld2("bar"); 793 794 oldReader = oldVersion; 795 } 796 797 size_t size = builder.getSegmentsForOutput()[0].size(); 798 size_t size2; 799 800 { 801 auto newVersion = root.getAnyPointerField().getAs<test::TestNewVersion>(); 802 803 // The old instance should have been zero'd. 804 EXPECT_EQ(0, oldReader.getOld1()); 805 EXPECT_EQ("", oldReader.getOld2()); 806 EXPECT_EQ(0, oldReader.getOld3().getOld1()); 807 EXPECT_EQ("", oldReader.getOld3().getOld2()); 808 809 // Size should have increased due to re-allocating the struct. 810 size_t size1 = builder.getSegmentsForOutput()[0].size(); 811 EXPECT_GT(size1, size); 812 813 auto sub = newVersion.getOld3(); 814 815 // Size should have increased due to re-allocating the sub-struct. 816 size2 = builder.getSegmentsForOutput()[0].size(); 817 EXPECT_GT(size2, size1); 818 819 // Check contents. 820 EXPECT_EQ(123, newVersion.getOld1()); 821 EXPECT_EQ("foo", newVersion.getOld2()); 822 EXPECT_EQ(987, newVersion.getNew1()); 823 EXPECT_EQ("baz", newVersion.getNew2()); 824 825 EXPECT_EQ(456, sub.getOld1()); 826 EXPECT_EQ("bar", sub.getOld2()); 827 EXPECT_EQ(987, sub.getNew1()); 828 EXPECT_EQ("baz", sub.getNew2()); 829 830 newVersion.setOld1(234); 831 newVersion.setOld2("qux"); 832 newVersion.setNew1(321); 833 newVersion.setNew2("quux"); 834 835 sub.setOld1(567); 836 sub.setOld2("corge"); 837 sub.setNew1(654); 838 sub.setNew2("grault"); 839 } 840 841 // We set four small text fields and implicitly initialized two to defaults, so the size should 842 // have raised by six words. 843 size_t size3 = builder.getSegmentsForOutput()[0].size(); 844 EXPECT_EQ(size2 + 6, size3); 845 846 { 847 // Go back to old version. It should have the values set on the new version. 848 auto oldVersion = root.getAnyPointerField().getAs<test::TestOldVersion>(); 849 EXPECT_EQ(234, oldVersion.getOld1()); 850 EXPECT_EQ("qux", oldVersion.getOld2()); 851 852 auto sub = oldVersion.getOld3(); 853 EXPECT_EQ(567, sub.getOld1()); 854 EXPECT_EQ("corge", sub.getOld2()); 855 856 // Overwrite the old fields. The new fields should remain intact. 857 oldVersion.setOld1(345); 858 oldVersion.setOld2("garply"); 859 sub.setOld1(678); 860 sub.setOld2("waldo"); 861 } 862 863 // We set two small text fields, so the size should have raised by two words. 864 size_t size4 = builder.getSegmentsForOutput()[0].size(); 865 EXPECT_EQ(size3 + 2, size4); 866 867 { 868 // Back to the new version again. 869 auto newVersion = root.getAnyPointerField().getAs<test::TestNewVersion>(); 870 EXPECT_EQ(345, newVersion.getOld1()); 871 EXPECT_EQ("garply", newVersion.getOld2()); 872 EXPECT_EQ(321, newVersion.getNew1()); 873 EXPECT_EQ("quux", newVersion.getNew2()); 874 875 auto sub = newVersion.getOld3(); 876 EXPECT_EQ(678, sub.getOld1()); 877 EXPECT_EQ("waldo", sub.getOld2()); 878 EXPECT_EQ(654, sub.getNew1()); 879 EXPECT_EQ("grault", sub.getNew2()); 880 } 881 882 // Size should not have changed because we didn't write anything and the structs were already 883 // the right size. 884 EXPECT_EQ(size4, builder.getSegmentsForOutput()[0].size()); 885 } 886 887 TEST(Encoding, UpgradeStructInBuilderMultiSegment) { 888 // Exactly like the previous test, except that we force multiple segments. Since we force a 889 // separate segment for every object, every pointer is a far pointer, and far pointers are easily 890 // transferred, so this is actually not such a complicated case. 891 892 MallocMessageBuilder builder(0, AllocationStrategy::FIXED_SIZE); 893 auto root = builder.initRoot<test::TestAnyPointer>(); 894 895 // Start with a 1-word first segment and the root object in the second segment. 896 size_t size = builder.getSegmentsForOutput().size(); 897 EXPECT_EQ(2u, size); 898 899 { 900 auto oldVersion = root.getAnyPointerField().initAs<test::TestOldVersion>(); 901 oldVersion.setOld1(123); 902 oldVersion.setOld2("foo"); 903 auto sub = oldVersion.initOld3(); 904 sub.setOld1(456); 905 sub.setOld2("bar"); 906 } 907 908 // Allocated two structs and two strings. 909 size_t size2 = builder.getSegmentsForOutput().size(); 910 EXPECT_EQ(size + 4, size2); 911 912 size_t size4; 913 914 { 915 auto newVersion = root.getAnyPointerField().getAs<test::TestNewVersion>(); 916 917 // Allocated a new struct. 918 size_t size3 = builder.getSegmentsForOutput().size(); 919 EXPECT_EQ(size2 + 1, size3); 920 921 auto sub = newVersion.getOld3(); 922 923 // Allocated another new struct for its string field. 924 size4 = builder.getSegmentsForOutput().size(); 925 EXPECT_EQ(size3 + 1, size4); 926 927 // Check contents. 928 EXPECT_EQ(123, newVersion.getOld1()); 929 EXPECT_EQ("foo", newVersion.getOld2()); 930 EXPECT_EQ(987, newVersion.getNew1()); 931 EXPECT_EQ("baz", newVersion.getNew2()); 932 933 EXPECT_EQ(456, sub.getOld1()); 934 EXPECT_EQ("bar", sub.getOld2()); 935 EXPECT_EQ(987, sub.getNew1()); 936 EXPECT_EQ("baz", sub.getNew2()); 937 938 newVersion.setOld1(234); 939 newVersion.setOld2("qux"); 940 newVersion.setNew1(321); 941 newVersion.setNew2("quux"); 942 943 sub.setOld1(567); 944 sub.setOld2("corge"); 945 sub.setNew1(654); 946 sub.setNew2("grault"); 947 } 948 949 // Set four strings and implicitly initialized two. 950 size_t size5 = builder.getSegmentsForOutput().size(); 951 EXPECT_EQ(size4 + 6, size5); 952 953 { 954 // Go back to old version. It should have the values set on the new version. 955 auto oldVersion = root.getAnyPointerField().getAs<test::TestOldVersion>(); 956 EXPECT_EQ(234, oldVersion.getOld1()); 957 EXPECT_EQ("qux", oldVersion.getOld2()); 958 959 auto sub = oldVersion.getOld3(); 960 EXPECT_EQ(567, sub.getOld1()); 961 EXPECT_EQ("corge", sub.getOld2()); 962 963 // Overwrite the old fields. The new fields should remain intact. 964 oldVersion.setOld1(345); 965 oldVersion.setOld2("garply"); 966 sub.setOld1(678); 967 sub.setOld2("waldo"); 968 } 969 970 // Set two new strings. 971 size_t size6 = builder.getSegmentsForOutput().size(); 972 EXPECT_EQ(size5 + 2, size6); 973 974 { 975 // Back to the new version again. 976 auto newVersion = root.getAnyPointerField().getAs<test::TestNewVersion>(); 977 EXPECT_EQ(345, newVersion.getOld1()); 978 EXPECT_EQ("garply", newVersion.getOld2()); 979 EXPECT_EQ(321, newVersion.getNew1()); 980 EXPECT_EQ("quux", newVersion.getNew2()); 981 982 auto sub = newVersion.getOld3(); 983 EXPECT_EQ(678, sub.getOld1()); 984 EXPECT_EQ("waldo", sub.getOld2()); 985 EXPECT_EQ(654, sub.getNew1()); 986 EXPECT_EQ("grault", sub.getNew2()); 987 } 988 989 // Size should not have changed because we didn't write anything and the structs were already 990 // the right size. 991 EXPECT_EQ(size6, builder.getSegmentsForOutput().size()); 992 } 993 994 TEST(Encoding, UpgradeStructInBuilderFarPointers) { 995 // Force allocation of a Far pointer. 996 997 MallocMessageBuilder builder(7, AllocationStrategy::FIXED_SIZE); 998 auto root = builder.initRoot<test::TestAnyPointer>(); 999 1000 root.getAnyPointerField().initAs<test::TestOldVersion>().setOld2("foo"); 1001 1002 // We should have allocated all but one word of the first segment. 1003 EXPECT_EQ(1u, builder.getSegmentsForOutput().size()); 1004 EXPECT_EQ(6u, builder.getSegmentsForOutput()[0].size()); 1005 1006 // Now if we upgrade... 1007 EXPECT_EQ("foo", root.getAnyPointerField().getAs<test::TestNewVersion>().getOld2()); 1008 1009 // We should have allocated the new struct in a new segment, but allocated the far pointer 1010 // landing pad back in the first segment. 1011 ASSERT_EQ(2u, builder.getSegmentsForOutput().size()); 1012 EXPECT_EQ(7u, builder.getSegmentsForOutput()[0].size()); 1013 EXPECT_EQ(6u, builder.getSegmentsForOutput()[1].size()); 1014 } 1015 1016 TEST(Encoding, UpgradeStructInBuilderDoubleFarPointers) { 1017 // Force allocation of a double-Far pointer. 1018 1019 MallocMessageBuilder builder(6, AllocationStrategy::FIXED_SIZE); 1020 auto root = builder.initRoot<test::TestAnyPointer>(); 1021 1022 root.getAnyPointerField().initAs<test::TestOldVersion>().setOld2("foo"); 1023 1024 // We should have allocated all of the first segment. 1025 EXPECT_EQ(1u, builder.getSegmentsForOutput().size()); 1026 EXPECT_EQ(6u, builder.getSegmentsForOutput()[0].size()); 1027 1028 // Now if we upgrade... 1029 EXPECT_EQ("foo", root.getAnyPointerField().getAs<test::TestNewVersion>().getOld2()); 1030 1031 // We should have allocated the new struct in a new segment, and also allocated the far pointer 1032 // landing pad in yet another segment. 1033 ASSERT_EQ(3u, builder.getSegmentsForOutput().size()); 1034 EXPECT_EQ(6u, builder.getSegmentsForOutput()[0].size()); 1035 EXPECT_EQ(6u, builder.getSegmentsForOutput()[1].size()); 1036 EXPECT_EQ(2u, builder.getSegmentsForOutput()[2].size()); 1037 } 1038 1039 void checkUpgradedList(test::TestAnyPointer::Builder root, 1040 std::initializer_list<int64_t> expectedData, 1041 std::initializer_list<Text::Reader> expectedPointers) { 1042 { 1043 auto builder = root.getAnyPointerField().getAs<List<test::TestNewVersion>>(); 1044 1045 ASSERT_EQ(expectedData.size(), builder.size()); 1046 for (uint i = 0; i < expectedData.size(); i++) { 1047 EXPECT_EQ(expectedData.begin()[i], builder[i].getOld1()); 1048 EXPECT_EQ(expectedPointers.begin()[i], builder[i].getOld2()); 1049 1050 // Other fields shouldn't be set. 1051 EXPECT_EQ(0, builder[i].asReader().getOld3().getOld1()); 1052 EXPECT_EQ("", builder[i].asReader().getOld3().getOld2()); 1053 EXPECT_EQ(987, builder[i].getNew1()); 1054 EXPECT_EQ("baz", builder[i].getNew2()); 1055 1056 // Write some new data. 1057 builder[i].setOld1(i * 123); 1058 builder[i].setOld2(kj::str("qux", i, '\0').begin()); 1059 builder[i].setNew1(i * 456); 1060 builder[i].setNew2(kj::str("corge", i, '\0').begin()); 1061 } 1062 } 1063 1064 // Read the newly-written data as TestOldVersion to ensure it was updated. 1065 { 1066 auto builder = root.getAnyPointerField().getAs<List<test::TestOldVersion>>(); 1067 1068 ASSERT_EQ(expectedData.size(), builder.size()); 1069 for (uint i = 0; i < expectedData.size(); i++) { 1070 EXPECT_EQ(i * 123, builder[i].getOld1()); 1071 EXPECT_EQ(Text::Reader(kj::str("qux", i, "\0").begin()), builder[i].getOld2()); 1072 } 1073 } 1074 1075 // Also read back as TestNewVersion again. 1076 { 1077 auto builder = root.getAnyPointerField().getAs<List<test::TestNewVersion>>(); 1078 1079 ASSERT_EQ(expectedData.size(), builder.size()); 1080 for (uint i = 0; i < expectedData.size(); i++) { 1081 EXPECT_EQ(i * 123, builder[i].getOld1()); 1082 EXPECT_EQ(Text::Reader(kj::str("qux", i, '\0').begin()), builder[i].getOld2()); 1083 EXPECT_EQ(i * 456, builder[i].getNew1()); 1084 EXPECT_EQ(Text::Reader(kj::str("corge", i, '\0').begin()), builder[i].getNew2()); 1085 } 1086 } 1087 } 1088 1089 TEST(Encoding, UpgradeListInBuilder) { 1090 // Test every damned list upgrade. 1091 1092 MallocMessageBuilder builder; 1093 auto root = builder.initRoot<test::TestAnyPointer>(); 1094 1095 // ----------------------------------------------------------------- 1096 1097 root.getAnyPointerField().setAs<List<Void>>({VOID, VOID, VOID, VOID}); 1098 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID, VOID}); 1099 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1100 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint8_t>>()); 1101 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint16_t>>()); 1102 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1103 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1104 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1105 checkUpgradedList(root, {0, 0, 0, 0}, {"", "", "", ""}); 1106 1107 // ----------------------------------------------------------------- 1108 1109 { 1110 root.getAnyPointerField().setAs<List<bool>>({true, false, true, true}); 1111 auto orig = root.asReader().getAnyPointerField().getAs<List<bool>>(); 1112 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Void>>()); 1113 checkList(root.getAnyPointerField().getAs<List<bool>>(), {true, false, true, true}); 1114 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint8_t>>()); 1115 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint16_t>>()); 1116 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1117 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1118 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1119 1120 checkList(orig, {true, false, true, true}); 1121 1122 // Can't upgrade bit lists. (This used to be supported.) 1123 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<test::TestNewVersion>>()); 1124 } 1125 1126 // ----------------------------------------------------------------- 1127 1128 { 1129 root.getAnyPointerField().setAs<List<uint8_t>>({0x12, 0x23, 0x33, 0x44}); 1130 auto orig = root.asReader().getAnyPointerField().getAs<List<uint8_t>>(); 1131 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID, VOID}); 1132 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1133 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0x12, 0x23, 0x33, 0x44}); 1134 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint16_t>>()); 1135 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1136 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1137 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1138 1139 checkList(orig, {0x12, 0x23, 0x33, 0x44}); 1140 checkUpgradedList(root, {0x12, 0x23, 0x33, 0x44}, {"", "", "", ""}); 1141 checkList(orig, {0, 0, 0, 0}); // old location zero'd during upgrade 1142 } 1143 1144 // ----------------------------------------------------------------- 1145 1146 { 1147 root.getAnyPointerField().setAs<List<uint16_t>>({0x5612, 0x7823, 0xab33, 0xcd44}); 1148 auto orig = root.asReader().getAnyPointerField().getAs<List<uint16_t>>(); 1149 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID, VOID}); 1150 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1151 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0x12, 0x23, 0x33, 0x44}); 1152 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {0x5612, 0x7823, 0xab33, 0xcd44}); 1153 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1154 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1155 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1156 1157 checkList(orig, {0x5612, 0x7823, 0xab33, 0xcd44}); 1158 checkUpgradedList(root, {0x5612, 0x7823, 0xab33, 0xcd44}, {"", "", "", ""}); 1159 checkList(orig, {0, 0, 0, 0}); // old location zero'd during upgrade 1160 } 1161 1162 // ----------------------------------------------------------------- 1163 1164 { 1165 root.getAnyPointerField().setAs<List<uint32_t>>({0x17595612, 0x29347823, 0x5923ab32, 0x1a39cd45}); 1166 auto orig = root.asReader().getAnyPointerField().getAs<List<uint32_t>>(); 1167 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID, VOID}); 1168 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1169 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0x12, 0x23, 0x32, 0x45}); 1170 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {0x5612, 0x7823, 0xab32, 0xcd45}); 1171 checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), {0x17595612u, 0x29347823u, 0x5923ab32u, 0x1a39cd45u}); 1172 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1173 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1174 1175 checkList(orig, {0x17595612u, 0x29347823u, 0x5923ab32u, 0x1a39cd45u}); 1176 checkUpgradedList(root, {0x17595612, 0x29347823, 0x5923ab32, 0x1a39cd45}, {"", "", "", ""}); 1177 checkList(orig, {0u, 0u, 0u, 0u}); // old location zero'd during upgrade 1178 } 1179 1180 // ----------------------------------------------------------------- 1181 1182 { 1183 root.getAnyPointerField().setAs<List<uint64_t>>({0x1234abcd8735fe21, 0x7173bc0e1923af36}); 1184 auto orig = root.asReader().getAnyPointerField().getAs<List<uint64_t>>(); 1185 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID}); 1186 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1187 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0x21, 0x36}); 1188 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {0xfe21, 0xaf36}); 1189 checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), {0x8735fe21u, 0x1923af36u}); 1190 checkList(root.getAnyPointerField().getAs<List<uint64_t>>(), {0x1234abcd8735fe21ull, 0x7173bc0e1923af36ull}); 1191 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1192 1193 checkList(orig, {0x1234abcd8735fe21ull, 0x7173bc0e1923af36ull}); 1194 checkUpgradedList(root, {0x1234abcd8735fe21ull, 0x7173bc0e1923af36ull}, {"", ""}); 1195 checkList(orig, {0u, 0u}); // old location zero'd during upgrade 1196 } 1197 1198 // ----------------------------------------------------------------- 1199 1200 { 1201 root.getAnyPointerField().setAs<List<Text>>({"foo", "bar", "baz"}); 1202 auto orig = root.asReader().getAnyPointerField().getAs<List<Text>>(); 1203 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID}); 1204 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1205 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint8_t>>()); 1206 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint16_t>>()); 1207 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1208 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1209 checkList(root.getAnyPointerField().getAs<List<Text>>(), {"foo", "bar", "baz"}); 1210 1211 checkList(orig, {"foo", "bar", "baz"}); 1212 checkUpgradedList(root, {0, 0, 0}, {"foo", "bar", "baz"}); 1213 checkList(orig, {"", "", ""}); // old location zero'd during upgrade 1214 } 1215 1216 // ----------------------------------------------------------------- 1217 1218 { 1219 { 1220 auto l = root.getAnyPointerField().initAs<List<test::TestOldVersion>>(3); 1221 l[0].setOld1(0x1234567890abcdef); 1222 l[1].setOld1(0x234567890abcdef1); 1223 l[2].setOld1(0x34567890abcdef12); 1224 l[0].setOld2("foo"); 1225 l[1].setOld2("bar"); 1226 l[2].setOld2("baz"); 1227 } 1228 auto orig = root.asReader().getAnyPointerField().getAs<List<test::TestOldVersion>>(); 1229 1230 checkList(root.getAnyPointerField().getAs<List<Void>>(), {VOID, VOID, VOID}); 1231 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1232 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0xefu, 0xf1u, 0x12u}); 1233 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {0xcdefu, 0xdef1u, 0xef12u}); 1234 checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), {0x90abcdefu, 0x0abcdef1u, 0xabcdef12u}); 1235 checkList(root.getAnyPointerField().getAs<List<uint64_t>>(), 1236 {0x1234567890abcdefull, 0x234567890abcdef1ull, 0x34567890abcdef12ull}); 1237 checkList(root.getAnyPointerField().getAs<List<Text>>(), {"foo", "bar", "baz"}); 1238 1239 checkList(orig, {0x1234567890abcdefull, 0x234567890abcdef1ull, 0x34567890abcdef12ull}, 1240 {"foo", "bar", "baz"}); 1241 checkUpgradedList(root, {0x1234567890abcdefull, 0x234567890abcdef1ull, 0x34567890abcdef12ull}, 1242 {"foo", "bar", "baz"}); 1243 checkList(orig, {0u, 0u, 0u}, {"", "", ""}); // old location zero'd during upgrade 1244 } 1245 1246 // ----------------------------------------------------------------- 1247 // OK, now we've tested upgrading every primitive list to every primitive list, every primitive 1248 // list to a multi-word struct, and a multi-word struct to every primitive list. But we haven't 1249 // tried upgrading primitive lists to sub-word structs. 1250 1251 // Upgrade from multi-byte, sub-word data. 1252 root.getAnyPointerField().setAs<List<uint16_t>>({12u, 34u, 56u, 78u}); 1253 { 1254 auto orig = root.asReader().getAnyPointerField().getAs<List<uint16_t>>(); 1255 checkList(orig, {12u, 34u, 56u, 78u}); 1256 auto l = root.getAnyPointerField().getAs<List<test::TestLists::Struct32>>(); 1257 checkList(orig, {0u, 0u, 0u, 0u}); // old location zero'd during upgrade 1258 ASSERT_EQ(4u, l.size()); 1259 EXPECT_EQ(12u, l[0].getF()); 1260 EXPECT_EQ(34u, l[1].getF()); 1261 EXPECT_EQ(56u, l[2].getF()); 1262 EXPECT_EQ(78u, l[3].getF()); 1263 l[0].setF(0x65ac1235u); 1264 l[1].setF(0x13f12879u); 1265 l[2].setF(0x33423082u); 1266 l[3].setF(0x12988948u); 1267 } 1268 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1269 checkList(root.getAnyPointerField().getAs<List<uint8_t>>(), {0x35u, 0x79u, 0x82u, 0x48u}); 1270 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {0x1235u, 0x2879u, 0x3082u, 0x8948u}); 1271 checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), 1272 {0x65ac1235u, 0x13f12879u, 0x33423082u, 0x12988948u}); 1273 checkList(root.getAnyPointerField().getAs<List<uint64_t>>(), 1274 {0x65ac1235u, 0x13f12879u, 0x33423082u, 0x12988948u}); 1275 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1276 1277 // Upgrade from void -> data struct 1278 root.getAnyPointerField().setAs<List<Void>>({VOID, VOID, VOID, VOID}); 1279 { 1280 auto l = root.getAnyPointerField().getAs<List<test::TestLists::Struct16>>(); 1281 ASSERT_EQ(4u, l.size()); 1282 EXPECT_EQ(0u, l[0].getF()); 1283 EXPECT_EQ(0u, l[1].getF()); 1284 EXPECT_EQ(0u, l[2].getF()); 1285 EXPECT_EQ(0u, l[3].getF()); 1286 l[0].setF(12573); 1287 l[1].setF(3251); 1288 l[2].setF(9238); 1289 l[3].setF(5832); 1290 } 1291 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1292 checkList(root.getAnyPointerField().getAs<List<uint16_t>>(), {12573u, 3251u, 9238u, 5832u}); 1293 checkList(root.getAnyPointerField().getAs<List<uint32_t>>(), {12573u, 3251u, 9238u, 5832u}); 1294 checkList(root.getAnyPointerField().getAs<List<uint64_t>>(), {12573u, 3251u, 9238u, 5832u}); 1295 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1296 1297 // Upgrade from void -> pointer struct 1298 root.getAnyPointerField().setAs<List<Void>>({VOID, VOID, VOID, VOID}); 1299 { 1300 auto l = root.getAnyPointerField().getAs<List<test::TestLists::StructP>>(); 1301 ASSERT_EQ(4u, l.size()); 1302 EXPECT_EQ("", l[0].getF()); 1303 EXPECT_EQ("", l[1].getF()); 1304 EXPECT_EQ("", l[2].getF()); 1305 EXPECT_EQ("", l[3].getF()); 1306 l[0].setF("foo"); 1307 l[1].setF("bar"); 1308 l[2].setF("baz"); 1309 l[3].setF("qux"); 1310 } 1311 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<bool>>()); 1312 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint16_t>>()); 1313 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1314 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint64_t>>()); 1315 checkList(root.getAnyPointerField().getAs<List<Text>>(), {"foo", "bar", "baz", "qux"}); 1316 1317 // Verify that we cannot "side-grade" a pointer list to a data list, or a data list to 1318 // a pointer struct list. 1319 root.getAnyPointerField().setAs<List<Text>>({"foo", "bar", "baz", "qux"}); 1320 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<uint32_t>>()); 1321 root.getAnyPointerField().setAs<List<uint32_t>>({12, 34, 56, 78}); 1322 EXPECT_NONFATAL_FAILURE(root.getAnyPointerField().getAs<List<Text>>()); 1323 } 1324 1325 TEST(Encoding, UpgradeUnion) { 1326 // This tests for a specific case that was broken originally. 1327 MallocMessageBuilder builder; 1328 1329 { 1330 auto root = builder.getRoot<test::TestOldUnionVersion>(); 1331 root.setB(123); 1332 } 1333 1334 { 1335 auto root = builder.getRoot<test::TestNewUnionVersion>(); 1336 ASSERT_TRUE(root.isB()) 1337 EXPECT_EQ(123, root.getB()); 1338 } 1339 } 1340 1341 // ======================================================================================= 1342 // Tests of generated code, not really of the encoding. 1343 // TODO(cleanup): Move to a different test? 1344 1345 TEST(Encoding, NestedTypes) { 1346 // This is more of a test of the generated code than the encoding. 1347 1348 MallocMessageBuilder builder; 1349 TestNestedTypes::Reader reader = builder.getRoot<TestNestedTypes>().asReader(); 1350 1351 EXPECT_EQ(TestNestedTypes::NestedEnum::BAR, reader.getOuterNestedEnum()); 1352 EXPECT_EQ(TestNestedTypes::NestedStruct::NestedEnum::QUUX, reader.getInnerNestedEnum()); 1353 1354 TestNestedTypes::NestedStruct::Reader nested = reader.getNestedStruct(); 1355 EXPECT_EQ(TestNestedTypes::NestedEnum::BAR, nested.getOuterNestedEnum()); 1356 EXPECT_EQ(TestNestedTypes::NestedStruct::NestedEnum::QUUX, nested.getInnerNestedEnum()); 1357 } 1358 1359 TEST(Encoding, Imports) { 1360 // Also just testing the generated code. 1361 1362 { 1363 MallocMessageBuilder builder; 1364 TestImport::Builder root = builder.getRoot<TestImport>(); 1365 initTestMessage(root.initField()); 1366 checkTestMessage(root.asReader().getField()); 1367 } 1368 1369 { 1370 MallocMessageBuilder builder; 1371 TestImport2::Builder root = builder.getRoot<TestImport2>(); 1372 initTestMessage(root.initFoo()); 1373 checkTestMessage(root.asReader().getFoo()); 1374 root.setBar(schemaProto<TestAllTypes>()); 1375 initTestMessage(root.initBaz().initField()); 1376 checkTestMessage(root.asReader().getBaz().getField()); 1377 } 1378 } 1379 1380 TEST(Encoding, Using) { 1381 MallocMessageBuilder builder; 1382 TestUsing::Reader reader = builder.getRoot<TestUsing>().asReader(); 1383 EXPECT_EQ(TestNestedTypes::NestedEnum::BAR, reader.getOuterNestedEnum()); 1384 EXPECT_EQ(TestNestedTypes::NestedStruct::NestedEnum::QUUX, reader.getInnerNestedEnum()); 1385 } 1386 1387 TEST(Encoding, StructSetters) { 1388 MallocMessageBuilder builder; 1389 auto root = builder.getRoot<TestAllTypes>(); 1390 initTestMessage(root); 1391 1392 { 1393 MallocMessageBuilder builder2; 1394 builder2.setRoot(root.asReader()); 1395 checkTestMessage(builder2.getRoot<TestAllTypes>()); 1396 } 1397 1398 { 1399 MallocMessageBuilder builder2; 1400 auto root2 = builder2.getRoot<TestAllTypes>(); 1401 root2.setStructField(root); 1402 checkTestMessage(root2.getStructField()); 1403 } 1404 1405 { 1406 MallocMessageBuilder builder2; 1407 auto root2 = builder2.getRoot<test::TestAnyPointer>(); 1408 root2.getAnyPointerField().setAs<test::TestAllTypes>(root); 1409 checkTestMessage(root2.getAnyPointerField().getAs<test::TestAllTypes>()); 1410 } 1411 } 1412 1413 TEST(Encoding, OneBitStructSetters) { 1414 // Test case of setting a 1-bit struct. 1415 1416 MallocMessageBuilder builder; 1417 auto root = builder.getRoot<test::TestLists>(); 1418 auto list = root.initList1(8); 1419 list[0].setF(true); 1420 list[1].setF(true); 1421 list[2].setF(false); 1422 list[3].setF(true); 1423 list[4].setF(true); 1424 list[5].setF(false); 1425 list[6].setF(true); 1426 list[7].setF(false); 1427 1428 MallocMessageBuilder builder2; 1429 builder2.setRoot(list.asReader()[2]); 1430 EXPECT_FALSE(builder2.getRoot<test::TestLists::Struct1>().getF()); 1431 builder2.setRoot(list.asReader()[6]); 1432 EXPECT_TRUE(builder2.getRoot<test::TestLists::Struct1>().getF()); 1433 } 1434 1435 TEST(Encoding, ListSetters) { 1436 MallocMessageBuilder builder; 1437 auto root = builder.getRoot<TestListDefaults>(); 1438 initTestMessage(root); 1439 1440 { 1441 MallocMessageBuilder builder2; 1442 auto root2 = builder2.getRoot<TestListDefaults>(); 1443 1444 root2.getLists().setList0(root.getLists().getList0()); 1445 root2.getLists().setList1(root.getLists().getList1()); 1446 root2.getLists().setList8(root.getLists().getList8()); 1447 root2.getLists().setList16(root.getLists().getList16()); 1448 root2.getLists().setList32(root.getLists().getList32()); 1449 root2.getLists().setList64(root.getLists().getList64()); 1450 root2.getLists().setListP(root.getLists().getListP()); 1451 1452 { 1453 auto dst = root2.getLists().initInt32ListList(3); 1454 auto src = root.getLists().getInt32ListList(); 1455 dst.set(0, src[0]); 1456 dst.set(1, src[1]); 1457 dst.set(2, src[2]); 1458 } 1459 1460 { 1461 auto dst = root2.getLists().initTextListList(3); 1462 auto src = root.getLists().getTextListList(); 1463 dst.set(0, src[0]); 1464 dst.set(1, src[1]); 1465 dst.set(2, src[2]); 1466 } 1467 1468 { 1469 auto dst = root2.getLists().initStructListList(2); 1470 auto src = root.getLists().getStructListList(); 1471 dst.set(0, src[0]); 1472 dst.set(1, src[1]); 1473 } 1474 1475 checkTestMessage(root2); 1476 1477 // Now let's do some adopting and disowning. 1478 auto adopter = builder2.getOrphanage().newOrphan<test::TestLists>(); 1479 auto disowner = root2.disownLists(); 1480 1481 adopter.get().adoptList0(disowner.get().disownList0()); 1482 adopter.get().adoptList1(disowner.get().disownList1()); 1483 adopter.get().adoptList8(disowner.get().disownList8()); 1484 adopter.get().adoptList16(disowner.get().disownList16()); 1485 adopter.get().adoptList32(disowner.get().disownList32()); 1486 adopter.get().adoptList64(disowner.get().disownList64()); 1487 adopter.get().adoptListP(disowner.get().disownListP()); 1488 1489 { 1490 auto dst = adopter.get().initInt32ListList(3); 1491 auto src = disowner.get().getInt32ListList(); 1492 1493 auto orphan = src.disown(0); 1494 checkList(orphan.getReader(), {1, 2, 3}); 1495 dst.adopt(0, kj::mv(orphan)); 1496 dst.adopt(1, src.disown(1)); 1497 dst.adopt(2, src.disown(2)); 1498 } 1499 1500 { 1501 auto dst = adopter.get().initTextListList(3); 1502 auto src = disowner.get().getTextListList(); 1503 1504 auto orphan = src.disown(0); 1505 checkList(orphan.getReader(), {"foo", "bar"}); 1506 dst.adopt(0, kj::mv(orphan)); 1507 dst.adopt(1, src.disown(1)); 1508 dst.adopt(2, src.disown(2)); 1509 } 1510 1511 { 1512 auto dst = adopter.get().initStructListList(2); 1513 auto src = disowner.get().getStructListList(); 1514 1515 auto orphan = src.disown(0); 1516 KJ_EXPECT(orphan.getReader()[0].getInt32Field() == 123); 1517 KJ_EXPECT(orphan.getReader()[1].getInt32Field() == 456); 1518 dst.adopt(0, kj::mv(orphan)); 1519 dst.adopt(1, src.disown(1)); 1520 } 1521 1522 root2.adoptLists(kj::mv(adopter)); 1523 1524 checkTestMessage(root2); 1525 } 1526 } 1527 1528 TEST(Encoding, ZeroOldObject) { 1529 MallocMessageBuilder builder; 1530 1531 auto root = builder.initRoot<TestAllTypes>(); 1532 initTestMessage(root); 1533 1534 auto oldRoot = root.asReader(); 1535 checkTestMessage(oldRoot); 1536 1537 auto oldSub = oldRoot.getStructField(); 1538 auto oldSub2 = oldRoot.getStructList()[0]; 1539 1540 root = builder.initRoot<TestAllTypes>(); 1541 checkTestMessageAllZero(oldRoot); 1542 checkTestMessageAllZero(oldSub); 1543 checkTestMessageAllZero(oldSub2); 1544 } 1545 1546 TEST(Encoding, Has) { 1547 MallocMessageBuilder builder; 1548 1549 auto root = builder.initRoot<TestAllTypes>(); 1550 1551 EXPECT_FALSE(root.hasTextField()); 1552 EXPECT_FALSE(root.hasDataField()); 1553 EXPECT_FALSE(root.hasStructField()); 1554 EXPECT_FALSE(root.hasInt32List()); 1555 1556 EXPECT_FALSE(root.asReader().hasTextField()); 1557 EXPECT_FALSE(root.asReader().hasDataField()); 1558 EXPECT_FALSE(root.asReader().hasStructField()); 1559 EXPECT_FALSE(root.asReader().hasInt32List()); 1560 1561 initTestMessage(root); 1562 1563 EXPECT_TRUE(root.hasTextField()); 1564 EXPECT_TRUE(root.hasDataField()); 1565 EXPECT_TRUE(root.hasStructField()); 1566 EXPECT_TRUE(root.hasInt32List()); 1567 1568 EXPECT_TRUE(root.asReader().hasTextField()); 1569 EXPECT_TRUE(root.asReader().hasDataField()); 1570 EXPECT_TRUE(root.asReader().hasStructField()); 1571 EXPECT_TRUE(root.asReader().hasInt32List()); 1572 } 1573 1574 TEST(Encoding, VoidListAmplification) { 1575 MallocMessageBuilder builder; 1576 builder.initRoot<test::TestAnyPointer>().getAnyPointerField().initAs<List<Void>>(1u << 28); 1577 1578 auto segments = builder.getSegmentsForOutput(); 1579 EXPECT_EQ(1, segments.size()); 1580 EXPECT_LT(segments[0].size(), 16); // quite small for such a big list! 1581 1582 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 1583 auto root = reader.getRoot<test::TestAnyPointer>().getAnyPointerField(); 1584 EXPECT_NONFATAL_FAILURE(root.getAs<List<TestAllTypes>>()); 1585 1586 MallocMessageBuilder copy; 1587 EXPECT_NONFATAL_FAILURE(copy.setRoot(reader.getRoot<AnyPointer>())); 1588 } 1589 1590 TEST(Encoding, EmptyStructListAmplification) { 1591 MallocMessageBuilder builder(1024); 1592 auto listList = builder.initRoot<test::TestAnyPointer>().getAnyPointerField() 1593 .initAs<List<List<test::TestEmptyStruct>>>(500); 1594 1595 for (uint i = 0; i < listList.size(); i++) { 1596 listList.init(i, 1u << 28); 1597 } 1598 1599 auto segments = builder.getSegmentsForOutput(); 1600 ASSERT_EQ(1, segments.size()); 1601 1602 SegmentArrayMessageReader reader(builder.getSegmentsForOutput()); 1603 auto root = reader.getRoot<test::TestAnyPointer>(); 1604 auto listListReader = root.getAnyPointerField().getAs<List<List<TestAllTypes>>>(); 1605 EXPECT_NONFATAL_FAILURE(listListReader[0]); 1606 EXPECT_NONFATAL_FAILURE(listListReader[10]); 1607 1608 EXPECT_EQ(segments[0].size() - 1, root.totalSize().wordCount); 1609 } 1610 1611 TEST(Encoding, Constants) { 1612 EXPECT_EQ(VOID, test::TestConstants::VOID_CONST); 1613 EXPECT_EQ(true, test::TestConstants::BOOL_CONST); 1614 EXPECT_EQ(-123, test::TestConstants::INT8_CONST); 1615 EXPECT_EQ(-12345, test::TestConstants::INT16_CONST); 1616 EXPECT_EQ(-12345678, test::TestConstants::INT32_CONST); 1617 EXPECT_EQ(-123456789012345ll, test::TestConstants::INT64_CONST); 1618 EXPECT_EQ(234u, test::TestConstants::UINT8_CONST); 1619 EXPECT_EQ(45678u, test::TestConstants::UINT16_CONST); 1620 EXPECT_EQ(3456789012u, test::TestConstants::UINT32_CONST); 1621 EXPECT_EQ(12345678901234567890ull, test::TestConstants::UINT64_CONST); 1622 EXPECT_FLOAT_EQ(1234.5f, test::TestConstants::FLOAT32_CONST); 1623 EXPECT_DOUBLE_EQ(-123e45, test::TestConstants::FLOAT64_CONST); 1624 EXPECT_EQ("foo", *test::TestConstants::TEXT_CONST); 1625 EXPECT_EQ(data("bar"), test::TestConstants::DATA_CONST); 1626 { 1627 TestAllTypes::Reader subReader = test::TestConstants::STRUCT_CONST; 1628 EXPECT_EQ(VOID, subReader.getVoidField()); 1629 EXPECT_EQ(true, subReader.getBoolField()); 1630 EXPECT_EQ(-12, subReader.getInt8Field()); 1631 EXPECT_EQ(3456, subReader.getInt16Field()); 1632 EXPECT_EQ(-78901234, subReader.getInt32Field()); 1633 EXPECT_EQ(56789012345678ll, subReader.getInt64Field()); 1634 EXPECT_EQ(90u, subReader.getUInt8Field()); 1635 EXPECT_EQ(1234u, subReader.getUInt16Field()); 1636 EXPECT_EQ(56789012u, subReader.getUInt32Field()); 1637 EXPECT_EQ(345678901234567890ull, subReader.getUInt64Field()); 1638 EXPECT_FLOAT_EQ(-1.25e-10f, subReader.getFloat32Field()); 1639 EXPECT_DOUBLE_EQ(345, subReader.getFloat64Field()); 1640 EXPECT_EQ("baz", subReader.getTextField()); 1641 EXPECT_EQ(data("qux"), subReader.getDataField()); 1642 { 1643 auto subSubReader = subReader.getStructField(); 1644 EXPECT_EQ("nested", subSubReader.getTextField()); 1645 EXPECT_EQ("really nested", subSubReader.getStructField().getTextField()); 1646 } 1647 EXPECT_EQ(TestEnum::BAZ, subReader.getEnumField()); 1648 1649 checkList(subReader.getVoidList(), {VOID, VOID, VOID}); 1650 checkList(subReader.getBoolList(), {false, true, false, true, true}); 1651 checkList(subReader.getInt8List(), {12, -34, -0x80, 0x7f}); 1652 checkList(subReader.getInt16List(), {1234, -5678, -0x8000, 0x7fff}); 1653 // gcc warns on -0x800... and the only work-around I could find was to do -0x7ff...-1. 1654 checkList(subReader.getInt32List(), {12345678, -90123456, -0x7fffffff - 1, 0x7fffffff}); 1655 checkList(subReader.getInt64List(), {123456789012345ll, -678901234567890ll, -0x7fffffffffffffffll-1, 0x7fffffffffffffffll}); 1656 checkList(subReader.getUInt8List(), {12u, 34u, 0u, 0xffu}); 1657 checkList(subReader.getUInt16List(), {1234u, 5678u, 0u, 0xffffu}); 1658 checkList(subReader.getUInt32List(), {12345678u, 90123456u, 0u, 0xffffffffu}); 1659 checkList(subReader.getUInt64List(), {123456789012345ull, 678901234567890ull, 0ull, 0xffffffffffffffffull}); 1660 checkList(subReader.getFloat32List(), {0.0f, 1234567.0f, 1e37f, -1e37f, 1e-37f, -1e-37f}); 1661 checkList(subReader.getFloat64List(), {0.0, 123456789012345.0, 1e306, -1e306, 1e-306, -1e-306}); 1662 checkList(subReader.getTextList(), {"quux", "corge", "grault"}); 1663 checkList(subReader.getDataList(), {data("garply"), data("waldo"), data("fred")}); 1664 { 1665 auto listReader = subReader.getStructList(); 1666 ASSERT_EQ(3u, listReader.size()); 1667 EXPECT_EQ("x structlist 1", listReader[0].getTextField()); 1668 EXPECT_EQ("x structlist 2", listReader[1].getTextField()); 1669 EXPECT_EQ("x structlist 3", listReader[2].getTextField()); 1670 } 1671 checkList(subReader.getEnumList(), {TestEnum::QUX, TestEnum::BAR, TestEnum::GRAULT}); 1672 } 1673 EXPECT_EQ(TestEnum::CORGE, test::TestConstants::ENUM_CONST); 1674 1675 EXPECT_EQ(6u, test::TestConstants::VOID_LIST_CONST->size()); 1676 checkList(*test::TestConstants::BOOL_LIST_CONST, {true, false, false, true}); 1677 checkList(*test::TestConstants::INT8_LIST_CONST, {111, -111}); 1678 checkList(*test::TestConstants::INT16_LIST_CONST, {11111, -11111}); 1679 checkList(*test::TestConstants::INT32_LIST_CONST, {111111111, -111111111}); 1680 checkList(*test::TestConstants::INT64_LIST_CONST, {1111111111111111111ll, -1111111111111111111ll}); 1681 checkList(*test::TestConstants::UINT8_LIST_CONST, {111u, 222u}); 1682 checkList(*test::TestConstants::UINT16_LIST_CONST, {33333u, 44444u}); 1683 checkList(*test::TestConstants::UINT32_LIST_CONST, {3333333333u}); 1684 checkList(*test::TestConstants::UINT64_LIST_CONST, {11111111111111111111ull}); 1685 { 1686 List<float>::Reader listReader = test::TestConstants::FLOAT32_LIST_CONST; 1687 ASSERT_EQ(4u, listReader.size()); 1688 EXPECT_EQ(5555.5f, listReader[0]); 1689 EXPECT_EQ(kj::inf(), listReader[1]); 1690 EXPECT_EQ(-kj::inf(), listReader[2]); 1691 EXPECT_TRUE(listReader[3] != listReader[3]); 1692 } 1693 { 1694 List<double>::Reader listReader = test::TestConstants::FLOAT64_LIST_CONST; 1695 ASSERT_EQ(4u, listReader.size()); 1696 EXPECT_EQ(7777.75, listReader[0]); 1697 EXPECT_EQ(kj::inf(), listReader[1]); 1698 EXPECT_EQ(-kj::inf(), listReader[2]); 1699 EXPECT_TRUE(listReader[3] != listReader[3]); 1700 } 1701 checkList(*test::TestConstants::TEXT_LIST_CONST, {"plugh", "xyzzy", "thud"}); 1702 checkList(*test::TestConstants::DATA_LIST_CONST, {data("oops"), data("exhausted"), data("rfc3092")}); 1703 { 1704 List<TestAllTypes>::Reader listReader = test::TestConstants::STRUCT_LIST_CONST; 1705 ASSERT_EQ(3u, listReader.size()); 1706 EXPECT_EQ("structlist 1", listReader[0].getTextField()); 1707 EXPECT_EQ("structlist 2", listReader[1].getTextField()); 1708 EXPECT_EQ("structlist 3", listReader[2].getTextField()); 1709 } 1710 checkList(*test::TestConstants::ENUM_LIST_CONST, {TestEnum::FOO, TestEnum::GARPLY}); 1711 } 1712 1713 TEST(Encoding, AnyPointerConstants) { 1714 auto reader = test::ANY_POINTER_CONSTANTS.get(); 1715 1716 EXPECT_EQ("baz", reader.getAnyKindAsStruct().getAs<TestAllTypes>().getTextField()); 1717 EXPECT_EQ("baz", reader.getAnyStructAsStruct().as<TestAllTypes>().getTextField()); 1718 1719 EXPECT_EQ(111111111, reader.getAnyKindAsList().getAs<List<int32_t>>()[0]); 1720 EXPECT_EQ(111111111, reader.getAnyListAsList().as<List<int32_t>>()[0]); 1721 } 1722 1723 TEST(Encoding, GlobalConstants) { 1724 EXPECT_EQ(12345u, test::GLOBAL_INT); 1725 EXPECT_EQ("foobar", test::GLOBAL_TEXT.get()); 1726 EXPECT_EQ(54321, test::GLOBAL_STRUCT->getInt32Field()); 1727 1728 TestAllTypes::Reader reader = test::DERIVED_CONSTANT; 1729 1730 EXPECT_EQ(12345, reader.getUInt32Field()); 1731 EXPECT_EQ("foo", reader.getTextField()); 1732 checkList(reader.getStructField().getTextList(), {"quux", "corge", "grault"}); 1733 checkList(reader.getInt16List(), {11111, -11111}); 1734 { 1735 List<TestAllTypes>::Reader listReader = reader.getStructList(); 1736 ASSERT_EQ(3u, listReader.size()); 1737 EXPECT_EQ("structlist 1", listReader[0].getTextField()); 1738 EXPECT_EQ("structlist 2", listReader[1].getTextField()); 1739 EXPECT_EQ("structlist 3", listReader[2].getTextField()); 1740 } 1741 } 1742 1743 TEST(Encoding, Embeds) { 1744 { 1745 kj::ArrayInputStream input(test::EMBEDDED_DATA); 1746 PackedMessageReader reader(input); 1747 checkTestMessage(reader.getRoot<TestAllTypes>()); 1748 } 1749 1750 #if !CAPNP_LITE 1751 1752 { 1753 MallocMessageBuilder builder; 1754 auto root = builder.getRoot<TestAllTypes>(); 1755 initTestMessage(root); 1756 kj::StringPtr text = test::EMBEDDED_TEXT; 1757 EXPECT_EQ(kj::str(root, text.endsWith("\r\n") ? "\r\n" : "\n"), text); 1758 } 1759 1760 #endif // CAPNP_LITE 1761 1762 { 1763 checkTestMessage(test::EMBEDDED_STRUCT); 1764 } 1765 } 1766 1767 TEST(Encoding, HasEmptyStruct) { 1768 MallocMessageBuilder message; 1769 auto root = message.initRoot<test::TestAnyPointer>(); 1770 1771 EXPECT_EQ(1, root.totalSize().wordCount); 1772 1773 EXPECT_FALSE(root.asReader().hasAnyPointerField()); 1774 EXPECT_FALSE(root.hasAnyPointerField()); 1775 root.getAnyPointerField().initAs<test::TestEmptyStruct>(); 1776 EXPECT_TRUE(root.asReader().hasAnyPointerField()); 1777 EXPECT_TRUE(root.hasAnyPointerField()); 1778 1779 EXPECT_EQ(1, root.totalSize().wordCount); 1780 } 1781 1782 TEST(Encoding, HasEmptyList) { 1783 MallocMessageBuilder message; 1784 auto root = message.initRoot<test::TestAnyPointer>(); 1785 1786 EXPECT_EQ(1, root.totalSize().wordCount); 1787 1788 EXPECT_FALSE(root.asReader().hasAnyPointerField()); 1789 EXPECT_FALSE(root.hasAnyPointerField()); 1790 root.getAnyPointerField().initAs<List<int32_t>>(0); 1791 EXPECT_TRUE(root.asReader().hasAnyPointerField()); 1792 EXPECT_TRUE(root.hasAnyPointerField()); 1793 1794 EXPECT_EQ(1, root.totalSize().wordCount); 1795 } 1796 1797 TEST(Encoding, HasEmptyStructList) { 1798 MallocMessageBuilder message; 1799 auto root = message.initRoot<test::TestAnyPointer>(); 1800 1801 EXPECT_EQ(1, root.totalSize().wordCount); 1802 1803 EXPECT_FALSE(root.asReader().hasAnyPointerField()); 1804 EXPECT_FALSE(root.hasAnyPointerField()); 1805 root.getAnyPointerField().initAs<List<TestAllTypes>>(0); 1806 EXPECT_TRUE(root.asReader().hasAnyPointerField()); 1807 EXPECT_TRUE(root.hasAnyPointerField()); 1808 1809 EXPECT_EQ(2, root.totalSize().wordCount); 1810 } 1811 1812 TEST(Encoding, NameAnnotation) { 1813 EXPECT_EQ(2, static_cast<uint16_t>(test::RenamedStruct::RenamedEnum::QUX)); 1814 EXPECT_EQ(2, static_cast<uint16_t>(test::RenamedStruct::RenamedNestedStruct::RenamedDeeplyNestedEnum::GARPLY)); 1815 1816 MallocMessageBuilder message; 1817 auto root = message.initRoot<test::RenamedStruct>(); 1818 1819 root.setGoodFieldName(true); 1820 EXPECT_EQ(true, root.getGoodFieldName()); 1821 EXPECT_TRUE(root.isGoodFieldName()); 1822 1823 root.setBar(0xff); 1824 EXPECT_FALSE(root.isGoodFieldName()); 1825 1826 root.setAnotherGoodFieldName(test::RenamedStruct::RenamedEnum::QUX); 1827 EXPECT_EQ(test::RenamedStruct::RenamedEnum::QUX, root.getAnotherGoodFieldName()); 1828 1829 EXPECT_FALSE(root.getRenamedUnion().isQux()); 1830 auto quxBuilder = root.getRenamedUnion().initQux(); 1831 EXPECT_TRUE(root.getRenamedUnion().isQux()); 1832 EXPECT_FALSE(root.getRenamedUnion().getQux().hasAnotherGoodNestedFieldName()); 1833 1834 quxBuilder.setGoodNestedFieldName(true); 1835 EXPECT_EQ(true, quxBuilder.getGoodNestedFieldName()); 1836 1837 EXPECT_FALSE(quxBuilder.hasAnotherGoodNestedFieldName()); 1838 auto nestedFieldBuilder = quxBuilder.initAnotherGoodNestedFieldName(); 1839 EXPECT_TRUE(quxBuilder.hasAnotherGoodNestedFieldName()); 1840 1841 nestedFieldBuilder.setGoodNestedFieldName(true); 1842 EXPECT_EQ(true, nestedFieldBuilder.getGoodNestedFieldName()); 1843 EXPECT_FALSE(nestedFieldBuilder.hasAnotherGoodNestedFieldName()); 1844 1845 EXPECT_FALSE(root.getRenamedUnion().isRenamedGroup()); 1846 auto renamedGroupBuilder KJ_UNUSED = root.getRenamedUnion().initRenamedGroup(); 1847 EXPECT_TRUE(root.getRenamedUnion().isRenamedGroup()); 1848 1849 test::RenamedInterface::RenamedMethodParams::Reader renamedInterfaceParams; 1850 renamedInterfaceParams.getRenamedParam(); 1851 } 1852 1853 TEST(Encoding, DefaultFloatPlusNan) { 1854 MallocMessageBuilder message; 1855 auto root = message.initRoot<TestDefaults>(); 1856 1857 root.setFloat32Field(kj::nan()); 1858 root.setFloat64Field(kj::nan()); 1859 1860 float f = root.getFloat32Field(); 1861 EXPECT_TRUE(f != f); 1862 1863 double d = root.getFloat64Field(); 1864 EXPECT_TRUE(d != d); 1865 } 1866 1867 TEST(Encoding, WholeFloatDefault) { 1868 MallocMessageBuilder message; 1869 auto root = message.initRoot<test::TestWholeFloatDefault>(); 1870 1871 EXPECT_EQ(123.0f, root.getField()); 1872 EXPECT_EQ(2e30f, root.getBigField()); 1873 EXPECT_EQ(456.0f, test::TestWholeFloatDefault::CONSTANT); 1874 EXPECT_EQ(4e30f, test::TestWholeFloatDefault::BIG_CONSTANT); 1875 } 1876 1877 TEST(Encoding, Generics) { 1878 MallocMessageBuilder message; 1879 auto root = message.initRoot<test::TestUseGenerics>(); 1880 auto reader = root.asReader(); 1881 1882 initTestMessage(root.initBasic().initFoo()); 1883 checkTestMessage(reader.getBasic().getFoo()); 1884 1885 { 1886 auto typed = root.getBasic(); 1887 test::TestGenerics<>::Reader generic = typed.asGeneric<>(); 1888 checkTestMessage(generic.getFoo().getAs<TestAllTypes>()); 1889 test::TestGenerics<TestAllTypes>::Reader halfGeneric = typed.asGeneric<TestAllTypes>(); 1890 checkTestMessage(halfGeneric.getFoo()); 1891 } 1892 1893 { 1894 auto typed = root.getBasic().asReader(); 1895 test::TestGenerics<>::Reader generic = typed.asGeneric<>(); 1896 checkTestMessage(generic.getFoo().getAs<TestAllTypes>()); 1897 test::TestGenerics<TestAllTypes>::Reader halfGeneric = typed.asGeneric<TestAllTypes>(); 1898 checkTestMessage(halfGeneric.getFoo()); 1899 } 1900 1901 initTestMessage(root.initInner().initFoo()); 1902 checkTestMessage(reader.getInner().getFoo()); 1903 1904 { 1905 auto typed = root.getInner(); 1906 test::TestGenerics<>::Inner::Reader generic = typed.asTestGenericsGeneric<>(); 1907 checkTestMessage(generic.getFoo().getAs<TestAllTypes>()); 1908 test::TestGenerics<TestAllTypes>::Inner::Reader halfGeneric = typed.asTestGenericsGeneric<TestAllTypes>(); 1909 checkTestMessage(halfGeneric.getFoo()); 1910 } 1911 1912 { 1913 auto typed = root.getInner().asReader(); 1914 test::TestGenerics<>::Inner::Reader generic = typed.asTestGenericsGeneric<>(); 1915 checkTestMessage(generic.getFoo().getAs<TestAllTypes>()); 1916 test::TestGenerics<TestAllTypes>::Inner::Reader halfGeneric = typed.asTestGenericsGeneric<TestAllTypes>(); 1917 checkTestMessage(halfGeneric.getFoo()); 1918 } 1919 1920 root.initInner2().setBaz("foo"); 1921 EXPECT_EQ("foo", reader.getInner2().getBaz()); 1922 1923 initTestMessage(root.getInner2().initInnerBound().initFoo()); 1924 checkTestMessage(reader.getInner2().getInnerBound().getFoo()); 1925 1926 initTestMessage(root.getInner2().initInnerUnbound().getFoo().initAs<TestAllTypes>()); 1927 checkTestMessage(reader.getInner2().getInnerUnbound().getFoo().getAs<TestAllTypes>()); 1928 1929 initTestMessage(root.initUnspecified().getFoo().initAs<TestAllTypes>()); 1930 checkTestMessage(reader.getUnspecified().getFoo().getAs<TestAllTypes>()); 1931 1932 initTestMessage(root.initWrapper().initValue().initFoo()); 1933 checkTestMessage(reader.getWrapper().getValue().getFoo()); 1934 } 1935 1936 TEST(Encoding, GenericDefaults) { 1937 test::TestUseGenerics::Reader reader; 1938 1939 EXPECT_EQ(123, reader.getDefault().getFoo().getInt16Field()); 1940 EXPECT_EQ(123, reader.getDefaultInner().getFoo().getInt16Field()); 1941 EXPECT_EQ("text", reader.getDefaultInner().getBar()); 1942 EXPECT_EQ(123, reader.getDefaultUser().getBasic().getFoo().getInt16Field()); 1943 EXPECT_EQ("text", reader.getDefaultWrapper().getValue().getFoo()); 1944 EXPECT_EQ(321, reader.getDefaultWrapper().getValue().getRev().getFoo().getInt16Field()); 1945 EXPECT_EQ("text", reader.getDefaultWrapper2().getValue().getValue().getFoo()); 1946 EXPECT_EQ(321, reader.getDefaultWrapper2().getValue() 1947 .getValue().getRev().getFoo().getInt16Field()); 1948 } 1949 1950 TEST(Encoding, UnionInGenerics) { 1951 MallocMessageBuilder message; 1952 auto builder = message.initRoot<test::TestGenerics<>>(); 1953 auto reader = builder.asReader(); 1954 1955 //just call the methods to verify that generated code compiles 1956 reader.which(); 1957 builder.which(); 1958 1959 reader.isUv(); 1960 builder.isUv(); 1961 reader.getUv(); 1962 builder.getUv(); 1963 builder.setUv(); 1964 1965 builder.initUg(); 1966 1967 reader.isUg(); 1968 builder.isUg(); 1969 reader.getUg(); 1970 builder.getUg(); 1971 builder.initUg(); 1972 } 1973 1974 TEST(Encoding, DefaultListBuilder) { 1975 // At one point, this wouldn't compile. 1976 1977 List<int>::Builder(nullptr); 1978 List<TestAllTypes>::Builder(nullptr); 1979 List<List<int>>::Builder(nullptr); 1980 List<Text>::Builder(nullptr); 1981 } 1982 1983 TEST(Encoding, ListSize) { 1984 MallocMessageBuilder builder; 1985 auto root = builder.initRoot<TestListDefaults>(); 1986 initTestMessage(root); 1987 1988 auto lists = root.asReader().getLists(); 1989 1990 auto listSizes = 1991 lists.getList0().totalSize() + 1992 lists.getList1().totalSize() + 1993 lists.getList8().totalSize() + 1994 lists.getList16().totalSize() + 1995 lists.getList32().totalSize() + 1996 lists.getList64().totalSize() + 1997 lists.getListP().totalSize() + 1998 lists.getInt32ListList().totalSize() + 1999 lists.getTextListList().totalSize() + 2000 lists.getStructListList().totalSize(); 2001 2002 auto structSize = lists.totalSize(); 2003 2004 auto shallowSize = unbound(capnp::_::structSize<test::TestLists>().total() / WORDS); 2005 2006 EXPECT_EQ(structSize.wordCount - shallowSize, listSizes.wordCount); 2007 } 2008 2009 KJ_TEST("list.setWithCaveats(i, list[i]) doesn't corrupt contents") { 2010 MallocMessageBuilder builder; 2011 auto root = builder.initRoot<TestAllTypes>(); 2012 auto list = root.initStructList(2); 2013 initTestMessage(list[0]); 2014 list.setWithCaveats(0, list[0]); 2015 checkTestMessage(list[0]); 2016 checkTestMessageAllZero(list[1]); 2017 list.setWithCaveats(1, list[0]); 2018 checkTestMessage(list[0]); 2019 checkTestMessage(list[1]); 2020 } 2021 2022 } // namespace 2023 } // namespace _ (private) 2024 } // namespace capnp