blob: 0762ef89fb1f3d8356bf73e10b460432e9975687 [file] [log] [blame]
Zachary Turner90b8b8d2016-05-31 22:41:52 +00001//===- llvm/unittest/DebugInfo/PDB/MappedBlockStreamTest.cpp --------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Zachary Turnerf52a8992016-07-15 20:43:38 +000010#include "ErrorChecking.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000011
Zachary Turnerbac69d32016-07-22 19:56:05 +000012#include "llvm/DebugInfo/Msf/ByteStream.h"
13#include "llvm/DebugInfo/Msf/IMsfFile.h"
14#include "llvm/DebugInfo/Msf/IMsfStreamData.h"
15#include "llvm/DebugInfo/Msf/IndexedStreamData.h"
16#include "llvm/DebugInfo/Msf/MappedBlockStream.h"
17#include "llvm/DebugInfo/Msf/StreamReader.h"
18#include "llvm/DebugInfo/Msf/StreamRef.h"
19#include "llvm/DebugInfo/Msf/StreamWriter.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000020#include "gtest/gtest.h"
21
Zachary Turnerf52a8992016-07-15 20:43:38 +000022#include <unordered_map>
23
Zachary Turner90b8b8d2016-05-31 22:41:52 +000024using namespace llvm;
Zachary Turnerbac69d32016-07-22 19:56:05 +000025using namespace llvm::msf;
Zachary Turner90b8b8d2016-05-31 22:41:52 +000026
27namespace {
28
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000029static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
Zachary Turner5acb4ac2016-06-10 05:09:12 +000030static uint8_t DataAry[] = {'A', 'B', 'C', 'F', 'E', 'D', 'G', 'H', 'I', 'J'};
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000031
Zachary Turnerbac69d32016-07-22 19:56:05 +000032class DiscontiguousFile : public IMsfFile {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000033public:
Zachary Turner5acb4ac2016-06-10 05:09:12 +000034 DiscontiguousFile(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
35 : Blocks(Blocks.begin(), Blocks.end()), Data(Data.begin(), Data.end()) {}
Zachary Turner90b8b8d2016-05-31 22:41:52 +000036
Zachary Turner5acb4ac2016-06-10 05:09:12 +000037 uint32_t getBlockSize() const override { return 1; }
38 uint32_t getBlockCount() const override { return Blocks.size(); }
39 uint32_t getNumStreams() const override { return 1; }
40 uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000041 return getBlockCount() * getBlockSize();
42 }
Zachary Turner5acb4ac2016-06-10 05:09:12 +000043 ArrayRef<support::ulittle32_t>
Zachary Turner90b8b8d2016-05-31 22:41:52 +000044 getStreamBlockList(uint32_t StreamIndex) const override {
45 if (StreamIndex != 0)
Zachary Turner92d9e972016-06-07 05:32:48 +000046 return ArrayRef<support::ulittle32_t>();
Zachary Turner90b8b8d2016-05-31 22:41:52 +000047 return Blocks;
48 }
David Majnemer6211b1f2016-07-10 03:34:47 +000049 Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
50 uint32_t NumBytes) const override {
Zachary Turnerc448d652016-06-07 20:46:39 +000051 return ArrayRef<uint8_t>(&Data[BlockIndex], NumBytes);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000052 }
53
Zachary Turner5acb4ac2016-06-10 05:09:12 +000054 Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
55 ArrayRef<uint8_t> SrcData) const override {
56 if (BlockIndex >= Blocks.size())
Zachary Turnerbac69d32016-07-22 19:56:05 +000057 return make_error<MsfError>(msf_error_code::insufficient_buffer);
Zachary Turner5acb4ac2016-06-10 05:09:12 +000058 if (Offset > getBlockSize() - SrcData.size())
Zachary Turnerbac69d32016-07-22 19:56:05 +000059 return make_error<MsfError>(msf_error_code::insufficient_buffer);
Zachary Turner5acb4ac2016-06-10 05:09:12 +000060 ::memcpy(&Data[BlockIndex] + Offset, SrcData.data(), SrcData.size());
61 return Error::success();
62 }
63
Zachary Turner90b8b8d2016-05-31 22:41:52 +000064private:
Zachary Turner92d9e972016-06-07 05:32:48 +000065 std::vector<support::ulittle32_t> Blocks;
Zachary Turner5acb4ac2016-06-10 05:09:12 +000066 MutableArrayRef<uint8_t> Data;
Zachary Turner90b8b8d2016-05-31 22:41:52 +000067};
68
Zachary Turner3e65bcb2016-06-08 17:32:25 +000069class MappedBlockStreamImpl : public MappedBlockStream {
70public:
Zachary Turnerbac69d32016-07-22 19:56:05 +000071 MappedBlockStreamImpl(std::unique_ptr<IMsfStreamData> Data,
72 const IMsfFile &File)
Zachary Turner3e65bcb2016-06-08 17:32:25 +000073 : MappedBlockStream(std::move(Data), File) {}
74};
75
Zachary Turner90b8b8d2016-05-31 22:41:52 +000076// Tests that a read which is entirely contained within a single block works
77// and does not allocate.
David Majnemerb6aa8752016-06-01 18:13:06 +000078TEST(MappedBlockStreamTest, ReadBeyondEndOfStreamRef) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000079 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +000080 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000081 StreamReader R(S);
David Majnemerb6aa8752016-06-01 18:13:06 +000082 StreamRef SR;
83 EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
84 ArrayRef<uint8_t> Buffer;
85 EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
David Majnemer8c79db12016-06-02 06:21:44 +000086 EXPECT_NO_ERROR(R.readStreamRef(SR, 1U));
87 EXPECT_ERROR(SR.readBytes(1U, 1U, Buffer));
Zachary Turner90b8b8d2016-05-31 22:41:52 +000088}
89
90// Tests that a read which outputs into a full destination buffer works and
91// does not fail due to the length of the output buffer.
92TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000093 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +000094 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000095 StreamReader R(S);
96 StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
97 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
98 EXPECT_EQ(Str, StringRef("A"));
David Majnemerc0113052016-06-01 18:13:02 +000099 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000100}
101
102// Tests that a read which crosses a block boundary, but where the subsequent
103// blocks are still contiguous in memory to the previous block works and does
104// not allocate memory.
105TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000106 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000107 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000108 StreamReader R(S);
109 StringRef Str;
110 EXPECT_NO_ERROR(R.readFixedString(Str, 2));
111 EXPECT_EQ(Str, StringRef("AB"));
David Majnemerc0113052016-06-01 18:13:02 +0000112 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000113
114 R.setOffset(6);
115 EXPECT_NO_ERROR(R.readFixedString(Str, 4));
116 EXPECT_EQ(Str, StringRef("GHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000117 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000118}
119
120// Tests that a read which crosses a block boundary and cannot be referenced
121// contiguously works and allocates only the precise amount of bytes
122// requested.
123TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000124 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000125 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000126 StreamReader R(S);
127 StringRef Str;
128 EXPECT_NO_ERROR(R.readFixedString(Str, 10));
129 EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000130 EXPECT_EQ(10U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000131}
132
133// Test that an out of bounds read which doesn't cross a block boundary
134// fails and allocates no memory.
135TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000136 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000137 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000138 StreamReader R(S);
139 StringRef Str;
140
141 R.setOffset(10);
142 EXPECT_ERROR(R.readFixedString(Str, 1));
David Majnemerc0113052016-06-01 18:13:02 +0000143 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000144}
145
146// Test that an out of bounds read which crosses a contiguous block boundary
147// fails and allocates no memory.
148TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000149 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000150 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000151 StreamReader R(S);
152 StringRef Str;
153
154 R.setOffset(6);
155 EXPECT_ERROR(R.readFixedString(Str, 5));
David Majnemerc0113052016-06-01 18:13:02 +0000156 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000157}
158
159// Test that an out of bounds read which crosses a discontiguous block
160// boundary fails and allocates no memory.
161TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000162 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000163 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000164 StreamReader R(S);
165 StringRef Str;
166
167 EXPECT_ERROR(R.readFixedString(Str, 11));
David Majnemerc0113052016-06-01 18:13:02 +0000168 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000169}
170
David Majnemerb6aa8752016-06-01 18:13:06 +0000171// Tests that a read which is entirely contained within a single block but
172// beyond the end of a StreamRef fails.
173TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000174 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000175 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
David Majnemerb6aa8752016-06-01 18:13:06 +0000176 StreamReader R(S);
177 StringRef Str;
178 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
179 EXPECT_EQ(Str, StringRef("A"));
180 EXPECT_EQ(0U, S.getNumBytesCopied());
181}
182
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000183// Tests that a read which is not aligned on the same boundary as a previous
184// cached request, but which is known to overlap that request, shares the
185// previous allocation.
186TEST(MappedBlockStreamTest, UnalignedOverlappingRead) {
187 DiscontiguousFile F(BlocksAry, DataAry);
188 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
189 StreamReader R(S);
190 StringRef Str1;
191 StringRef Str2;
192 EXPECT_NO_ERROR(R.readFixedString(Str1, 7));
193 EXPECT_EQ(Str1, StringRef("ABCDEFG"));
194 EXPECT_EQ(7U, S.getNumBytesCopied());
195
196 R.setOffset(2);
197 EXPECT_NO_ERROR(R.readFixedString(Str2, 3));
198 EXPECT_EQ(Str2, StringRef("CDE"));
199 EXPECT_EQ(Str1.data() + 2, Str2.data());
200 EXPECT_EQ(7U, S.getNumBytesCopied());
201}
202
203// Tests that a read which is not aligned on the same boundary as a previous
204// cached request, but which only partially overlaps a previous cached request,
205// still works correctly and allocates again from the shared pool.
206TEST(MappedBlockStreamTest, UnalignedOverlappingReadFail) {
207 DiscontiguousFile F(BlocksAry, DataAry);
208 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
209 StreamReader R(S);
210 StringRef Str1;
211 StringRef Str2;
212 EXPECT_NO_ERROR(R.readFixedString(Str1, 6));
213 EXPECT_EQ(Str1, StringRef("ABCDEF"));
214 EXPECT_EQ(6U, S.getNumBytesCopied());
215
216 R.setOffset(4);
217 EXPECT_NO_ERROR(R.readFixedString(Str2, 4));
218 EXPECT_EQ(Str2, StringRef("EFGH"));
219 EXPECT_EQ(10U, S.getNumBytesCopied());
220}
221
222TEST(MappedBlockStreamTest, WriteBeyondEndOfStream) {
223 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
224 static uint8_t LargeBuffer[] = {'0', '1', '2', '3', '4', '5',
225 '6', '7', '8', '9', 'A'};
226 static uint8_t SmallBuffer[] = {'0', '1', '2'};
227 static_assert(sizeof(LargeBuffer) > sizeof(Data),
228 "LargeBuffer is not big enough");
229
230 DiscontiguousFile F(BlocksAry, Data);
231 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
232 ArrayRef<uint8_t> Buffer;
233
234 EXPECT_ERROR(S.writeBytes(0, ArrayRef<uint8_t>(LargeBuffer)));
235 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>(SmallBuffer)));
236 EXPECT_NO_ERROR(S.writeBytes(7, ArrayRef<uint8_t>(SmallBuffer)));
237 EXPECT_ERROR(S.writeBytes(8, ArrayRef<uint8_t>(SmallBuffer)));
238}
239
240TEST(MappedBlockStreamTest, TestWriteBytesNoBreakBoundary) {
241 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
242 DiscontiguousFile F(BlocksAry, Data);
243 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
244 ArrayRef<uint8_t> Buffer;
245
246 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
247 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
248 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
249 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
250
251 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>('J')));
252 EXPECT_NO_ERROR(S.writeBytes(9, ArrayRef<uint8_t>('A')));
253
254 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
255 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
256 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
257 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
258
259 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>('A')));
260 EXPECT_NO_ERROR(S.writeBytes(9, ArrayRef<uint8_t>('J')));
261
262 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
263 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
264 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
265 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
266}
267
268TEST(MappedBlockStreamTest, TestWriteBytesBreakBoundary) {
269 static uint8_t Data[] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
270 static uint8_t TestData[] = {'T', 'E', 'S', 'T', 'I', 'N', 'G', '.'};
271 static uint8_t Expected[] = {'T', 'E', 'S', 'N', 'I',
272 'T', 'G', '.', '0', '0'};
273
274 DiscontiguousFile F(BlocksAry, Data);
275 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
276 ArrayRef<uint8_t> Buffer;
277
278 EXPECT_NO_ERROR(S.writeBytes(0, TestData));
279 // First just compare the memory, then compare the result of reading the
280 // string out.
281 EXPECT_EQ(ArrayRef<uint8_t>(Data), ArrayRef<uint8_t>(Expected));
282
283 EXPECT_NO_ERROR(S.readBytes(0, 8, Buffer));
284 EXPECT_EQ(Buffer, ArrayRef<uint8_t>(TestData));
285}
286
287TEST(MappedBlockStreamTest, TestWriteThenRead) {
288 std::vector<uint8_t> DataBytes(10);
289 MutableArrayRef<uint8_t> Data(DataBytes);
290 const uint32_t Blocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
291
292 DiscontiguousFile F(Blocks, Data);
293 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
294
295 enum class MyEnum : uint32_t { Val1 = 2908234, Val2 = 120891234 };
Zachary Turner97609bb2016-06-10 21:47:26 +0000296 using support::ulittle32_t;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000297
298 uint16_t u16[] = {31468, 0};
299 uint32_t u32[] = {890723408, 0};
300 MyEnum Enum[] = {MyEnum::Val1, MyEnum::Val2};
301 StringRef ZStr[] = {"Zero Str", ""};
302 StringRef FStr[] = {"Fixed Str", ""};
NAKAMURA Takumif1b183c2016-06-11 06:37:28 +0000303 uint8_t byteArray0[] = {'1', '2'};
304 uint8_t byteArray1[] = {'0', '0'};
Zachary Turner352cfe42016-07-08 16:57:14 +0000305 ArrayRef<uint8_t> byteArrayRef0(byteArray0);
306 ArrayRef<uint8_t> byteArrayRef1(byteArray1);
307 ArrayRef<uint8_t> byteArray[] = { byteArrayRef0, byteArrayRef1 };
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000308 ArrayRef<uint32_t> intArray[] = {{890723408, 29082234}, {0, 0}};
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000309
310 StreamReader Reader(S);
311 StreamWriter Writer(S);
312 EXPECT_NO_ERROR(Writer.writeInteger(u16[0]));
313 EXPECT_NO_ERROR(Reader.readInteger(u16[1]));
314 EXPECT_EQ(u16[0], u16[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000315 EXPECT_EQ(std::vector<uint8_t>({0, 0x7A, 0xEC, 0, 0, 0, 0, 0, 0, 0}),
316 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000317
318 Reader.setOffset(0);
319 Writer.setOffset(0);
320 ::memset(DataBytes.data(), 0, 10);
321 EXPECT_NO_ERROR(Writer.writeInteger(u32[0]));
322 EXPECT_NO_ERROR(Reader.readInteger(u32[1]));
323 EXPECT_EQ(u32[0], u32[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000324 EXPECT_EQ(std::vector<uint8_t>({0x17, 0x5C, 0x50, 0, 0, 0, 0x35, 0, 0, 0}),
325 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000326
327 Reader.setOffset(0);
328 Writer.setOffset(0);
329 ::memset(DataBytes.data(), 0, 10);
330 EXPECT_NO_ERROR(Writer.writeEnum(Enum[0]));
331 EXPECT_NO_ERROR(Reader.readEnum(Enum[1]));
332 EXPECT_EQ(Enum[0], Enum[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000333 EXPECT_EQ(std::vector<uint8_t>({0x2C, 0x60, 0x4A, 0, 0, 0, 0, 0, 0, 0}),
334 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000335
336 Reader.setOffset(0);
337 Writer.setOffset(0);
338 ::memset(DataBytes.data(), 0, 10);
339 EXPECT_NO_ERROR(Writer.writeZeroString(ZStr[0]));
340 EXPECT_NO_ERROR(Reader.readZeroString(ZStr[1]));
341 EXPECT_EQ(ZStr[0], ZStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000342 EXPECT_EQ(
343 std::vector<uint8_t>({'r', 'e', 'Z', ' ', 'S', 't', 'o', 'r', 0, 0}),
344 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000345
346 Reader.setOffset(0);
347 Writer.setOffset(0);
348 ::memset(DataBytes.data(), 0, 10);
349 EXPECT_NO_ERROR(Writer.writeFixedString(FStr[0]));
350 EXPECT_NO_ERROR(Reader.readFixedString(FStr[1], FStr[0].size()));
351 EXPECT_EQ(FStr[0], FStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000352 EXPECT_EQ(
353 std::vector<uint8_t>({'x', 'i', 'F', 'd', ' ', 'S', 'e', 't', 0, 'r'}),
354 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000355
356 Reader.setOffset(0);
357 Writer.setOffset(0);
358 ::memset(DataBytes.data(), 0, 10);
359 EXPECT_NO_ERROR(Writer.writeArray(byteArray[0]));
360 EXPECT_NO_ERROR(Reader.readArray(byteArray[1], byteArray[0].size()));
361 EXPECT_EQ(byteArray[0], byteArray[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000362 EXPECT_EQ(std::vector<uint8_t>({0, 0x32, 0x31, 0, 0, 0, 0, 0, 0, 0}),
363 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000364
365 Reader.setOffset(0);
366 Writer.setOffset(0);
367 ::memset(DataBytes.data(), 0, 10);
368 EXPECT_NO_ERROR(Writer.writeArray(intArray[0]));
369 EXPECT_NO_ERROR(Reader.readArray(intArray[1], intArray[0].size()));
370 EXPECT_EQ(intArray[0], intArray[1]);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000371}
372
373TEST(MappedBlockStreamTest, TestWriteContiguousStreamRef) {
374 std::vector<uint8_t> DestDataBytes(10);
375 MutableArrayRef<uint8_t> DestData(DestDataBytes);
376 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
377
378 std::vector<uint8_t> SrcDataBytes(10);
379 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
380
381 DiscontiguousFile F(DestBlocks, DestData);
382 MappedBlockStreamImpl DestStream(llvm::make_unique<IndexedStreamData>(0, F),
383 F);
384
385 // First write "Test Str" into the source stream.
386 ByteStream<true> SourceStream(SrcData);
387 StreamWriter SourceWriter(SourceStream);
388 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
389 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
390 {'T', 'e', 's', 't', ' ', 'S', 't', 'r', 0, 0}));
391
392 // Then write the source stream into the dest stream.
393 StreamWriter DestWriter(DestStream);
394 EXPECT_NO_ERROR(DestWriter.writeStreamRef(SourceStream));
395 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
396 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
397
398 // Then read the string back out of the dest stream.
399 StringRef Result;
400 StreamReader DestReader(DestStream);
401 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
402 EXPECT_EQ(Result, "Test Str");
403}
404
405TEST(MappedBlockStreamTest, TestWriteDiscontiguousStreamRef) {
406 std::vector<uint8_t> DestDataBytes(10);
407 MutableArrayRef<uint8_t> DestData(DestDataBytes);
408 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
409
410 std::vector<uint8_t> SrcDataBytes(10);
411 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
412 const uint32_t SrcBlocks[] = {1, 0, 6, 3, 4, 5, 2, 7, 8, 9};
413
414 DiscontiguousFile DestFile(DestBlocks, DestData);
415 DiscontiguousFile SrcFile(SrcBlocks, SrcData);
416
417 MappedBlockStreamImpl DestStream(
418 llvm::make_unique<IndexedStreamData>(0, DestFile), DestFile);
419 MappedBlockStreamImpl SrcStream(
420 llvm::make_unique<IndexedStreamData>(0, SrcFile), SrcFile);
421
422 // First write "Test Str" into the source stream.
423 StreamWriter SourceWriter(SrcStream);
424 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
425 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
426 {'e', 'T', 't', 't', ' ', 'S', 's', 'r', 0, 0}));
427
428 // Then write the source stream into the dest stream.
429 StreamWriter DestWriter(DestStream);
430 EXPECT_NO_ERROR(DestWriter.writeStreamRef(SrcStream));
431 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
432 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
433
434 // Then read the string back out of the dest stream.
435 StringRef Result;
436 StreamReader DestReader(DestStream);
437 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
438 EXPECT_EQ(Result, "Test Str");
439}
440
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000441} // end anonymous namespace