blob: 6f9e86c4f262069aa1ae73db3078fbc9d13c2514 [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 Turner5acb4ac2016-06-10 05:09:12 +000012#include "llvm/DebugInfo/CodeView/ByteStream.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000013#include "llvm/DebugInfo/CodeView/StreamReader.h"
14#include "llvm/DebugInfo/CodeView/StreamRef.h"
Zachary Turner5acb4ac2016-06-10 05:09:12 +000015#include "llvm/DebugInfo/CodeView/StreamWriter.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000016#include "llvm/DebugInfo/PDB/Raw/IPDBFile.h"
Zachary Turner92d9e972016-06-07 05:32:48 +000017#include "llvm/DebugInfo/PDB/Raw/IPDBStreamData.h"
18#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000019#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
20#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;
25using namespace llvm::codeview;
26using namespace llvm::pdb;
27
28namespace {
29
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000030static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
Zachary Turner5acb4ac2016-06-10 05:09:12 +000031static uint8_t DataAry[] = {'A', 'B', 'C', 'F', 'E', 'D', 'G', 'H', 'I', 'J'};
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000032
Zachary Turner90b8b8d2016-05-31 22:41:52 +000033class DiscontiguousFile : public IPDBFile {
34public:
Zachary Turner5acb4ac2016-06-10 05:09:12 +000035 DiscontiguousFile(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
36 : Blocks(Blocks.begin(), Blocks.end()), Data(Data.begin(), Data.end()) {}
Zachary Turner90b8b8d2016-05-31 22:41:52 +000037
Zachary Turner5acb4ac2016-06-10 05:09:12 +000038 uint32_t getBlockSize() const override { return 1; }
39 uint32_t getBlockCount() const override { return Blocks.size(); }
40 uint32_t getNumStreams() const override { return 1; }
41 uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000042 return getBlockCount() * getBlockSize();
43 }
Zachary Turner5acb4ac2016-06-10 05:09:12 +000044 ArrayRef<support::ulittle32_t>
Zachary Turner90b8b8d2016-05-31 22:41:52 +000045 getStreamBlockList(uint32_t StreamIndex) const override {
46 if (StreamIndex != 0)
Zachary Turner92d9e972016-06-07 05:32:48 +000047 return ArrayRef<support::ulittle32_t>();
Zachary Turner90b8b8d2016-05-31 22:41:52 +000048 return Blocks;
49 }
David Majnemer6211b1f2016-07-10 03:34:47 +000050 Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
51 uint32_t NumBytes) const override {
Zachary Turnerc448d652016-06-07 20:46:39 +000052 return ArrayRef<uint8_t>(&Data[BlockIndex], NumBytes);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000053 }
54
Zachary Turner5acb4ac2016-06-10 05:09:12 +000055 Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
56 ArrayRef<uint8_t> SrcData) const override {
57 if (BlockIndex >= Blocks.size())
58 return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
59 if (Offset > getBlockSize() - SrcData.size())
60 return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
61 ::memcpy(&Data[BlockIndex] + Offset, SrcData.data(), SrcData.size());
62 return Error::success();
63 }
64
Zachary Turner90b8b8d2016-05-31 22:41:52 +000065private:
Zachary Turner92d9e972016-06-07 05:32:48 +000066 std::vector<support::ulittle32_t> Blocks;
Zachary Turner5acb4ac2016-06-10 05:09:12 +000067 MutableArrayRef<uint8_t> Data;
Zachary Turner90b8b8d2016-05-31 22:41:52 +000068};
69
Zachary Turner3e65bcb2016-06-08 17:32:25 +000070class MappedBlockStreamImpl : public MappedBlockStream {
71public:
72 MappedBlockStreamImpl(std::unique_ptr<IPDBStreamData> Data,
73 const IPDBFile &File)
74 : MappedBlockStream(std::move(Data), File) {}
75};
76
Zachary Turner90b8b8d2016-05-31 22:41:52 +000077// Tests that a read which is entirely contained within a single block works
78// and does not allocate.
David Majnemerb6aa8752016-06-01 18:13:06 +000079TEST(MappedBlockStreamTest, ReadBeyondEndOfStreamRef) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000080 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +000081 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000082 StreamReader R(S);
David Majnemerb6aa8752016-06-01 18:13:06 +000083 StreamRef SR;
84 EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
85 ArrayRef<uint8_t> Buffer;
86 EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
David Majnemer8c79db12016-06-02 06:21:44 +000087 EXPECT_NO_ERROR(R.readStreamRef(SR, 1U));
88 EXPECT_ERROR(SR.readBytes(1U, 1U, Buffer));
Zachary Turner90b8b8d2016-05-31 22:41:52 +000089}
90
91// Tests that a read which outputs into a full destination buffer works and
92// does not fail due to the length of the output buffer.
93TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000094 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +000095 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000096 StreamReader R(S);
97 StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
98 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
99 EXPECT_EQ(Str, StringRef("A"));
David Majnemerc0113052016-06-01 18:13:02 +0000100 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000101}
102
103// Tests that a read which crosses a block boundary, but where the subsequent
104// blocks are still contiguous in memory to the previous block works and does
105// not allocate memory.
106TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000107 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000108 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000109 StreamReader R(S);
110 StringRef Str;
111 EXPECT_NO_ERROR(R.readFixedString(Str, 2));
112 EXPECT_EQ(Str, StringRef("AB"));
David Majnemerc0113052016-06-01 18:13:02 +0000113 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000114
115 R.setOffset(6);
116 EXPECT_NO_ERROR(R.readFixedString(Str, 4));
117 EXPECT_EQ(Str, StringRef("GHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000118 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000119}
120
121// Tests that a read which crosses a block boundary and cannot be referenced
122// contiguously works and allocates only the precise amount of bytes
123// requested.
124TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000125 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000126 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000127 StreamReader R(S);
128 StringRef Str;
129 EXPECT_NO_ERROR(R.readFixedString(Str, 10));
130 EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
David Majnemerc0113052016-06-01 18:13:02 +0000131 EXPECT_EQ(10U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000132}
133
134// Test that an out of bounds read which doesn't cross a block boundary
135// fails and allocates no memory.
136TEST(MappedBlockStreamTest, InvalidReadSizeNoBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000137 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000138 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000139 StreamReader R(S);
140 StringRef Str;
141
142 R.setOffset(10);
143 EXPECT_ERROR(R.readFixedString(Str, 1));
David Majnemerc0113052016-06-01 18:13:02 +0000144 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000145}
146
147// Test that an out of bounds read which crosses a contiguous block boundary
148// fails and allocates no memory.
149TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000150 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000151 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000152 StreamReader R(S);
153 StringRef Str;
154
155 R.setOffset(6);
156 EXPECT_ERROR(R.readFixedString(Str, 5));
David Majnemerc0113052016-06-01 18:13:02 +0000157 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000158}
159
160// Test that an out of bounds read which crosses a discontiguous block
161// boundary fails and allocates no memory.
162TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000163 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000164 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000165 StreamReader R(S);
166 StringRef Str;
167
168 EXPECT_ERROR(R.readFixedString(Str, 11));
David Majnemerc0113052016-06-01 18:13:02 +0000169 EXPECT_EQ(0U, S.getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000170}
171
David Majnemerb6aa8752016-06-01 18:13:06 +0000172// Tests that a read which is entirely contained within a single block but
173// beyond the end of a StreamRef fails.
174TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000175 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner3e65bcb2016-06-08 17:32:25 +0000176 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
David Majnemerb6aa8752016-06-01 18:13:06 +0000177 StreamReader R(S);
178 StringRef Str;
179 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
180 EXPECT_EQ(Str, StringRef("A"));
181 EXPECT_EQ(0U, S.getNumBytesCopied());
182}
183
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000184// Tests that a read which is not aligned on the same boundary as a previous
185// cached request, but which is known to overlap that request, shares the
186// previous allocation.
187TEST(MappedBlockStreamTest, UnalignedOverlappingRead) {
188 DiscontiguousFile F(BlocksAry, DataAry);
189 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
190 StreamReader R(S);
191 StringRef Str1;
192 StringRef Str2;
193 EXPECT_NO_ERROR(R.readFixedString(Str1, 7));
194 EXPECT_EQ(Str1, StringRef("ABCDEFG"));
195 EXPECT_EQ(7U, S.getNumBytesCopied());
196
197 R.setOffset(2);
198 EXPECT_NO_ERROR(R.readFixedString(Str2, 3));
199 EXPECT_EQ(Str2, StringRef("CDE"));
200 EXPECT_EQ(Str1.data() + 2, Str2.data());
201 EXPECT_EQ(7U, S.getNumBytesCopied());
202}
203
204// Tests that a read which is not aligned on the same boundary as a previous
205// cached request, but which only partially overlaps a previous cached request,
206// still works correctly and allocates again from the shared pool.
207TEST(MappedBlockStreamTest, UnalignedOverlappingReadFail) {
208 DiscontiguousFile F(BlocksAry, DataAry);
209 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
210 StreamReader R(S);
211 StringRef Str1;
212 StringRef Str2;
213 EXPECT_NO_ERROR(R.readFixedString(Str1, 6));
214 EXPECT_EQ(Str1, StringRef("ABCDEF"));
215 EXPECT_EQ(6U, S.getNumBytesCopied());
216
217 R.setOffset(4);
218 EXPECT_NO_ERROR(R.readFixedString(Str2, 4));
219 EXPECT_EQ(Str2, StringRef("EFGH"));
220 EXPECT_EQ(10U, S.getNumBytesCopied());
221}
222
223TEST(MappedBlockStreamTest, WriteBeyondEndOfStream) {
224 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
225 static uint8_t LargeBuffer[] = {'0', '1', '2', '3', '4', '5',
226 '6', '7', '8', '9', 'A'};
227 static uint8_t SmallBuffer[] = {'0', '1', '2'};
228 static_assert(sizeof(LargeBuffer) > sizeof(Data),
229 "LargeBuffer is not big enough");
230
231 DiscontiguousFile F(BlocksAry, Data);
232 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
233 ArrayRef<uint8_t> Buffer;
234
235 EXPECT_ERROR(S.writeBytes(0, ArrayRef<uint8_t>(LargeBuffer)));
236 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>(SmallBuffer)));
237 EXPECT_NO_ERROR(S.writeBytes(7, ArrayRef<uint8_t>(SmallBuffer)));
238 EXPECT_ERROR(S.writeBytes(8, ArrayRef<uint8_t>(SmallBuffer)));
239}
240
241TEST(MappedBlockStreamTest, TestWriteBytesNoBreakBoundary) {
242 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
243 DiscontiguousFile F(BlocksAry, Data);
244 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
245 ArrayRef<uint8_t> Buffer;
246
247 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
248 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
249 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
250 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
251
252 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>('J')));
253 EXPECT_NO_ERROR(S.writeBytes(9, ArrayRef<uint8_t>('A')));
254
255 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
256 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
257 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
258 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
259
260 EXPECT_NO_ERROR(S.writeBytes(0, ArrayRef<uint8_t>('A')));
261 EXPECT_NO_ERROR(S.writeBytes(9, ArrayRef<uint8_t>('J')));
262
263 EXPECT_NO_ERROR(S.readBytes(0, 1, Buffer));
264 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
265 EXPECT_NO_ERROR(S.readBytes(9, 1, Buffer));
266 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
267}
268
269TEST(MappedBlockStreamTest, TestWriteBytesBreakBoundary) {
270 static uint8_t Data[] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
271 static uint8_t TestData[] = {'T', 'E', 'S', 'T', 'I', 'N', 'G', '.'};
272 static uint8_t Expected[] = {'T', 'E', 'S', 'N', 'I',
273 'T', 'G', '.', '0', '0'};
274
275 DiscontiguousFile F(BlocksAry, Data);
276 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
277 ArrayRef<uint8_t> Buffer;
278
279 EXPECT_NO_ERROR(S.writeBytes(0, TestData));
280 // First just compare the memory, then compare the result of reading the
281 // string out.
282 EXPECT_EQ(ArrayRef<uint8_t>(Data), ArrayRef<uint8_t>(Expected));
283
284 EXPECT_NO_ERROR(S.readBytes(0, 8, Buffer));
285 EXPECT_EQ(Buffer, ArrayRef<uint8_t>(TestData));
286}
287
288TEST(MappedBlockStreamTest, TestWriteThenRead) {
289 std::vector<uint8_t> DataBytes(10);
290 MutableArrayRef<uint8_t> Data(DataBytes);
291 const uint32_t Blocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
292
293 DiscontiguousFile F(Blocks, Data);
294 MappedBlockStreamImpl S(llvm::make_unique<IndexedStreamData>(0, F), F);
295
296 enum class MyEnum : uint32_t { Val1 = 2908234, Val2 = 120891234 };
Zachary Turner97609bb2016-06-10 21:47:26 +0000297 using support::ulittle32_t;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000298
299 uint16_t u16[] = {31468, 0};
300 uint32_t u32[] = {890723408, 0};
301 MyEnum Enum[] = {MyEnum::Val1, MyEnum::Val2};
302 StringRef ZStr[] = {"Zero Str", ""};
303 StringRef FStr[] = {"Fixed Str", ""};
NAKAMURA Takumif1b183c2016-06-11 06:37:28 +0000304 uint8_t byteArray0[] = {'1', '2'};
305 uint8_t byteArray1[] = {'0', '0'};
Zachary Turner352cfe42016-07-08 16:57:14 +0000306 ArrayRef<uint8_t> byteArrayRef0(byteArray0);
307 ArrayRef<uint8_t> byteArrayRef1(byteArray1);
308 ArrayRef<uint8_t> byteArray[] = { byteArrayRef0, byteArrayRef1 };
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000309 ArrayRef<uint32_t> intArray[] = {{890723408, 29082234}, {0, 0}};
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000310
311 StreamReader Reader(S);
312 StreamWriter Writer(S);
313 EXPECT_NO_ERROR(Writer.writeInteger(u16[0]));
314 EXPECT_NO_ERROR(Reader.readInteger(u16[1]));
315 EXPECT_EQ(u16[0], u16[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000316 EXPECT_EQ(std::vector<uint8_t>({0, 0x7A, 0xEC, 0, 0, 0, 0, 0, 0, 0}),
317 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000318
319 Reader.setOffset(0);
320 Writer.setOffset(0);
321 ::memset(DataBytes.data(), 0, 10);
322 EXPECT_NO_ERROR(Writer.writeInteger(u32[0]));
323 EXPECT_NO_ERROR(Reader.readInteger(u32[1]));
324 EXPECT_EQ(u32[0], u32[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000325 EXPECT_EQ(std::vector<uint8_t>({0x17, 0x5C, 0x50, 0, 0, 0, 0x35, 0, 0, 0}),
326 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000327
328 Reader.setOffset(0);
329 Writer.setOffset(0);
330 ::memset(DataBytes.data(), 0, 10);
331 EXPECT_NO_ERROR(Writer.writeEnum(Enum[0]));
332 EXPECT_NO_ERROR(Reader.readEnum(Enum[1]));
333 EXPECT_EQ(Enum[0], Enum[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000334 EXPECT_EQ(std::vector<uint8_t>({0x2C, 0x60, 0x4A, 0, 0, 0, 0, 0, 0, 0}),
335 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000336
337 Reader.setOffset(0);
338 Writer.setOffset(0);
339 ::memset(DataBytes.data(), 0, 10);
340 EXPECT_NO_ERROR(Writer.writeZeroString(ZStr[0]));
341 EXPECT_NO_ERROR(Reader.readZeroString(ZStr[1]));
342 EXPECT_EQ(ZStr[0], ZStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000343 EXPECT_EQ(
344 std::vector<uint8_t>({'r', 'e', 'Z', ' ', 'S', 't', 'o', 'r', 0, 0}),
345 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000346
347 Reader.setOffset(0);
348 Writer.setOffset(0);
349 ::memset(DataBytes.data(), 0, 10);
350 EXPECT_NO_ERROR(Writer.writeFixedString(FStr[0]));
351 EXPECT_NO_ERROR(Reader.readFixedString(FStr[1], FStr[0].size()));
352 EXPECT_EQ(FStr[0], FStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000353 EXPECT_EQ(
354 std::vector<uint8_t>({'x', 'i', 'F', 'd', ' ', 'S', 'e', 't', 0, 'r'}),
355 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000356
357 Reader.setOffset(0);
358 Writer.setOffset(0);
359 ::memset(DataBytes.data(), 0, 10);
360 EXPECT_NO_ERROR(Writer.writeArray(byteArray[0]));
361 EXPECT_NO_ERROR(Reader.readArray(byteArray[1], byteArray[0].size()));
362 EXPECT_EQ(byteArray[0], byteArray[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000363 EXPECT_EQ(std::vector<uint8_t>({0, 0x32, 0x31, 0, 0, 0, 0, 0, 0, 0}),
364 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000365
366 Reader.setOffset(0);
367 Writer.setOffset(0);
368 ::memset(DataBytes.data(), 0, 10);
369 EXPECT_NO_ERROR(Writer.writeArray(intArray[0]));
370 EXPECT_NO_ERROR(Reader.readArray(intArray[1], intArray[0].size()));
371 EXPECT_EQ(intArray[0], intArray[1]);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000372}
373
374TEST(MappedBlockStreamTest, TestWriteContiguousStreamRef) {
375 std::vector<uint8_t> DestDataBytes(10);
376 MutableArrayRef<uint8_t> DestData(DestDataBytes);
377 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
378
379 std::vector<uint8_t> SrcDataBytes(10);
380 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
381
382 DiscontiguousFile F(DestBlocks, DestData);
383 MappedBlockStreamImpl DestStream(llvm::make_unique<IndexedStreamData>(0, F),
384 F);
385
386 // First write "Test Str" into the source stream.
387 ByteStream<true> SourceStream(SrcData);
388 StreamWriter SourceWriter(SourceStream);
389 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
390 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
391 {'T', 'e', 's', 't', ' ', 'S', 't', 'r', 0, 0}));
392
393 // Then write the source stream into the dest stream.
394 StreamWriter DestWriter(DestStream);
395 EXPECT_NO_ERROR(DestWriter.writeStreamRef(SourceStream));
396 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
397 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
398
399 // Then read the string back out of the dest stream.
400 StringRef Result;
401 StreamReader DestReader(DestStream);
402 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
403 EXPECT_EQ(Result, "Test Str");
404}
405
406TEST(MappedBlockStreamTest, TestWriteDiscontiguousStreamRef) {
407 std::vector<uint8_t> DestDataBytes(10);
408 MutableArrayRef<uint8_t> DestData(DestDataBytes);
409 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
410
411 std::vector<uint8_t> SrcDataBytes(10);
412 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
413 const uint32_t SrcBlocks[] = {1, 0, 6, 3, 4, 5, 2, 7, 8, 9};
414
415 DiscontiguousFile DestFile(DestBlocks, DestData);
416 DiscontiguousFile SrcFile(SrcBlocks, SrcData);
417
418 MappedBlockStreamImpl DestStream(
419 llvm::make_unique<IndexedStreamData>(0, DestFile), DestFile);
420 MappedBlockStreamImpl SrcStream(
421 llvm::make_unique<IndexedStreamData>(0, SrcFile), SrcFile);
422
423 // First write "Test Str" into the source stream.
424 StreamWriter SourceWriter(SrcStream);
425 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
426 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
427 {'e', 'T', 't', 't', ' ', 'S', 's', 'r', 0, 0}));
428
429 // Then write the source stream into the dest stream.
430 StreamWriter DestWriter(DestStream);
431 EXPECT_NO_ERROR(DestWriter.writeStreamRef(SrcStream));
432 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
433 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
434
435 // Then read the string back out of the dest stream.
436 StringRef Result;
437 StreamReader DestReader(DestStream);
438 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
439 EXPECT_EQ(Result, "Test Str");
440}
441
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000442} // end anonymous namespace