layout-test.c++ 16.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
// Copyright (c) 2013, Kenton Varda <temporal@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Kenton Varda's avatar
Kenton Varda committed
24
#define CAPNP_PRIVATE
25
#include "layout.h"
Kenton Varda's avatar
Kenton Varda committed
26
#include "message.h"
27
#include "arena.h"
28 29
#include <gtest/gtest.h>

30
namespace capnp {
Kenton Varda's avatar
Kenton Varda committed
31
  template <typename T, typename U>
32 33
  std::ostream& operator<<(std::ostream& os, kj::Quantity<T, U> value) {
    return os << (value / kj::unit<kj::Quantity<T, U>>());
Kenton Varda's avatar
Kenton Varda committed
34 35 36
  }
}

37
namespace capnp {
38
namespace _ {  // private
39 40
namespace {

Kenton Varda's avatar
Kenton Varda committed
41 42
TEST(WireFormat, SimpleRawDataStruct) {
  AlignedData<2> data = {{
43
    // Struct ref, offset = 1, dataSize = 1, pointerCount = 0
44
    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
45
    // Content for the data section.
Kenton Varda's avatar
Kenton Varda committed
46 47
    0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
  }};
48

49
  StructReader reader = StructReader::readRootUnchecked(data.words);
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64

  EXPECT_EQ(0xefcdab8967452301ull, reader.getDataField<uint64_t>(0 * ELEMENTS));
  EXPECT_EQ(0u, reader.getDataField<uint64_t>(1 * ELEMENTS));
  EXPECT_EQ(0x67452301u, reader.getDataField<uint32_t>(0 * ELEMENTS));
  EXPECT_EQ(0xefcdab89u, reader.getDataField<uint32_t>(1 * ELEMENTS));
  EXPECT_EQ(0u, reader.getDataField<uint32_t>(2 * ELEMENTS));
  EXPECT_EQ(0x2301u, reader.getDataField<uint16_t>(0 * ELEMENTS));
  EXPECT_EQ(0x6745u, reader.getDataField<uint16_t>(1 * ELEMENTS));
  EXPECT_EQ(0xab89u, reader.getDataField<uint16_t>(2 * ELEMENTS));
  EXPECT_EQ(0xefcdu, reader.getDataField<uint16_t>(3 * ELEMENTS));
  EXPECT_EQ(0u, reader.getDataField<uint16_t>(4 * ELEMENTS));

  EXPECT_EQ(321u ^ 0xefcdab8967452301ull, reader.getDataField<uint64_t>(0 * ELEMENTS, 321u));
  EXPECT_EQ(321u ^ 0x67452301u, reader.getDataField<uint32_t>(0 * ELEMENTS, 321u));
  EXPECT_EQ(321u ^ 0x2301u, reader.getDataField<uint16_t>(0 * ELEMENTS, 321u));
65 66 67 68 69
  EXPECT_EQ(321u, reader.getDataField<uint64_t>(1 * ELEMENTS, 321u));
  EXPECT_EQ(321u, reader.getDataField<uint32_t>(2 * ELEMENTS, 321u));
  EXPECT_EQ(321u, reader.getDataField<uint16_t>(4 * ELEMENTS, 321u));

  // Bits
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
  EXPECT_TRUE (reader.getDataField<bool>(0 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(1 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(2 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(3 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(4 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(5 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(6 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(7 * ELEMENTS));

  EXPECT_TRUE (reader.getDataField<bool>( 8 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>( 9 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(10 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(11 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(12 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>(13 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(14 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(15 * ELEMENTS));

  EXPECT_TRUE (reader.getDataField<bool>(63 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(64 * ELEMENTS));

91 92
  EXPECT_TRUE (reader.getDataField<bool>(0 * ELEMENTS, false));
  EXPECT_FALSE(reader.getDataField<bool>(1 * ELEMENTS, false));
Kenton Varda's avatar
Kenton Varda committed
93
  EXPECT_TRUE (reader.getDataField<bool>(63 * ELEMENTS, false));
94
  EXPECT_FALSE(reader.getDataField<bool>(64 * ELEMENTS, false));
95 96 97 98
  EXPECT_FALSE(reader.getDataField<bool>(0 * ELEMENTS, true));
  EXPECT_TRUE (reader.getDataField<bool>(1 * ELEMENTS, true));
  EXPECT_FALSE(reader.getDataField<bool>(63 * ELEMENTS, true));
  EXPECT_TRUE (reader.getDataField<bool>(64 * ELEMENTS, true));
99 100
}

101
static const AlignedData<2> SUBSTRUCT_DEFAULT = {{0,0,0,0,1,0,0,0,  0,0,0,0,0,0,0,0}};
102
static const AlignedData<2> STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT =
103
    {{0,0,0,0,1,0,0,0,  0,0,0,0,0,0,0,0}};
104

105
static constexpr StructSize STRUCTLIST_ELEMENT_SIZE(
106
    1 * WORDS, 1 * POINTERS, FieldSize::INLINE_COMPOSITE);
107

Kenton Varda's avatar
Kenton Varda committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
static void setupStruct(StructBuilder builder) {
  builder.setDataField<uint64_t>(0 * ELEMENTS, 0x1011121314151617ull);
  builder.setDataField<uint32_t>(2 * ELEMENTS, 0x20212223u);
  builder.setDataField<uint16_t>(6 * ELEMENTS, 0x3031u);
  builder.setDataField<uint8_t>(14 * ELEMENTS, 0x40u);
  builder.setDataField<bool>(120 * ELEMENTS, false);
  builder.setDataField<bool>(121 * ELEMENTS, false);
  builder.setDataField<bool>(122 * ELEMENTS, true);
  builder.setDataField<bool>(123 * ELEMENTS, false);
  builder.setDataField<bool>(124 * ELEMENTS, true);
  builder.setDataField<bool>(125 * ELEMENTS, true);
  builder.setDataField<bool>(126 * ELEMENTS, true);
  builder.setDataField<bool>(127 * ELEMENTS, false);

  {
123
    StructBuilder subStruct = builder.initStructField(
124
        0 * POINTERS, StructSize(1 * WORDS, 0 * POINTERS, FieldSize::EIGHT_BYTES));
Kenton Varda's avatar
Kenton Varda committed
125 126 127 128
    subStruct.setDataField<uint32_t>(0 * ELEMENTS, 123);
  }

  {
129
    ListBuilder list = builder.initListField(1 * POINTERS, FieldSize::FOUR_BYTES, 3 * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
130 131 132 133 134 135 136 137
    EXPECT_EQ(3 * ELEMENTS, list.size());
    list.setDataElement<int32_t>(0 * ELEMENTS, 200);
    list.setDataElement<int32_t>(1 * ELEMENTS, 201);
    list.setDataElement<int32_t>(2 * ELEMENTS, 202);
  }

  {
    ListBuilder list = builder.initStructListField(
138
        2 * POINTERS, 4 * ELEMENTS, STRUCTLIST_ELEMENT_SIZE);
Kenton Varda's avatar
Kenton Varda committed
139 140
    EXPECT_EQ(4 * ELEMENTS, list.size());
    for (int i = 0; i < 4; i++) {
Kenton Varda's avatar
Kenton Varda committed
141
      StructBuilder element = list.getStructElement(i * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
142
      element.setDataField<int32_t>(0 * ELEMENTS, 300 + i);
143 144
      element.initStructField(0 * POINTERS,
                              StructSize(1 * WORDS, 0 * POINTERS, FieldSize::EIGHT_BYTES))
Kenton Varda's avatar
Kenton Varda committed
145 146 147 148 149
             .setDataField<int32_t>(0 * ELEMENTS, 400 + i);
    }
  }

  {
150
    ListBuilder list = builder.initListField(3 * POINTERS, FieldSize::POINTER, 5 * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
151 152 153
    EXPECT_EQ(5 * ELEMENTS, list.size());
    for (uint i = 0; i < 5; i++) {
      ListBuilder element = list.initListElement(
154
          i * ELEMENTS, FieldSize::TWO_BYTES, (i + 1) * ELEMENTS);
Kenton Varda's avatar
Kenton Varda committed
155 156 157 158 159 160 161 162
      EXPECT_EQ((i + 1) * ELEMENTS, element.size());
      for (uint j = 0; j <= i; j++) {
        element.setDataElement<uint16_t>(j * ELEMENTS, 500 + j);
      }
    }
  }
}

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
static void checkStruct(StructBuilder builder) {
  EXPECT_EQ(0x1011121314151617ull, builder.getDataField<uint64_t>(0 * ELEMENTS));
  EXPECT_EQ(0x20212223u, builder.getDataField<uint32_t>(2 * ELEMENTS));
  EXPECT_EQ(0x3031u, builder.getDataField<uint16_t>(6 * ELEMENTS));
  EXPECT_EQ(0x40u, builder.getDataField<uint8_t>(14 * ELEMENTS));
  EXPECT_FALSE(builder.getDataField<bool>(120 * ELEMENTS));
  EXPECT_FALSE(builder.getDataField<bool>(121 * ELEMENTS));
  EXPECT_TRUE (builder.getDataField<bool>(122 * ELEMENTS));
  EXPECT_FALSE(builder.getDataField<bool>(123 * ELEMENTS));
  EXPECT_TRUE (builder.getDataField<bool>(124 * ELEMENTS));
  EXPECT_TRUE (builder.getDataField<bool>(125 * ELEMENTS));
  EXPECT_TRUE (builder.getDataField<bool>(126 * ELEMENTS));
  EXPECT_FALSE(builder.getDataField<bool>(127 * ELEMENTS));

  {
178
    StructBuilder subStruct = builder.getStructField(
179
        0 * POINTERS, StructSize(1 * WORDS, 0 * POINTERS, FieldSize::EIGHT_BYTES),
180
        SUBSTRUCT_DEFAULT.words);
181 182 183 184
    EXPECT_EQ(123u, subStruct.getDataField<uint32_t>(0 * ELEMENTS));
  }

  {
185
    ListBuilder list = builder.getListField(1 * POINTERS, FieldSize::FOUR_BYTES, nullptr);
186 187 188 189 190 191 192
    ASSERT_EQ(3 * ELEMENTS, list.size());
    EXPECT_EQ(200, list.getDataElement<int32_t>(0 * ELEMENTS));
    EXPECT_EQ(201, list.getDataElement<int32_t>(1 * ELEMENTS));
    EXPECT_EQ(202, list.getDataElement<int32_t>(2 * ELEMENTS));
  }

  {
193
    ListBuilder list = builder.getStructListField(2 * POINTERS, STRUCTLIST_ELEMENT_SIZE, nullptr);
194 195
    ASSERT_EQ(4 * ELEMENTS, list.size());
    for (int i = 0; i < 4; i++) {
Kenton Varda's avatar
Kenton Varda committed
196
      StructBuilder element = list.getStructElement(i * ELEMENTS);
197 198
      EXPECT_EQ(300 + i, element.getDataField<int32_t>(0 * ELEMENTS));
      EXPECT_EQ(400 + i,
199 200
          element.getStructField(0 * POINTERS,
                                 StructSize(1 * WORDS, 0 * POINTERS, FieldSize::EIGHT_BYTES),
201
                                 STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT.words)
202 203 204 205 206
              .getDataField<int32_t>(0 * ELEMENTS));
    }
  }

  {
207
    ListBuilder list = builder.getListField(3 * POINTERS, FieldSize::POINTER, nullptr);
208 209
    ASSERT_EQ(5 * ELEMENTS, list.size());
    for (uint i = 0; i < 5; i++) {
210
      ListBuilder element = list.getListElement(i * ELEMENTS, FieldSize::TWO_BYTES);
211 212 213 214 215 216 217 218
      ASSERT_EQ((i + 1) * ELEMENTS, element.size());
      for (uint j = 0; j <= i; j++) {
        EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
      }
    }
  }
}

Kenton Varda's avatar
Kenton Varda committed
219
static void checkStruct(StructReader reader) {
220 221 222 223 224 225 226 227 228 229 230 231
  EXPECT_EQ(0x1011121314151617ull, reader.getDataField<uint64_t>(0 * ELEMENTS));
  EXPECT_EQ(0x20212223u, reader.getDataField<uint32_t>(2 * ELEMENTS));
  EXPECT_EQ(0x3031u, reader.getDataField<uint16_t>(6 * ELEMENTS));
  EXPECT_EQ(0x40u, reader.getDataField<uint8_t>(14 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(120 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(121 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>(122 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(123 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>(124 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>(125 * ELEMENTS));
  EXPECT_TRUE (reader.getDataField<bool>(126 * ELEMENTS));
  EXPECT_FALSE(reader.getDataField<bool>(127 * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
232 233

  {
234
    StructReader subStruct = reader.getStructField(0 * POINTERS, SUBSTRUCT_DEFAULT.words);
235
    EXPECT_EQ(123u, subStruct.getDataField<uint32_t>(0 * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
236 237 238
  }

  {
239
    ListReader list = reader.getListField(1 * POINTERS, FieldSize::FOUR_BYTES, nullptr);
Kenton Varda's avatar
Kenton Varda committed
240 241 242 243 244 245 246
    ASSERT_EQ(3 * ELEMENTS, list.size());
    EXPECT_EQ(200, list.getDataElement<int32_t>(0 * ELEMENTS));
    EXPECT_EQ(201, list.getDataElement<int32_t>(1 * ELEMENTS));
    EXPECT_EQ(202, list.getDataElement<int32_t>(2 * ELEMENTS));
  }

  {
247
    ListReader list = reader.getListField(2 * POINTERS, FieldSize::INLINE_COMPOSITE, nullptr);
Kenton Varda's avatar
Kenton Varda committed
248 249
    ASSERT_EQ(4 * ELEMENTS, list.size());
    for (int i = 0; i < 4; i++) {
250 251
      StructReader element = list.getStructElement(i * ELEMENTS);
      EXPECT_EQ(300 + i, element.getDataField<int32_t>(0 * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
252
      EXPECT_EQ(400 + i,
253
          element.getStructField(0 * POINTERS, STRUCTLIST_ELEMENT_SUBSTRUCT_DEFAULT.words)
254
              .getDataField<int32_t>(0 * ELEMENTS));
Kenton Varda's avatar
Kenton Varda committed
255 256 257 258
    }
  }

  {
259
    ListReader list = reader.getListField(3 * POINTERS, FieldSize::POINTER, nullptr);
Kenton Varda's avatar
Kenton Varda committed
260 261
    ASSERT_EQ(5 * ELEMENTS, list.size());
    for (uint i = 0; i < 5; i++) {
262
      ListReader element = list.getListElement(i * ELEMENTS, FieldSize::TWO_BYTES);
Kenton Varda's avatar
Kenton Varda committed
263 264 265 266 267 268 269 270
      ASSERT_EQ((i + 1) * ELEMENTS, element.size());
      for (uint j = 0; j <= i; j++) {
        EXPECT_EQ(500u + j, element.getDataElement<uint16_t>(j * ELEMENTS));
      }
    }
  }
}

271
TEST(WireFormat, StructRoundTrip_OneSegment) {
272 273
  MallocMessageBuilder message;
  BuilderArena arena(&message);
274 275 276
  auto allocation = arena.allocate(1 * WORDS);
  SegmentBuilder* segment = allocation.segment;
  word* rootLocation = allocation.words;
Kenton Varda's avatar
Kenton Varda committed
277

278
  StructBuilder builder = StructBuilder::initRoot(
279
      segment, rootLocation, StructSize(2 * WORDS, 4 * POINTERS, FieldSize::INLINE_COMPOSITE));
Kenton Varda's avatar
Kenton Varda committed
280 281 282
  setupStruct(builder);

  // word count:
283
  //    1  root pointer
Kenton Varda's avatar
Kenton Varda committed
284 285 286 287 288 289
  //    6  root struct
  //    1  sub message
  //    2  3-element int32 list
  //   13  struct list
  //         1 tag
  //        12 4x struct
290 291
  //           1 data section
  //           1 pointer section
Kenton Varda's avatar
Kenton Varda committed
292 293
  //           1 sub-struct
  //   11  list list
294
  //         5 pointers to sub-lists
Kenton Varda's avatar
Kenton Varda committed
295 296 297
  //         6 sub-lists (4x 1 word, 1x 2 words)
  // -----
  //   34
298
  kj::ArrayPtr<const kj::ArrayPtr<const word>> segments = arena.getSegmentsForOutput();
299 300
  ASSERT_EQ(1u, segments.size());
  EXPECT_EQ(34u, segments[0].size());
Kenton Varda's avatar
Kenton Varda committed
301

302
  checkStruct(builder);
Kenton Varda's avatar
Kenton Varda committed
303
  checkStruct(builder.asReader());
304
  checkStruct(StructReader::readRootUnchecked(segment->getStartPtr()));
305
  checkStruct(StructReader::readRoot(segment->getStartPtr(), segment, 4));
Kenton Varda's avatar
Kenton Varda committed
306 307
}

308
TEST(WireFormat, StructRoundTrip_OneSegmentPerAllocation) {
309 310
  MallocMessageBuilder message(0, AllocationStrategy::FIXED_SIZE);
  BuilderArena arena(&message);
311 312 313
  auto allocation = arena.allocate(1 * WORDS);
  SegmentBuilder* segment = allocation.segment;
  word* rootLocation = allocation.words;
Kenton Varda's avatar
Kenton Varda committed
314

315
  StructBuilder builder = StructBuilder::initRoot(
316
      segment, rootLocation, StructSize(2 * WORDS, 4 * POINTERS, FieldSize::INLINE_COMPOSITE));
Kenton Varda's avatar
Kenton Varda committed
317 318
  setupStruct(builder);

Kenton Varda's avatar
Kenton Varda committed
319
  // Verify that we made 15 segments.
320
  kj::ArrayPtr<const kj::ArrayPtr<const word>> segments = arena.getSegmentsForOutput();
321
  ASSERT_EQ(15u, segments.size());
Kenton Varda's avatar
Kenton Varda committed
322

Kenton Varda's avatar
Kenton Varda committed
323
  // Check that each segment has the expected size.  Recall that the first word of each segment will
324
  // actually be a pointer to the first thing allocated within that segment.
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
  EXPECT_EQ( 1u, segments[ 0].size());  // root ref
  EXPECT_EQ( 7u, segments[ 1].size());  // root struct
  EXPECT_EQ( 2u, segments[ 2].size());  // sub-struct
  EXPECT_EQ( 3u, segments[ 3].size());  // 3-element int32 list
  EXPECT_EQ(10u, segments[ 4].size());  // struct list
  EXPECT_EQ( 2u, segments[ 5].size());  // struct list substruct 1
  EXPECT_EQ( 2u, segments[ 6].size());  // struct list substruct 2
  EXPECT_EQ( 2u, segments[ 7].size());  // struct list substruct 3
  EXPECT_EQ( 2u, segments[ 8].size());  // struct list substruct 4
  EXPECT_EQ( 6u, segments[ 9].size());  // list list
  EXPECT_EQ( 2u, segments[10].size());  // list list sublist 1
  EXPECT_EQ( 2u, segments[11].size());  // list list sublist 2
  EXPECT_EQ( 2u, segments[12].size());  // list list sublist 3
  EXPECT_EQ( 2u, segments[13].size());  // list list sublist 4
  EXPECT_EQ( 3u, segments[14].size());  // list list sublist 5
Kenton Varda's avatar
Kenton Varda committed
340

341
  checkStruct(builder);
Kenton Varda's avatar
Kenton Varda committed
342
  checkStruct(builder.asReader());
343
  checkStruct(StructReader::readRoot(segment->getStartPtr(), segment, 4));
344 345 346
}

TEST(WireFormat, StructRoundTrip_MultipleSegmentsWithMultipleAllocations) {
347 348
  MallocMessageBuilder message(8, AllocationStrategy::FIXED_SIZE);
  BuilderArena arena(&message);
349 350 351
  auto allocation = arena.allocate(1 * WORDS);
  SegmentBuilder* segment = allocation.segment;
  word* rootLocation = allocation.words;
352

353
  StructBuilder builder = StructBuilder::initRoot(
354
      segment, rootLocation, StructSize(2 * WORDS, 4 * POINTERS, FieldSize::INLINE_COMPOSITE));
355 356 357
  setupStruct(builder);

  // Verify that we made 6 segments.
358
  kj::ArrayPtr<const kj::ArrayPtr<const word>> segments = arena.getSegmentsForOutput();
359
  ASSERT_EQ(6u, segments.size());
360 361 362

  // Check that each segment has the expected size.  Recall that each object will be prefixed by an
  // extra word if its parent is in a different segment.
363 364 365 366 367 368
  EXPECT_EQ( 8u, segments[0].size());  // root ref + struct + sub
  EXPECT_EQ( 3u, segments[1].size());  // 3-element int32 list
  EXPECT_EQ(10u, segments[2].size());  // struct list
  EXPECT_EQ( 8u, segments[3].size());  // struct list substructs
  EXPECT_EQ( 8u, segments[4].size());  // list list + sublist 1,2
  EXPECT_EQ( 7u, segments[5].size());  // list list sublist 3,4,5
369 370 371

  checkStruct(builder);
  checkStruct(builder.asReader());
372
  checkStruct(StructReader::readRoot(segment->getStartPtr(), segment, 4));
Kenton Varda's avatar
Kenton Varda committed
373 374
}

375
}  // namespace
376
}  // namespace _ (private)
377
}  // namespace capnp