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