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 module capnproto.tests.EncodingSuite;
23 
24 import java.nio.ByteBuffer;
25 
26 import capnproto;
27 
28 import capnproto.tests.test;
29 import capnproto.tests.testimport;
30 import capnproto.tests.TestUtil;
31 
32 //AllTypes
33 unittest
34 {
35 	auto message = new MessageBuilder();
36 	auto allTypes = message.initRoot!TestAllTypes();
37 	TestUtil.initTestMessage(allTypes);
38 	TestUtil.checkTestMessage(allTypes);
39 	TestUtil.checkTestMessage(allTypes.asReader());
40 }
41 
42 //AllTypesMultiSegment
43 unittest
44 {
45 	auto message = new MessageBuilder(5, BuilderArena.AllocationStrategy.FIXED_SIZE);
46 	auto allTypes = message.initRoot!TestAllTypes();
47 	TestUtil.initTestMessage(allTypes);
48 	
49 	TestUtil.checkTestMessage(allTypes);
50 	TestUtil.checkTestMessage(allTypes.asReader());
51 }
52 
53 //Setters
54 unittest
55 {
56 	auto message = new MessageBuilder();
57 	auto allTypes = message.initRoot!TestAllTypes();
58 	TestUtil.initTestMessage(allTypes);
59 	
60 	auto message2 = new MessageBuilder();
61 	auto allTypes2 = message2.initRoot!TestAllTypes();
62 	
63 	allTypes2.setStructField(allTypes.asReader());
64 	TestUtil.checkTestMessage(allTypes2.getStructField());
65 	auto reader = allTypes2.asReader().getStructField();
66 	TestUtil.checkTestMessage(reader);
67 }
68 
69 //Zeroing
70 unittest
71 {
72 	auto message = new MessageBuilder();
73 	auto allTypes = message.initRoot!TestAllTypes();
74 	
75 	auto structList = allTypes.initStructList(3);
76 	TestUtil.initTestMessage(structList.get(0));
77 	
78 	auto structField = allTypes.initStructField();
79 	TestUtil.initTestMessage(structField);
80 	
81 	TestUtil.initTestMessage(structList.get(1));
82 	TestUtil.initTestMessage(structList.get(2));
83 	TestUtil.checkTestMessage(structList.get(0));
84 	allTypes.initStructList(0);
85 	
86 	TestUtil.checkTestMessage(allTypes.getStructField());
87 	auto allTypesReader = allTypes.asReader();
88 	TestUtil.checkTestMessage(allTypesReader.getStructField());
89 	
90 	auto any = message.initRoot!AnyPointer();
91 	auto segments = message.getSegmentsForOutput();
92 	foreach(segment; segments)
93 	{
94 		foreach(jj; 0..segment.limit - 1)
95 			assert(segment.get!ubyte(jj) == 0);
96 	}
97 }
98 
99 //DoubleFarPointers
100 unittest
101 {
102 	ubyte[] bytes = [2,0,0,0, 1,0,0,0, 2,0,  0,  0, 1,0,0,0,
103 	                 6,0,0,0, 1,0,0,0, 2,0,  0,  0, 2,0,0,0,
104 	                 0,0,0,0, 1,0,0,0, 1,7,255,127, 0,0,0,0];
105 	
106 	auto input = new ArrayInputStream(ByteBuffer(bytes));
107 	auto message = Serialize.read(input);
108 	auto root = message.getRoot!TestAllTypes();
109 	assert(root.getBoolField() == true);
110 	assert(root.getInt8Field() == 7);
111 	assert(root.getInt16Field() == 32767);
112 }
113 
114 //UpgradeStructInBuilder
115 unittest
116 {
117 	auto builder = new MessageBuilder();
118 	auto root = builder.initRoot!TestAnyPointer();
119 	
120 	{
121 		auto oldVersion = root.getAnyPointerField().initAs!TestOldVersion();
122 		oldVersion.setOld1(123);
123 		oldVersion.setOld2("foo");
124 		auto sub = oldVersion.initOld3();
125 		sub.setOld1(456);
126 		sub.setOld2("bar");
127 	}
128 	
129 	{
130 		auto newVersion = root.getAnyPointerField().getAs!TestNewVersion();
131 		assert(newVersion.getOld1() == 123);
132 		assert(newVersion.getOld2().toString() == "foo");
133 		assert(newVersion.getNew1() == 987);
134 		assert(newVersion.getNew2().toString() == "baz");
135 		
136 		auto sub = newVersion.getOld3();
137 		assert(sub.getOld1() == 456);
138 		assert(sub.getOld2().toString() == "bar");
139 		
140 		newVersion.setOld1(234);
141 		newVersion.setOld2("qux");
142 		newVersion.setNew1(654);
143 		newVersion.setNew2("quux");
144 	}
145 	
146 	{
147 		auto oldVersion = root.getAnyPointerField().getAs!TestOldVersion();
148 		assert(oldVersion.getOld1() == 234);
149 		assert(oldVersion.getOld2.toString() == "qux");
150 	}
151 }
152 
153 //StructListUpgrade
154 unittest
155 {
156 	auto message = new MessageBuilder();
157 	auto root = message.initRoot!TestAnyPointer();
158 	auto any = root.getAnyPointerField();
159 	
160 	{
161 		auto longs = any.initAs!(PrimitiveList!long)(3);
162 		longs.set(0, 123);
163 		longs.set(1, 456);
164 		longs.set(2, 789);
165 	}
166 	
167 	{
168 		auto olds = any.asReader().getAs!(StructList!TestOldVersion)();
169 		assert(olds.get(0).getOld1() == 123);
170 		assert(olds.get(1).getOld1() == 456);
171 		assert(olds.get(2).getOld1() == 789);
172 	}
173 	
174 	{
175 		auto olds = any.getAs!(StructList!TestOldVersion)();
176 		assert(olds.length == 3);
177 		assert(olds.get(0).getOld1() == 123);
178 		assert(olds.get(1).getOld1() == 456);
179 		assert(olds.get(2).getOld1() == 789);
180 		
181 		olds.get(0).setOld2("zero");
182 		olds.get(1).setOld2("one");
183 		olds.get(2).setOld2("two");
184 	}
185 	
186 	{
187 		auto news = any.getAs!(StructList!TestNewVersion)();
188 		assert(news.length == 3);
189 		assert(news.get(0).getOld1() == 123);
190 		assert(news.get(0).getOld2().toString() == "zero");
191 		
192 		assert(news.get(1).getOld1() == 456);
193 		assert(news.get(1).getOld2().toString() == "one");
194 		
195 		assert(news.get(2).getOld1() == 789);
196 		assert(news.get(2).getOld2().toString() == "two");
197 	}
198 }
199 
200 //StructListUpgradeDoubleFar
201 unittest
202 {
203 	ubyte[] bytes = [
204 	           1, 0, 0, 0, 0x1f, 0, 0, 0, //List, inline composite, 3 words.
205 	           4, 0, 0, 0,    1, 0, 2, 0, //Struct tag. 1 element, 1 word data, 2 pointers.
206 	          91, 0, 0, 0,    0, 0, 0, 0, //Data: 91.
207 	        0x05, 0, 0, 0, 0x42, 0, 0, 0, //List pointer, offset 1, type = BYTE, length 8.
208 	           0, 0, 0, 0,    0, 0, 0, 0, //Null pointer.
209 	        0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x21, 0x21, 0]; //"hello!!".
210 	
211 	auto segment = ByteBuffer(bytes);
212 	auto messageReader = new MessageReader([segment], ReaderOptions.DEFAULT_READER_OPTIONS);
213 	
214 	auto oldVersion = messageReader.getRoot!(StructList!TestOldVersion)();
215 	
216 	assert(oldVersion.length == 1);
217 	assert(oldVersion.get(0).getOld1() == 91);
218 	assert(oldVersion.get(0).getOld2() == "hello!!");
219 	
220 	//Make the first segment exactly large enough to fit the original message.
221 	//This leaves no room for a far pointer landing pad in the first segment.
222 	auto message = new MessageBuilder(6);
223 	message.setRoot!TestOldVersion(oldVersion);
224 	
225 	auto segments = message.getSegmentsForOutput();
226 	assert(segments.length == 1);
227 	assert(segments[0].limit == 6 * 8);
228 	
229 	auto newVersion = message.getRoot!(StructList!TestNewVersion)();
230 	assert(newVersion.length == 1);
231 	assert(newVersion.get(0).getOld1() == 91);
232 	assert(newVersion.get(0).getOld2().toString() == "hello!!");
233 	
234 	auto segments1 = message.getSegmentsForOutput();
235 	assert(segments[0].limit == 6 * 8);
236 	//Check the the old list, including the tag, was zeroed.
237 	foreach(ii; 8..(5 * 8) - 1)
238 		assert(segments[0].get!ubyte(ii) == 0);
239 }
240 
241 //Generics
242 unittest
243 {
244 	auto message = new MessageBuilder();
245 	auto root = message.initRoot!(TestGenerics!(TestAllTypes, Text))();
246 	TestUtil.initTestMessage(root.getFoo());
247 	root.getDub().setFoo(Text.Reader("Hello"));
248 	auto bar = root.getDub().initBar(1);
249 	bar.set(0, 11);
250 	auto revBar = root.getRev().getBar();
251 	revBar.setInt8Field(111);
252 	auto boolList = revBar.initBoolList(2);
253 	boolList.set(0, false);
254 	boolList.set(1, true);
255 	
256 	TestUtil.checkTestMessage(root.getFoo());
257 	auto rootReader = root.asReader();
258 	TestUtil.checkTestMessage(rootReader.getFoo());
259 	auto dubReader = root.getDub();
260 	assert(dubReader.getFoo().toString() == "Hello");
261 	auto barReader = dubReader.getBar();
262 	assert(barReader.length == 1);
263 	assert(barReader.get(0) == 11);
264 }
265 
266 //UseGenerics
267 unittest
268 {
269 	auto message = new MessageBuilder();
270 	auto root = message.initRoot!TestUseGenerics();
271 	
272 	{
273 		auto message2 = new MessageBuilder();
274 		auto root2 = message2.initRoot!(TestGenerics!(AnyPointer, AnyPointer))();
275 		root2.initDub().setFoo(Text.Reader("foobar"));
276 		
277 		root.setUnspecified(root2.asReader());
278 	}
279 	
280 	auto rootReader = root.asReader();
281 	assert(root.getUnspecified().getDub().getFoo().toString() == "foobar");
282 }
283 
284 //Defaults
285 unittest
286 {
287 	auto message = new MessageBuilder();
288 	auto defaults = message.initRoot!TestDefaults();
289 	TestUtil.checkDefaultMessage(defaults);
290 	TestUtil.checkDefaultMessage(defaults.asReader());
291 	TestUtil.setDefaultMessage(defaults);
292 	TestUtil.checkSettedDefaultMessage(defaults.asReader());
293 }
294 
295 //Unions
296 unittest
297 {
298 	auto builder = new MessageBuilder();
299 	auto root = builder.initRoot!TestUnion();
300 	auto u0 = root.initUnion0();
301 	u0.initU0f1sp(10);
302 	assert(u0.which() == TestUnion.Union0.Which.u0f1sp);
303 	
304 	u0.initPrimitiveList(10);
305 	assert(u0.which() == TestUnion.Union0.Which.primitiveList);
306 }
307 
308 //Groups
309 unittest
310 {
311 	auto builder = new MessageBuilder();
312 	auto root = builder.initRoot!TestGroups();
313 	
314 	{
315 		auto foo = root.getGroups().initFoo();
316 		foo.setCorge(12345678);
317 		foo.setGrault(123456789012345L);
318 		foo.setGarply(Text.Reader("foobar"));
319 		
320 		assert(foo.getCorge() == 12345678);
321 		assert(foo.getGrault() == 123456789012345L);
322 		assert(foo.getGarply().toString() == "foobar");
323 	}
324 	
325 	{
326 		auto bar = root.getGroups.initBar();
327 		bar.setCorge(23456789);
328 		bar.setGrault(Text.Reader("barbaz"));
329 		bar.setGarply(234567890123456L);
330 		
331 		assert(bar.getCorge() == 23456789);
332 		assert(bar.getGrault().toString() == "barbaz");
333 		assert(bar.getGarply() == 234567890123456L);
334 	}
335 	
336 	{
337 		auto baz = root.getGroups().initBaz();
338 		baz.setCorge(34567890);
339 		baz.setGrault(Text.Reader("bazqux"));
340 		baz.setGarply(Text.Reader("quxquux"));
341 		
342 		assert(baz.getCorge() == 34567890);
343 		assert(baz.getGrault().toString() == "bazqux");
344 		assert(baz.getGarply().toString() == "quxquux");
345 	}
346 }
347 
348 
349 //NestedLists
350 unittest
351 {
352 	auto builder = new MessageBuilder();
353 	auto root = builder.initRoot!TestLists();
354 	
355 	{
356 		auto intListList = root.initInt32ListList(2);
357 		auto intList0 = intListList.init(0, 4);
358 		intList0.set(0, 1);
359 		intList0.set(1, 2);
360 		intList0.set(2, 3);
361 		intList0.set(3, 4);
362 		auto intList1 = intListList.init(1, 1);
363 		intList1.set(0, 100);
364 	}
365 	
366 	{
367 		auto reader = root.asReader();
368 		auto intListList = root.getInt32ListList();
369 		assert(intListList.length == 2);
370 		auto intList0 = intListList.get(0);
371 		assert(intList0.length == 4);
372 		assert(intList0.get(0) == 1);
373 		assert(intList0.get(1) == 2);
374 		assert(intList0.get(2) == 3);
375 		assert(intList0.get(3) == 4);
376 		auto intList1 = intListList.get(1);
377 		assert(intList1.length == 1);
378 		assert(intList1.get(0) == 100);
379 	}
380 }
381 
382 //Constants
383 unittest
384 {
385 	assert(TestConstants.voidConst == Void.VOID);
386 	assert(TestConstants.boolConst == true);
387 	assert(TestConstants.int8Const == -123);
388 	assert(TestConstants.int16Const == -12345);
389 	assert(TestConstants.int32Const == -12345678);
390 	assert(TestConstants.int64Const == -123456789012345L);
391 	
392 	assert(TestConstants.uint8Const == cast(ubyte)-22);
393 	assert(TestConstants.uint16Const == cast(ushort)-19858);
394 	assert(TestConstants.uint32Const == cast(uint)-838178284);
395 	assert(TestConstants.uint64Const == cast(ulong)-6101065172474983726L);
396 	
397 	assert(TestConstants.float32Const == 1234.5f);
398 	assert(TestConstants.float64Const == -123e45);
399 	
400 	assert(TestConstants.textConst.get().toString() == "foo");
401 	assert(TestConstants.dataConst.get().toArray() == TestUtil.data("bar"));
402 	
403 	assert(TestConstants.enumConst == TestEnum.corge);
404 	
405 	{
406 		auto subReader = TestConstants.structConst.get();
407 		assert(subReader.getBoolField() == true);
408 		assert(subReader.getInt8Field() == -12);
409 		assert(subReader.getInt16Field() == 3456);
410 		assert(subReader.getInt32Field() == -78901234);
411 		assert(subReader.getInt64Field() == 56789012345678L);
412 		assert(subReader.getUInt8Field() == 90);
413 		assert(subReader.getUInt16Field == 1234);
414 		assert(subReader.getUInt32Field() == 56789012);
415 		assert(subReader.getUInt64Field() == 345678901234567890L);
416 		assert(subReader.getFloat32Field() == -1.25e-10f);
417 		assert(subReader.getFloat64Field() == 345);
418 		assert(subReader.getTextField() == "baz");
419 	}
420 	
421 	assert(TestConstants.voidListConst.get().length == 6);
422 	
423 	{
424 		auto listReader = TestConstants.boolListConst.get();
425 		assert(listReader.length == 4);
426 		assert(listReader.get(0) == true);
427 		assert(listReader.get(1) == false);
428 		assert(listReader.get(2) == false);
429 		assert(listReader.get(3) == true);
430 	}
431 	
432 	{
433 		auto listReader = TestConstants.textListConst.get();
434 		assert(listReader.length == 3);
435 		assert(listReader.get(0) == "plugh");
436 		assert(listReader.get(1) == "xyzzy");
437 		assert(listReader.get(2) == "thud");
438 	}
439 	
440 	{
441 		auto listReader = TestConstants.structListConst.get();
442 		assert(listReader.length == 3);
443 		assert(listReader.get(0).getTextField() == "structlist 1");
444 		assert(listReader.get(1).getTextField() == "structlist 2");
445 		assert(listReader.get(2).getTextField() == "structlist 3");
446 	}
447 }
448 
449 //GlobalConstants
450 unittest
451 {
452 	assert(globalInt == 12345);
453 }
454 
455 //EmptyStruct
456 unittest
457 {
458 	auto builder = new MessageBuilder();
459 	auto root = builder.initRoot!TestAnyPointer();
460 	assert(root.hasAnyPointerField() == false);
461 	auto any = root.getAnyPointerField();
462 	assert(any.isNull() == true);
463 	any.initAs!TestEmptyStruct();
464 	assert(any.isNull() == false);
465 	assert(root.hasAnyPointerField() == true);
466 	
467 	{
468 		auto rootReader = root.asReader();
469 		assert(rootReader.hasAnyPointerField() == true);
470 		assert(rootReader.getAnyPointerField().isNull() == false);
471 	}
472 }
473 
474 //TextBuilderIntUnderflow
475 unittest
476 {
477 	import std.exception : assertThrown;
478 	auto message = new MessageBuilder();
479 	auto root = message.initRoot!TestAnyPointer();
480 	root.getAnyPointerField.initAs!Data(0);
481 	assertThrown!DecodeException(root.getAnyPointerField.getAs!Text());
482 }
483 
484 //InlineCompositeListIntOverflow
485 unittest
486 {
487 	import std.exception : assertThrown;
488 	ubyte[] bytes = [0,0,0,0,    0,0,1,0,
489 	                 1,0,0,0, 0x17,0,0,0, 0,0,0,0xff, 16,0,0,0,
490 	                 0,0,0,0,    0,0,0,0, 0,0,0,   0,  0,0,0,0];
491 	
492 	auto segment = ByteBuffer(bytes);
493 	auto message = new MessageReader([segment], ReaderOptions.DEFAULT_READER_OPTIONS);
494 	
495 	auto root = message.getRoot!TestAnyPointer();
496 	//TODO: Add this after we implement totalSize():
497 	//root.totalSize();
498 	
499 	assertThrown!DecodeException(root.getAnyPointerField.getAs!(StructList!TestAllTypes)());
500 	
501 	auto messageBuilder = new MessageBuilder();
502 	auto builderRoot = messageBuilder.initRoot!TestAnyPointer();
503 	assertThrown!DecodeException(builderRoot.getAnyPointerField.setAs!TestAnyPointer(root));
504 }
505 
506 //VoidListAmplification
507 unittest
508 {
509 	import std.exception : assertThrown;
510 	auto builder = new MessageBuilder();
511 	builder.initRoot!TestAnyPointer().getAnyPointerField().initAs!(PrimitiveList!Void)(1 << 28);
512 	
513 	auto segments = builder.getSegmentsForOutput();
514 	assert(segments.length == 1);
515 	
516 	auto reader = new MessageReader(segments, ReaderOptions.DEFAULT_READER_OPTIONS);
517 	auto root = reader.getRoot!TestAnyPointer();
518 	assertThrown!DecodeException(root.getAnyPointerField().getAs!(StructList!TestAllTypes)());
519 }
520 
521 //EmptyStructListAmplification
522 unittest
523 {
524 	import std.exception : assertThrown;
525 	auto builder = new MessageBuilder();
526 	builder.initRoot!TestAnyPointer().getAnyPointerField().initAs!(StructList!TestEmptyStruct)((1 << 29) - 1);
527 	
528 	auto segments = builder.getSegmentsForOutput();
529 	assert(segments.length == 1);
530 	
531 	auto reader = new MessageReader(segments, ReaderOptions.DEFAULT_READER_OPTIONS);
532 	auto root = reader.getRoot!TestAnyPointer();
533 	assertThrown!DecodeException(root.getAnyPointerField().getAs!(StructList!TestAllTypes)());
534 }
535 
536 //LongUint8List
537 unittest
538 {
539 	auto message = new MessageBuilder();
540 	auto allTypes = message.initRoot!TestAllTypes();
541 	auto length = (1 << 28) + 1;
542 	auto list = allTypes.initUInt8List(length);
543 	assert(list.length == length);
544 	list.set(length - 1, 3);
545 	assert(list.get(length - 1) == 3);
546 	assert(allTypes.asReader().getUInt8List().get(length - 1) == 3);
547 }
548 
549 
550 //LongUint16List
551 unittest
552 {
553 	auto message = new MessageBuilder();
554 	auto allTypes = message.initRoot!TestAllTypes();
555 	auto length = (1 << 27) + 1;
556 	auto list = allTypes.initUInt16List(length);
557 	assert(list.length == length);
558 	list.set(length - 1, 3);
559 	assert(list.get(length - 1) == 3);
560 	assert(allTypes.asReader().getUInt16List().get(length - 1) == 3);
561 }
562 
563 //LongUint32List
564 unittest
565 {
566 	auto message = new MessageBuilder();
567 	auto allTypes = message.initRoot!TestAllTypes();
568 	auto length = (1 << 26) + 1;
569 	auto list = allTypes.initUInt32List(length);
570 	assert(list.length == length);
571 	list.set(length - 1, 3);
572 	assert(list.get(length - 1) == 3);
573 	assert(allTypes.asReader().getUInt32List().get(length - 1) == 3);
574 }
575 
576 //LongUint64List
577 unittest
578 {
579 	auto message = new MessageBuilder();
580 	auto allTypes = message.initRoot!TestAllTypes();
581 	auto length = (1 << 25) + 1;
582 	auto list = allTypes.initUInt64List(length);
583 	assert(list.length == length);
584 	list.set(length - 1, 3);
585 	assert(list.get(length - 1) == 3);
586 	assert(allTypes.asReader().getUInt64List().get(length - 1) == 3);
587 }
588 
589 //LongFloat32List
590 unittest
591 {
592 	auto message = new MessageBuilder();
593 	auto allTypes = message.initRoot!TestAllTypes();
594 	auto length = (1 << 26) + 1;
595 	auto list = allTypes.initFloat32List(length);
596 	assert(list.length == length);
597 	list.set(length - 1, 3.14f);
598 	assert(list.get(length - 1) == 3.14f);
599 	assert(allTypes.asReader().getFloat32List().get(length - 1) == 3.14f);
600 }
601 
602 //LongFloat64List
603 unittest
604 {
605 	auto message = new MessageBuilder();
606 	auto allTypes = message.initRoot!TestAllTypes();
607 	auto length = (1 << 25) + 1;
608 	auto list = allTypes.initFloat64List(length);
609 	assert(list.length == length);
610 	list.set(length - 1, 3.14);
611 	assert(list.get(length - 1) == 3.14);
612 	assert(allTypes.asReader().getFloat64List().get(length - 1) == 3.14);
613 }
614 
615 //LongStructList
616 unittest
617 {
618 	auto message = new MessageBuilder();
619 	auto allTypes = message.initRoot!TestAllTypes();
620 	auto length = (1 << 21) + 1;
621 	auto list = allTypes.initStructList(length);
622 	assert(list.length == length);
623 	list.get(length - 1).setUInt8Field(3);
624 	assert(allTypes.asReader().getStructList().get(length - 1).getUInt8Field() == 3);
625 }
626 
627 //LongTextList
628 unittest
629 {
630 	auto message = new MessageBuilder();
631 	auto allTypes = message.initRoot!TestAllTypes();
632 	auto length = (1 << 25) + 1;
633 	auto list = allTypes.initTextList(length);
634 	assert(list.length == length);
635 	list.set(length - 1, Text.Reader("foo"));
636 	assert(allTypes.asReader().getTextList().get(length - 1) == "foo");
637 }
638 
639 //LongListList
640 unittest
641 {
642 	auto message = new MessageBuilder();
643 	auto root = message.initRoot!TestLists();
644 	auto length = (1 << 25) + 1;
645 	auto list = root.initStructListList(length);
646 	assert(list.length == length);
647 	list.init(length - 1, 3);
648 	assert(list.get(length - 1).length == 3);
649 	assert(root.asReader().getStructListList().get(length - 1).length == 3);
650 }
651 
652 //StructSetters
653 unittest
654 {
655 	auto builder = new MessageBuilder();
656 	auto root = builder.initRoot!TestAllTypes();
657 	TestUtil.initTestMessage(root);
658 	
659 	{
660 		auto builder2 = new MessageBuilder();
661 		builder2.setRoot!TestAllTypes(root.asReader());
662 		TestUtil.checkTestMessage(builder2.getRoot!TestAllTypes());
663 	}
664 	
665 	{
666 		auto builder2 = new MessageBuilder();
667 		auto root2 = builder2.getRoot!TestAllTypes();
668 		root2.setStructField(root.asReader());
669 		TestUtil.checkTestMessage(root2.getStructField());
670 	}
671 	
672 	{
673 		auto builder2 = new MessageBuilder();
674 		auto root2 = builder2.getRoot!TestAnyPointer();
675 		root2.getAnyPointerField().setAs!TestAllTypes(root.asReader());
676 		TestUtil.checkTestMessage(root2.getAnyPointerField.getAs!TestAllTypes());
677 	}
678 }
679 
680 //SerializedSize
681 unittest
682 {
683 	auto builder = new MessageBuilder();
684 	auto root = builder.initRoot!TestAnyPointer();
685 	root.getAnyPointerField().setAs!Text(Text.Reader("12345"));
686 	
687 	//One word for segment table, one for the root pointer,
688 	//one for the body of the TestAnyPointer struct,
689 	//and one for the body of the Text.
690 	assert(Serialize.computeSerializedSizeInWords(builder) == 4);
691 }
692 
693 //Import
694 unittest
695 {
696 	auto builder = new MessageBuilder();
697 	auto root = builder.initRoot!Foo();
698 	auto field = root.initImportedStruct();
699 	TestUtil.initTestMessage(field);
700 	TestUtil.checkTestMessage(field);
701 	TestUtil.checkTestMessage(field.asReader());
702 }
703 
704 //GenericMap
705 unittest
706 {
707 	auto builder = new MessageBuilder();
708 	auto root = builder.initRoot!(GenericMap!(Text, TestAllTypes))();
709 	
710 	{
711 		auto entries = root.initEntries(3);
712 		
713 		auto entry0 = entries.get(0);
714 		entry0.setKey(Text.Reader("foo"));
715 		auto value0 = entry0.initValue();
716 		value0.setInt64Field(101);
717 		
718 		auto entry1 = entries.get(1);
719 		entry1.setKey(Text.Reader("bar"));
720 		auto value1 = entry1.initValue();
721 		value1.setInt64Field(202);
722 		
723 		auto entry2 = entries.get(2);
724 		entry2.setKey(Text.Reader("baz"));
725 		auto value2 = entry2.initValue();
726 		value2.setInt64Field(303);
727 	}
728 	
729 	{
730 		auto entries = root.asReader().getEntries();
731 		auto entry0 = entries.get(0);
732 		assert(entry0.getKey().toString() == "foo");
733 		assert(entry0.getValue().getInt64Field() == 101);
734 		
735 		auto entry1 = entries.get(1);
736 		assert(entry1.getKey().toString() == "bar");
737 		assert(entry1.getValue().getInt64Field() == 202);
738 		
739 		auto entry2 = entries.get(2);
740 		assert(entry2.getKey().toString() == "baz");
741 		assert(entry2.getValue().getInt64Field == 303);
742 	}
743 }