llvm.org GIT mirror llvm / 854f9fd
[PDB] Add tests for BinaryStream. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296555 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 2 years ago
2 changed file(s) with 644 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- llvm/unittest/Support/BinaryStreamTest.cpp -------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/MSF/BinaryByteStream.h"
10 #include "llvm/DebugInfo/MSF/BinaryItemStream.h"
11 #include "llvm/DebugInfo/MSF/BinaryStreamArray.h"
12 #include "llvm/DebugInfo/MSF/BinaryStreamReader.h"
13 #include "llvm/DebugInfo/MSF/BinaryStreamRef.h"
14 #include "llvm/DebugInfo/MSF/BinaryStreamWriter.h"
15 #include "gtest/gtest.h"
16
17 #include
18
19 using namespace llvm;
20 using namespace llvm::support;
21
22 #define EXPECT_NO_ERROR(Err) \
23 { \
24 auto E = Err; \
25 EXPECT_FALSE(static_cast(E)); \
26 if (E) \
27 consumeError(std::move(E)); \
28 }
29
30 #define ASSERT_NO_ERROR(Err) \
31 { \
32 auto E = Err; \
33 ASSERT_FALSE(static_cast(E)); \
34 if (E) \
35 consumeError(std::move(E)); \
36 }
37
38 #define EXPECT_ERROR(Err) \
39 { \
40 auto E = Err; \
41 EXPECT_TRUE(static_cast(E)); \
42 if (E) \
43 consumeError(std::move(E)); \
44 }
45
46 namespace {
47
48 class DiscontiguousStream : public WritableBinaryStream {
49 public:
50 DiscontiguousStream(MutableArrayRef Data, endianness Endian)
51 : Data(Data), PartitionIndex(Data.size() / 2), Endian(Endian) {}
52
53 endianness getEndian() const override { return Endian; }
54
55 Error readBytes(uint32_t Offset, uint32_t Size,
56 ArrayRef &Buffer) override {
57 if (Offset + Size > Data.size())
58 return errorCodeToError(make_error_code(std::errc::no_buffer_space));
59 uint32_t S = startIndex(Offset);
60 auto Ref = Data.drop_front(S);
61 if (Ref.size() >= Size) {
62 Buffer = Ref.take_front(Size);
63 return Error::success();
64 }
65
66 uint32_t BytesLeft = Size - Ref.size();
67 uint8_t *Ptr = Allocator.Allocate(Size);
68 ::memcpy(Ptr, Ref.data(), Ref.size());
69 ::memcpy(Ptr + Ref.size(), Data.data(), BytesLeft);
70 Buffer = makeArrayRef(Ptr, Size);
71 return Error::success();
72 }
73
74 Error readLongestContiguousChunk(uint32_t Offset,
75 ArrayRef &Buffer) override {
76 if (Offset >= Data.size())
77 return errorCodeToError(make_error_code(std::errc::no_buffer_space));
78 uint32_t S = startIndex(Offset);
79 Buffer = Data.drop_front(S);
80 return Error::success();
81 }
82
83 uint32_t getLength() override { return Data.size(); }
84
85 Error writeBytes(uint32_t Offset, ArrayRef SrcData) override {
86 if (Offset + SrcData.size() > Data.size())
87 return errorCodeToError(make_error_code(std::errc::no_buffer_space));
88 if (SrcData.empty())
89 return Error::success();
90
91 uint32_t S = startIndex(Offset);
92 MutableArrayRef Ref(Data);
93 Ref = Ref.drop_front(S);
94 if (Ref.size() >= SrcData.size()) {
95 ::memcpy(Ref.data(), SrcData.data(), SrcData.size());
96 return Error::success();
97 }
98
99 uint32_t BytesLeft = SrcData.size() - Ref.size();
100 ::memcpy(Ref.data(), SrcData.data(), Ref.size());
101 ::memcpy(&Data[0], SrcData.data() + Ref.size(), BytesLeft);
102 return Error::success();
103 }
104 Error commit() override { return Error::success(); }
105
106 private:
107 uint32_t startIndex(uint32_t Offset) const {
108 return (Offset + PartitionIndex) % Data.size();
109 }
110
111 uint32_t endIndex(uint32_t Offset, uint32_t Size) const {
112 return (startIndex(Offset) + Size - 1) % Data.size();
113 }
114
115 // Buffer is organized like this:
116 // -------------------------------------------------
117 // | N/2 | N/2+1 | ... | N-1 | 0 | 1 | ... | N-2-1 |
118 // -------------------------------------------------
119 // So reads from the beginning actually come from the middle.
120 MutableArrayRef Data;
121 uint32_t PartitionIndex = 0;
122 endianness Endian;
123 BumpPtrAllocator Allocator;
124 };
125
126 class BinaryStreamTest : public testing::Test {
127 static constexpr endianness Endians[] = {big, little, native};
128 static constexpr uint32_t NumEndians = llvm::array_lengthof(Endians);
129 static constexpr uint32_t NumStreams = 2 * NumEndians;
130
131 public:
132 BinaryStreamTest() {}
133
134 void SetUp() override {
135 Streams.clear();
136 Streams.resize(NumStreams);
137 InputData.clear();
138 OutputData.clear();
139 }
140
141 protected:
142 struct StreamPair {
143 std::unique_ptr Input;
144 std::unique_ptr Output;
145 };
146
147 void initializeInput(ArrayRef Input) {
148 InputData = Input;
149
150 BrokenInputData.resize(InputData.size());
151 if (!Input.empty()) {
152 uint32_t PartitionIndex = InputData.size() / 2;
153 uint32_t RightBytes = InputData.size() - PartitionIndex;
154 uint32_t LeftBytes = PartitionIndex;
155 if (RightBytes > 0)
156 ::memcpy(&BrokenInputData[PartitionIndex], Input.data(), RightBytes);
157 if (LeftBytes > 0)
158 ::memcpy(&BrokenInputData[0], Input.data() + RightBytes, LeftBytes);
159 }
160
161 for (uint32_t I = 0; I < NumEndians; ++I) {
162 auto InByteStream =
163 llvm::make_unique(InputData, Endians[I]);
164 auto InBrokenStream =
165 llvm::make_unique(BrokenInputData, Endians[I]);
166
167 Streams[I * 2].Input = std::move(InByteStream);
168 Streams[I * 2 + 1].Input = std::move(InBrokenStream);
169 }
170 }
171
172 void initializeOutput(uint32_t Size) {
173 OutputData.resize(Size);
174 BrokenOutputData.resize(Size);
175
176 for (uint32_t I = 0; I < NumEndians; ++I) {
177 Streams[I * 2].Output =
178 llvm::make_unique(OutputData, Endians[I]);
179 Streams[I * 2 + 1].Output =
180 llvm::make_unique(BrokenOutputData, Endians[I]);
181 }
182 }
183
184 void initializeOutputFromInput() {
185 for (uint32_t I = 0; I < NumEndians; ++I) {
186 Streams[I * 2].Output =
187 llvm::make_unique(InputData, Endians[I]);
188 Streams[I * 2 + 1].Output =
189 llvm::make_unique(BrokenInputData, Endians[I]);
190 }
191 }
192
193 void initializeInputFromOutput() {
194 for (uint32_t I = 0; I < NumEndians; ++I) {
195 Streams[I * 2].Input =
196 llvm::make_unique(OutputData, Endians[I]);
197 Streams[I * 2 + 1].Input =
198 llvm::make_unique(BrokenOutputData, Endians[I]);
199 }
200 }
201
202 std::vector InputData;
203 std::vector BrokenInputData;
204
205 std::vector OutputData;
206 std::vector BrokenOutputData;
207
208 std::vector Streams;
209 };
210
211 // Tests that a we can read from a BinaryByteStream without a StreamReader.
212 TEST_F(BinaryStreamTest, BinaryByteStreamProperties) {
213 std::vector InputData = {1, 2, 3, 4, 5};
214 initializeInput(InputData);
215
216 for (auto &Stream : Streams) {
217 ArrayRef Buffer;
218
219 // 1. If the read fits it should work.
220 ASSERT_EQ(InputData.size(), Stream.Input->getLength());
221 ASSERT_NO_ERROR(Stream.Input->readBytes(2, 1, Buffer));
222 EXPECT_EQ(makeArrayRef(InputData).slice(2, 1), Buffer);
223 ASSERT_NO_ERROR(Stream.Input->readBytes(0, 4, Buffer));
224 EXPECT_EQ(makeArrayRef(InputData).slice(0, 4), Buffer);
225
226 // 2. Reading past the bounds of the input should fail.
227 EXPECT_ERROR(Stream.Input->readBytes(4, 2, Buffer));
228 }
229 }
230
231 // Test that we can write to a BinaryStream without a StreamWriter.
232 TEST_F(BinaryStreamTest, MutableBinaryByteStreamProperties) {
233 std::vector InputData = {'T', 'e', 's', 't', '\0'};
234 initializeInput(InputData);
235 initializeOutput(InputData.size());
236
237 // For every combination of input stream and output stream.
238 for (auto &Stream : Streams) {
239 MutableArrayRef Buffer;
240 ASSERT_EQ(InputData.size(), Stream.Input->getLength());
241
242 // 1. Try two reads that are supposed to work. One from offset 0, and one
243 // from the middle.
244 uint32_t Offsets[] = {0, 3};
245 for (auto Offset : Offsets) {
246 uint32_t ExpectedSize = Stream.Input->getLength() - Offset;
247
248 // Read everything from Offset until the end of the input data.
249 ArrayRef Data;
250 ASSERT_NO_ERROR(Stream.Input->readBytes(Offset, ExpectedSize, Data));
251 ASSERT_EQ(ExpectedSize, Data.size());
252
253 // Then write it to the destination.
254 ASSERT_NO_ERROR(Stream.Output->writeBytes(0, Data));
255
256 // Then we read back what we wrote, it should match the corresponding
257 // slice of the original input data.
258 ArrayRef Data2;
259 ASSERT_NO_ERROR(Stream.Output->readBytes(Offset, ExpectedSize, Data2));
260 EXPECT_EQ(makeArrayRef(InputData).drop_front(Offset), Data2);
261 }
262
263 std::vector BigData = {0, 1, 2, 3, 4};
264 // 2. If the write is too big, it should fail.
265 EXPECT_ERROR(Stream.Output->writeBytes(3, BigData));
266 }
267 }
268
269 // Test that FixedStreamArray works correctly.
270 TEST_F(BinaryStreamTest, FixedStreamArray) {
271 std::vector Ints = {90823, 12908, 109823, 209823};
272 ArrayRef IntBytes(reinterpret_cast(Ints.data()),
273 Ints.size() * sizeof(uint32_t));
274
275 initializeInput(IntBytes);
276
277 for (auto &Stream : Streams) {
278 MutableArrayRef Buffer;
279 ASSERT_EQ(InputData.size(), Stream.Input->getLength());
280
281 FixedStreamArray Array(*Stream.Input);
282 auto Iter = Array.begin();
283 ASSERT_EQ(Ints[0], *Iter++);
284 ASSERT_EQ(Ints[1], *Iter++);
285 ASSERT_EQ(Ints[2], *Iter++);
286 ASSERT_EQ(Ints[3], *Iter++);
287 ASSERT_EQ(Array.end(), Iter);
288 }
289 }
290
291 // Test that VarStreamArray works correctly.
292 TEST_F(BinaryStreamTest, VarStreamArray) {
293 StringLiteral Strings("1. Test2. Longer Test3. Really Long Test4. Super "
294 "Extra Longest Test Of All");
295 ArrayRef StringBytes(
296 reinterpret_cast(Strings.data()), Strings.size());
297 initializeInput(StringBytes);
298
299 struct StringExtractor {
300 public:
301 Error operator()(BinaryStreamRef Stream, uint32_t &Len, StringRef &Item) {
302 if (Index == 0)
303 Len = strlen("1. Test");
304 else if (Index == 1)
305 Len = strlen("2. Longer Test");
306 else if (Index == 2)
307 Len = strlen("3. Really Long Test");
308 else
309 Len = strlen("4. Super Extra Longest Test Of All");
310 ArrayRef Bytes;
311 if (auto EC = Stream.readBytes(0, Len, Bytes))
312 return EC;
313 Item =
314 StringRef(reinterpret_cast(Bytes.data()), Bytes.size());
315 ++Index;
316 return Error::success();
317 }
318
319 private:
320 uint32_t Index = 0;
321 };
322
323 for (auto &Stream : Streams) {
324 VarStreamArray Array(*Stream.Input);
325 auto Iter = Array.begin();
326 ASSERT_EQ("1. Test", *Iter++);
327 ASSERT_EQ("2. Longer Test", *Iter++);
328 ASSERT_EQ("3. Really Long Test", *Iter++);
329 ASSERT_EQ("4. Super Extra Longest Test Of All", *Iter++);
330 ASSERT_EQ(Array.end(), Iter);
331 }
332 }
333
334 TEST_F(BinaryStreamTest, StreamReaderBounds) {
335 std::vector Bytes;
336
337 initializeInput(Bytes);
338 for (auto &Stream : Streams) {
339 StringRef S;
340 BinaryStreamReader Reader(*Stream.Input);
341 EXPECT_EQ(0U, Reader.bytesRemaining());
342 EXPECT_ERROR(Reader.readFixedString(S, 1));
343 }
344
345 Bytes.resize(5);
346 initializeInput(Bytes);
347 for (auto &Stream : Streams) {
348 StringRef S;
349 BinaryStreamReader Reader(*Stream.Input);
350 EXPECT_EQ(Bytes.size(), Reader.bytesRemaining());
351 EXPECT_NO_ERROR(Reader.readFixedString(S, 5));
352 EXPECT_ERROR(Reader.readFixedString(S, 6));
353 }
354 }
355
356 TEST_F(BinaryStreamTest, StreamReaderIntegers) {
357 support::ulittle64_t Little{908234};
358 support::ubig32_t Big{28907823};
359 short NS = 2897;
360 int NI = -89723;
361 unsigned long NUL = 902309023UL;
362 constexpr uint32_t Size =
363 sizeof(Little) + sizeof(Big) + sizeof(NS) + sizeof(NI) + sizeof(NUL);
364
365 initializeOutput(Size);
366 initializeInputFromOutput();
367
368 for (auto &Stream : Streams) {
369 BinaryStreamWriter Writer(*Stream.Output);
370 ASSERT_NO_ERROR(Writer.writeObject(Little));
371 ASSERT_NO_ERROR(Writer.writeObject(Big));
372 ASSERT_NO_ERROR(Writer.writeInteger(NS));
373 ASSERT_NO_ERROR(Writer.writeInteger(NI));
374 ASSERT_NO_ERROR(Writer.writeInteger(NUL));
375
376 const support::ulittle64_t *Little2;
377 const support::ubig32_t *Big2;
378 short NS2;
379 int NI2;
380 unsigned long NUL2;
381
382 // 1. Reading fields individually.
383 BinaryStreamReader Reader(*Stream.Input);
384 ASSERT_NO_ERROR(Reader.readObject(Little2));
385 ASSERT_NO_ERROR(Reader.readObject(Big2));
386 ASSERT_NO_ERROR(Reader.readInteger(NS2));
387 ASSERT_NO_ERROR(Reader.readInteger(NI2));
388 ASSERT_NO_ERROR(Reader.readInteger(NUL2));
389 ASSERT_EQ(0U, Reader.bytesRemaining());
390
391 EXPECT_EQ(Little, *Little2);
392 EXPECT_EQ(Big, *Big2);
393 EXPECT_EQ(NS, NS2);
394 EXPECT_EQ(NI, NI2);
395 EXPECT_EQ(NUL, NUL2);
396 }
397 }
398
399 TEST_F(BinaryStreamTest, StreamReaderIntegerArray) {
400 // 1. Arrays of integers
401 std::vector Ints = {1, 2, 3, 4, 5};
402 ArrayRef IntBytes(reinterpret_cast(&Ints[0]),
403 Ints.size() * sizeof(int));
404
405 initializeInput(IntBytes);
406 for (auto &Stream : Streams) {
407 BinaryStreamReader Reader(*Stream.Input);
408 ArrayRef IntsRef;
409 ASSERT_NO_ERROR(Reader.readArray(IntsRef, Ints.size()));
410 ASSERT_EQ(0U, Reader.bytesRemaining());
411 EXPECT_EQ(makeArrayRef(Ints), IntsRef);
412
413 Reader.setOffset(0);
414 FixedStreamArray FixedIntsRef;
415 ASSERT_NO_ERROR(Reader.readArray(FixedIntsRef, Ints.size()));
416 ASSERT_EQ(0U, Reader.bytesRemaining());
417 ASSERT_EQ(Ints, std::vector(FixedIntsRef.begin(), FixedIntsRef.end()));
418 }
419 }
420
421 TEST_F(BinaryStreamTest, StreamReaderEnum) {
422 enum class MyEnum : int64_t { Foo = -10, Bar = 0, Baz = 10 };
423
424 std::vector Enums = {MyEnum::Bar, MyEnum::Baz, MyEnum::Foo};
425
426 initializeOutput(Enums.size() * sizeof(MyEnum));
427 initializeInputFromOutput();
428 for (auto &Stream : Streams) {
429 BinaryStreamWriter Writer(*Stream.Output);
430 for (auto Value : Enums)
431 ASSERT_NO_ERROR(Writer.writeEnum(Value));
432
433 BinaryStreamReader Reader(*Stream.Input);
434
435 ArrayRef Array;
436 FixedStreamArray FSA;
437
438 for (size_t I = 0; I < Enums.size(); ++I) {
439 MyEnum Value;
440 ASSERT_NO_ERROR(Reader.readEnum(Value));
441 EXPECT_EQ(Enums[I], Value);
442 }
443 ASSERT_EQ(0U, Reader.bytesRemaining());
444 }
445 }
446
447 TEST_F(BinaryStreamTest, StreamReaderObject) {
448 struct Foo {
449 int X;
450 double Y;
451 char Z;
452 };
453
454 std::vector Foos;
455 Foos.push_back({-42, 42.42, 42});
456 Foos.push_back({100, 3.1415, static_cast(-89)});
457
458 const uint8_t *Bytes = reinterpret_cast(&Foos[0]);
459
460 initializeInput(makeArrayRef(Bytes, 2 * sizeof(Foo)));
461
462 for (auto &Stream : Streams) {
463 // 1. Reading object pointers.
464 BinaryStreamReader Reader(*Stream.Input);
465 const Foo *FPtrOut = nullptr;
466 const Foo *GPtrOut = nullptr;
467 ASSERT_NO_ERROR(Reader.readObject(FPtrOut));
468 ASSERT_NO_ERROR(Reader.readObject(GPtrOut));
469 EXPECT_EQ(0U, Reader.bytesRemaining());
470 EXPECT_EQ(0, ::memcmp(&Foos[0], FPtrOut, sizeof(Foo)));
471 EXPECT_EQ(0, ::memcmp(&Foos[1], GPtrOut, sizeof(Foo)));
472 }
473 }
474
475 TEST_F(BinaryStreamTest, StreamReaderStrings) {
476 std::vector Bytes = {'O', 'n', 'e', '\0', 'T', 'w', 'o',
477 '\0', 'T', 'h', 'r', 'e', 'e', '\0',
478 'F', 'o', 'u', 'r', '\0'};
479 initializeInput(Bytes);
480
481 for (auto &Stream : Streams) {
482 BinaryStreamReader Reader(*Stream.Input);
483
484 StringRef S1;
485 StringRef S2;
486 StringRef S3;
487 StringRef S4;
488 ASSERT_NO_ERROR(Reader.readCString(S1));
489 ASSERT_NO_ERROR(Reader.readCString(S2));
490 ASSERT_NO_ERROR(Reader.readCString(S3));
491 ASSERT_NO_ERROR(Reader.readCString(S4));
492 ASSERT_EQ(0U, Reader.bytesRemaining());
493
494 EXPECT_EQ("One", S1);
495 EXPECT_EQ("Two", S2);
496 EXPECT_EQ("Three", S3);
497 EXPECT_EQ("Four", S4);
498
499 S1 = S2 = S3 = S4 = "";
500 Reader.setOffset(0);
501 ASSERT_NO_ERROR(Reader.readFixedString(S1, 3));
502 ASSERT_NO_ERROR(Reader.skip(1));
503 ASSERT_NO_ERROR(Reader.readFixedString(S2, 3));
504 ASSERT_NO_ERROR(Reader.skip(1));
505 ASSERT_NO_ERROR(Reader.readFixedString(S3, 5));
506 ASSERT_NO_ERROR(Reader.skip(1));
507 ASSERT_NO_ERROR(Reader.readFixedString(S4, 4));
508 ASSERT_NO_ERROR(Reader.skip(1));
509 ASSERT_EQ(0U, Reader.bytesRemaining());
510
511 EXPECT_EQ("One", S1);
512 EXPECT_EQ("Two", S2);
513 EXPECT_EQ("Three", S3);
514 EXPECT_EQ("Four", S4);
515 }
516 }
517
518 TEST_F(BinaryStreamTest, StreamWriterBounds) {
519 initializeOutput(5);
520
521 for (auto &Stream : Streams) {
522 BinaryStreamWriter Writer(*Stream.Output);
523
524 // 1. Can write a string that exactly fills the buffer.
525 EXPECT_EQ(5U, Writer.bytesRemaining());
526 EXPECT_NO_ERROR(Writer.writeFixedString("abcde"));
527 EXPECT_EQ(0U, Writer.bytesRemaining());
528
529 // 2. Can write an empty string even when you're full
530 EXPECT_NO_ERROR(Writer.writeFixedString(""));
531 EXPECT_ERROR(Writer.writeFixedString("a"));
532
533 // 3. Can't write a string that is one character too long.
534 Writer.setOffset(0);
535 EXPECT_ERROR(Writer.writeFixedString("abcdef"));
536 }
537 }
538
539 TEST_F(BinaryStreamTest, StreamWriterIntegerArrays) {
540 // 3. Arrays of integers
541 std::vector SourceInts = {1, 2, 3, 4, 5};
542 ArrayRef SourceBytes(reinterpret_cast(&SourceInts[0]),
543 SourceInts.size() * sizeof(int));
544
545 initializeInput(SourceBytes);
546 initializeOutputFromInput();
547
548 for (auto &Stream : Streams) {
549 BinaryStreamReader Reader(*Stream.Input);
550 BinaryStreamWriter Writer(*Stream.Output);
551 ArrayRef Ints;
552 ArrayRef Ints2;
553 // First read them, then write them, then read them back.
554 ASSERT_NO_ERROR(Reader.readArray(Ints, SourceInts.size()));
555 ASSERT_NO_ERROR(Writer.writeArray(Ints));
556
557 BinaryStreamReader ReaderBacker(*Stream.Output);
558 ASSERT_NO_ERROR(ReaderBacker.readArray(Ints2, SourceInts.size()));
559
560 EXPECT_EQ(makeArrayRef(SourceInts), Ints2);
561 }
562 }
563
564 TEST_F(BinaryStreamTest, StringWriterStrings) {
565 StringRef Strings[] = {"First", "Second", "Third", "Fourth"};
566
567 size_t Length = 0;
568 for (auto S : Strings)
569 Length += S.size() + 1;
570 initializeOutput(Length);
571 initializeInputFromOutput();
572
573 for (auto &Stream : Streams) {
574 BinaryStreamWriter Writer(*Stream.Output);
575 for (auto S : Strings)
576 ASSERT_NO_ERROR(Writer.writeCString(S));
577 std::vector InStrings;
578 BinaryStreamReader Reader(*Stream.Input);
579 while (!Reader.empty()) {
580 StringRef S;
581 ASSERT_NO_ERROR(Reader.readCString(S));
582 InStrings.push_back(S);
583 }
584 EXPECT_EQ(makeArrayRef(Strings), makeArrayRef(InStrings));
585 }
586 }
587 }
588
589 namespace {
590 struct BinaryItemStreamObject {
591 explicit BinaryItemStreamObject(ArrayRef Bytes) : Bytes(Bytes) {}
592
593 ArrayRef Bytes;
594 };
595 }
596
597 namespace llvm {
598 template <> struct BinaryItemTraits {
599 static size_t length(const BinaryItemStreamObject &Item) {
600 return Item.Bytes.size();
601 }
602
603 static ArrayRef bytes(const BinaryItemStreamObject &Item) {
604 return Item.Bytes;
605 }
606 };
607 }
608
609 namespace {
610
611 TEST_F(BinaryStreamTest, BinaryItemStream) {
612 std::vector Objects;
613
614 struct Foo {
615 int X;
616 double Y;
617 };
618 std::vector Foos = {{1, 1.0}, {2, 2.0}, {3, 3.0}};
619 BumpPtrAllocator Allocator;
620 for (const auto &F : Foos) {
621 uint8_t *Ptr = Allocator.Allocate(sizeof(Foo));
622 MutableArrayRef Buffer(Ptr, sizeof(Foo));
623 MutableBinaryByteStream Stream(Buffer, llvm::support::big);
624 BinaryStreamWriter Writer(Stream);
625 ASSERT_NO_ERROR(Writer.writeObject(F));
626 Objects.push_back(BinaryItemStreamObject(Buffer));
627 }
628
629 BinaryItemStream ItemStream(big);
630 ItemStream.setItems(Objects);
631 BinaryStreamReader Reader(ItemStream);
632
633 for (const auto &F : Foos) {
634 const Foo *F2;
635 ASSERT_NO_ERROR(Reader.readObject(F2));
636
637 EXPECT_EQ(F.X, F2->X);
638 EXPECT_DOUBLE_EQ(F.Y, F2->Y);
639 }
640 }
641
642 } // end anonymous namespace
44 )
55
66 set(DebugInfoPDBSources
7 BinaryStreamTest.cpp
78 HashTableTest.cpp
89 MappedBlockStreamTest.cpp
910 StringTableBuilderTest.cpp