blob: f1bf031e019060990a9911eb47c02fb48e7e8009 [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"
Zachary Turnerbac69d32016-07-22 19:56:05 +000014#include "llvm/DebugInfo/Msf/MappedBlockStream.h"
Zachary Turner199f48a2016-07-28 19:11:09 +000015#include "llvm/DebugInfo/Msf/MsfStreamLayout.h"
Zachary Turnerbac69d32016-07-22 19:56:05 +000016#include "llvm/DebugInfo/Msf/StreamReader.h"
17#include "llvm/DebugInfo/Msf/StreamRef.h"
18#include "llvm/DebugInfo/Msf/StreamWriter.h"
Zachary Turner90b8b8d2016-05-31 22:41:52 +000019#include "gtest/gtest.h"
20
Zachary Turnerf52a8992016-07-15 20:43:38 +000021#include <unordered_map>
22
Zachary Turner90b8b8d2016-05-31 22:41:52 +000023using namespace llvm;
Zachary Turnerbac69d32016-07-22 19:56:05 +000024using namespace llvm::msf;
Zachary Turner90b8b8d2016-05-31 22:41:52 +000025
26namespace {
27
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000028static const uint32_t BlocksAry[] = {0, 1, 2, 5, 4, 3, 6, 7, 8, 9};
Zachary Turner5acb4ac2016-06-10 05:09:12 +000029static uint8_t DataAry[] = {'A', 'B', 'C', 'F', 'E', 'D', 'G', 'H', 'I', 'J'};
NAKAMURA Takumi47d1e372016-06-01 14:26:54 +000030
Zachary Turnerbac69d32016-07-22 19:56:05 +000031class DiscontiguousFile : public IMsfFile {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000032public:
Zachary Turner5acb4ac2016-06-10 05:09:12 +000033 DiscontiguousFile(ArrayRef<uint32_t> Blocks, MutableArrayRef<uint8_t> Data)
34 : Blocks(Blocks.begin(), Blocks.end()), Data(Data.begin(), Data.end()) {}
Zachary Turner90b8b8d2016-05-31 22:41:52 +000035
Zachary Turner5acb4ac2016-06-10 05:09:12 +000036 uint32_t getBlockSize() const override { return 1; }
37 uint32_t getBlockCount() const override { return Blocks.size(); }
38 uint32_t getNumStreams() const override { return 1; }
39 uint32_t getStreamByteSize(uint32_t StreamIndex) const override {
Zachary Turner90b8b8d2016-05-31 22:41:52 +000040 return getBlockCount() * getBlockSize();
41 }
Zachary Turner5acb4ac2016-06-10 05:09:12 +000042 ArrayRef<support::ulittle32_t>
Zachary Turner90b8b8d2016-05-31 22:41:52 +000043 getStreamBlockList(uint32_t StreamIndex) const override {
44 if (StreamIndex != 0)
Zachary Turner92d9e972016-06-07 05:32:48 +000045 return ArrayRef<support::ulittle32_t>();
Zachary Turner90b8b8d2016-05-31 22:41:52 +000046 return Blocks;
47 }
David Majnemer6211b1f2016-07-10 03:34:47 +000048 Expected<ArrayRef<uint8_t>> getBlockData(uint32_t BlockIndex,
49 uint32_t NumBytes) const override {
Zachary Turnerc448d652016-06-07 20:46:39 +000050 return ArrayRef<uint8_t>(&Data[BlockIndex], NumBytes);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000051 }
52
Zachary Turner5acb4ac2016-06-10 05:09:12 +000053 Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
54 ArrayRef<uint8_t> SrcData) const override {
55 if (BlockIndex >= Blocks.size())
Zachary Turnerbac69d32016-07-22 19:56:05 +000056 return make_error<MsfError>(msf_error_code::insufficient_buffer);
Zachary Turner5acb4ac2016-06-10 05:09:12 +000057 if (Offset > getBlockSize() - SrcData.size())
Zachary Turnerbac69d32016-07-22 19:56:05 +000058 return make_error<MsfError>(msf_error_code::insufficient_buffer);
Zachary Turner5acb4ac2016-06-10 05:09:12 +000059 ::memcpy(&Data[BlockIndex] + Offset, SrcData.data(), SrcData.size());
60 return Error::success();
61 }
62
Zachary Turner90b8b8d2016-05-31 22:41:52 +000063private:
Zachary Turner92d9e972016-06-07 05:32:48 +000064 std::vector<support::ulittle32_t> Blocks;
Zachary Turner5acb4ac2016-06-10 05:09:12 +000065 MutableArrayRef<uint8_t> Data;
Zachary Turner90b8b8d2016-05-31 22:41:52 +000066};
67
68// Tests that a read which is entirely contained within a single block works
69// and does not allocate.
David Majnemerb6aa8752016-06-01 18:13:06 +000070TEST(MappedBlockStreamTest, ReadBeyondEndOfStreamRef) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000071 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +000072 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
73 EXPECT_EXPECTED(ExpectedS);
74 auto &S = *ExpectedS;
75
76 StreamReader R(*S);
David Majnemerb6aa8752016-06-01 18:13:06 +000077 StreamRef SR;
78 EXPECT_NO_ERROR(R.readStreamRef(SR, 0U));
79 ArrayRef<uint8_t> Buffer;
80 EXPECT_ERROR(SR.readBytes(0U, 1U, Buffer));
David Majnemer8c79db12016-06-02 06:21:44 +000081 EXPECT_NO_ERROR(R.readStreamRef(SR, 1U));
82 EXPECT_ERROR(SR.readBytes(1U, 1U, Buffer));
Zachary Turner90b8b8d2016-05-31 22:41:52 +000083}
84
85// Tests that a read which outputs into a full destination buffer works and
86// does not fail due to the length of the output buffer.
87TEST(MappedBlockStreamTest, ReadOntoNonEmptyBuffer) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +000088 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +000089 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
90 EXPECT_EXPECTED(ExpectedS);
91 auto &S = *ExpectedS;
92 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +000093 StringRef Str = "ZYXWVUTSRQPONMLKJIHGFEDCBA";
94 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
95 EXPECT_EQ(Str, StringRef("A"));
Zachary Turner199f48a2016-07-28 19:11:09 +000096 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +000097}
98
99// Tests that a read which crosses a block boundary, but where the subsequent
100// blocks are still contiguous in memory to the previous block works and does
101// not allocate memory.
102TEST(MappedBlockStreamTest, ZeroCopyReadContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000103 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000104 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
105 EXPECT_EXPECTED(ExpectedS);
106 auto &S = *ExpectedS;
107 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000108 StringRef Str;
109 EXPECT_NO_ERROR(R.readFixedString(Str, 2));
110 EXPECT_EQ(Str, StringRef("AB"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000111 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000112
113 R.setOffset(6);
114 EXPECT_NO_ERROR(R.readFixedString(Str, 4));
115 EXPECT_EQ(Str, StringRef("GHIJ"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000116 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000117}
118
119// Tests that a read which crosses a block boundary and cannot be referenced
120// contiguously works and allocates only the precise amount of bytes
121// requested.
122TEST(MappedBlockStreamTest, CopyReadNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000123 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000124 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
125 EXPECT_EXPECTED(ExpectedS);
126 auto &S = *ExpectedS;
127 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000128 StringRef Str;
129 EXPECT_NO_ERROR(R.readFixedString(Str, 10));
130 EXPECT_EQ(Str, StringRef("ABCDEFGHIJ"));
Zachary Turner199f48a2016-07-28 19:11:09 +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 Turner199f48a2016-07-28 19:11:09 +0000138 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
139 EXPECT_EXPECTED(ExpectedS);
140 auto &S = *ExpectedS;
141 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000142 StringRef Str;
143
144 R.setOffset(10);
145 EXPECT_ERROR(R.readFixedString(Str, 1));
Zachary Turner199f48a2016-07-28 19:11:09 +0000146 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000147}
148
149// Test that an out of bounds read which crosses a contiguous block boundary
150// fails and allocates no memory.
151TEST(MappedBlockStreamTest, InvalidReadSizeContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000152 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000153 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
154 EXPECT_EXPECTED(ExpectedS);
155 auto &S = *ExpectedS;
156 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000157 StringRef Str;
158
159 R.setOffset(6);
160 EXPECT_ERROR(R.readFixedString(Str, 5));
Zachary Turner199f48a2016-07-28 19:11:09 +0000161 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000162}
163
164// Test that an out of bounds read which crosses a discontiguous block
165// boundary fails and allocates no memory.
166TEST(MappedBlockStreamTest, InvalidReadSizeNonContiguousBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000167 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000168 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
169 EXPECT_EXPECTED(ExpectedS);
170 auto &S = *ExpectedS;
171 StreamReader R(*S);
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000172 StringRef Str;
173
174 EXPECT_ERROR(R.readFixedString(Str, 11));
Zachary Turner199f48a2016-07-28 19:11:09 +0000175 EXPECT_EQ(0U, S->getNumBytesCopied());
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000176}
177
David Majnemerb6aa8752016-06-01 18:13:06 +0000178// Tests that a read which is entirely contained within a single block but
179// beyond the end of a StreamRef fails.
180TEST(MappedBlockStreamTest, ZeroCopyReadNoBreak) {
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000181 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000182 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
183 EXPECT_EXPECTED(ExpectedS);
184 auto &S = *ExpectedS;
185 StreamReader R(*S);
David Majnemerb6aa8752016-06-01 18:13:06 +0000186 StringRef Str;
187 EXPECT_NO_ERROR(R.readFixedString(Str, 1));
188 EXPECT_EQ(Str, StringRef("A"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000189 EXPECT_EQ(0U, S->getNumBytesCopied());
David Majnemerb6aa8752016-06-01 18:13:06 +0000190}
191
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000192// Tests that a read which is not aligned on the same boundary as a previous
193// cached request, but which is known to overlap that request, shares the
194// previous allocation.
195TEST(MappedBlockStreamTest, UnalignedOverlappingRead) {
196 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000197 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
198 EXPECT_EXPECTED(ExpectedS);
199 auto &S = *ExpectedS;
200 StreamReader R(*S);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000201 StringRef Str1;
202 StringRef Str2;
203 EXPECT_NO_ERROR(R.readFixedString(Str1, 7));
204 EXPECT_EQ(Str1, StringRef("ABCDEFG"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000205 EXPECT_EQ(7U, S->getNumBytesCopied());
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000206
207 R.setOffset(2);
208 EXPECT_NO_ERROR(R.readFixedString(Str2, 3));
209 EXPECT_EQ(Str2, StringRef("CDE"));
210 EXPECT_EQ(Str1.data() + 2, Str2.data());
Zachary Turner199f48a2016-07-28 19:11:09 +0000211 EXPECT_EQ(7U, S->getNumBytesCopied());
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000212}
213
214// Tests that a read which is not aligned on the same boundary as a previous
215// cached request, but which only partially overlaps a previous cached request,
216// still works correctly and allocates again from the shared pool.
217TEST(MappedBlockStreamTest, UnalignedOverlappingReadFail) {
218 DiscontiguousFile F(BlocksAry, DataAry);
Zachary Turner199f48a2016-07-28 19:11:09 +0000219 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
220 EXPECT_EXPECTED(ExpectedS);
221 auto &S = *ExpectedS;
222 StreamReader R(*S);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000223 StringRef Str1;
224 StringRef Str2;
225 EXPECT_NO_ERROR(R.readFixedString(Str1, 6));
226 EXPECT_EQ(Str1, StringRef("ABCDEF"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000227 EXPECT_EQ(6U, S->getNumBytesCopied());
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000228
229 R.setOffset(4);
230 EXPECT_NO_ERROR(R.readFixedString(Str2, 4));
231 EXPECT_EQ(Str2, StringRef("EFGH"));
Zachary Turner199f48a2016-07-28 19:11:09 +0000232 EXPECT_EQ(10U, S->getNumBytesCopied());
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000233}
234
235TEST(MappedBlockStreamTest, WriteBeyondEndOfStream) {
236 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
237 static uint8_t LargeBuffer[] = {'0', '1', '2', '3', '4', '5',
238 '6', '7', '8', '9', 'A'};
239 static uint8_t SmallBuffer[] = {'0', '1', '2'};
240 static_assert(sizeof(LargeBuffer) > sizeof(Data),
241 "LargeBuffer is not big enough");
242
243 DiscontiguousFile F(BlocksAry, Data);
Zachary Turner199f48a2016-07-28 19:11:09 +0000244 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
245 EXPECT_EXPECTED(ExpectedS);
246 auto &S = *ExpectedS;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000247 ArrayRef<uint8_t> Buffer;
248
Zachary Turner199f48a2016-07-28 19:11:09 +0000249 EXPECT_ERROR(S->writeBytes(0, ArrayRef<uint8_t>(LargeBuffer)));
250 EXPECT_NO_ERROR(S->writeBytes(0, ArrayRef<uint8_t>(SmallBuffer)));
251 EXPECT_NO_ERROR(S->writeBytes(7, ArrayRef<uint8_t>(SmallBuffer)));
252 EXPECT_ERROR(S->writeBytes(8, ArrayRef<uint8_t>(SmallBuffer)));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000253}
254
255TEST(MappedBlockStreamTest, TestWriteBytesNoBreakBoundary) {
256 static uint8_t Data[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
257 DiscontiguousFile F(BlocksAry, Data);
Zachary Turner199f48a2016-07-28 19:11:09 +0000258 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
259 EXPECT_EXPECTED(ExpectedS);
260 auto &S = *ExpectedS;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000261 ArrayRef<uint8_t> Buffer;
262
Zachary Turner199f48a2016-07-28 19:11:09 +0000263 EXPECT_NO_ERROR(S->readBytes(0, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000264 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
Zachary Turner199f48a2016-07-28 19:11:09 +0000265 EXPECT_NO_ERROR(S->readBytes(9, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000266 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
267
Zachary Turner199f48a2016-07-28 19:11:09 +0000268 EXPECT_NO_ERROR(S->writeBytes(0, ArrayRef<uint8_t>('J')));
269 EXPECT_NO_ERROR(S->writeBytes(9, ArrayRef<uint8_t>('A')));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000270
Zachary Turner199f48a2016-07-28 19:11:09 +0000271 EXPECT_NO_ERROR(S->readBytes(0, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000272 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
Zachary Turner199f48a2016-07-28 19:11:09 +0000273 EXPECT_NO_ERROR(S->readBytes(9, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000274 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
275
Zachary Turner199f48a2016-07-28 19:11:09 +0000276 EXPECT_NO_ERROR(S->writeBytes(0, ArrayRef<uint8_t>('A')));
277 EXPECT_NO_ERROR(S->writeBytes(9, ArrayRef<uint8_t>('J')));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000278
Zachary Turner199f48a2016-07-28 19:11:09 +0000279 EXPECT_NO_ERROR(S->readBytes(0, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000280 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('A'));
Zachary Turner199f48a2016-07-28 19:11:09 +0000281 EXPECT_NO_ERROR(S->readBytes(9, 1, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000282 EXPECT_EQ(Buffer, ArrayRef<uint8_t>('J'));
283}
284
285TEST(MappedBlockStreamTest, TestWriteBytesBreakBoundary) {
286 static uint8_t Data[] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0'};
287 static uint8_t TestData[] = {'T', 'E', 'S', 'T', 'I', 'N', 'G', '.'};
288 static uint8_t Expected[] = {'T', 'E', 'S', 'N', 'I',
289 'T', 'G', '.', '0', '0'};
290
291 DiscontiguousFile F(BlocksAry, Data);
Zachary Turner199f48a2016-07-28 19:11:09 +0000292 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
293 EXPECT_EXPECTED(ExpectedS);
294 auto &S = *ExpectedS;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000295 ArrayRef<uint8_t> Buffer;
296
Zachary Turner199f48a2016-07-28 19:11:09 +0000297 EXPECT_NO_ERROR(S->writeBytes(0, TestData));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000298 // First just compare the memory, then compare the result of reading the
299 // string out.
300 EXPECT_EQ(ArrayRef<uint8_t>(Data), ArrayRef<uint8_t>(Expected));
301
Zachary Turner199f48a2016-07-28 19:11:09 +0000302 EXPECT_NO_ERROR(S->readBytes(0, 8, Buffer));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000303 EXPECT_EQ(Buffer, ArrayRef<uint8_t>(TestData));
304}
305
306TEST(MappedBlockStreamTest, TestWriteThenRead) {
307 std::vector<uint8_t> DataBytes(10);
308 MutableArrayRef<uint8_t> Data(DataBytes);
309 const uint32_t Blocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
310
311 DiscontiguousFile F(Blocks, Data);
Zachary Turner199f48a2016-07-28 19:11:09 +0000312 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
313 EXPECT_EXPECTED(ExpectedS);
314 auto &S = *ExpectedS;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000315
316 enum class MyEnum : uint32_t { Val1 = 2908234, Val2 = 120891234 };
Zachary Turner97609bb2016-06-10 21:47:26 +0000317 using support::ulittle32_t;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000318
319 uint16_t u16[] = {31468, 0};
320 uint32_t u32[] = {890723408, 0};
321 MyEnum Enum[] = {MyEnum::Val1, MyEnum::Val2};
322 StringRef ZStr[] = {"Zero Str", ""};
323 StringRef FStr[] = {"Fixed Str", ""};
NAKAMURA Takumif1b183c2016-06-11 06:37:28 +0000324 uint8_t byteArray0[] = {'1', '2'};
325 uint8_t byteArray1[] = {'0', '0'};
Zachary Turner352cfe42016-07-08 16:57:14 +0000326 ArrayRef<uint8_t> byteArrayRef0(byteArray0);
327 ArrayRef<uint8_t> byteArrayRef1(byteArray1);
328 ArrayRef<uint8_t> byteArray[] = { byteArrayRef0, byteArrayRef1 };
Reid Kleckner84149c42016-07-28 18:17:01 +0000329 uint32_t intArr0[] = {890723408, 29082234};
330 uint32_t intArr1[] = {890723408, 29082234};
331 ArrayRef<uint32_t> intArray[] = {intArr0, intArr1};
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000332
Zachary Turner199f48a2016-07-28 19:11:09 +0000333 StreamReader Reader(*S);
334 StreamWriter Writer(*S);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000335 EXPECT_NO_ERROR(Writer.writeInteger(u16[0]));
336 EXPECT_NO_ERROR(Reader.readInteger(u16[1]));
337 EXPECT_EQ(u16[0], u16[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000338 EXPECT_EQ(std::vector<uint8_t>({0, 0x7A, 0xEC, 0, 0, 0, 0, 0, 0, 0}),
339 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000340
341 Reader.setOffset(0);
342 Writer.setOffset(0);
343 ::memset(DataBytes.data(), 0, 10);
344 EXPECT_NO_ERROR(Writer.writeInteger(u32[0]));
345 EXPECT_NO_ERROR(Reader.readInteger(u32[1]));
346 EXPECT_EQ(u32[0], u32[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000347 EXPECT_EQ(std::vector<uint8_t>({0x17, 0x5C, 0x50, 0, 0, 0, 0x35, 0, 0, 0}),
348 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000349
350 Reader.setOffset(0);
351 Writer.setOffset(0);
352 ::memset(DataBytes.data(), 0, 10);
353 EXPECT_NO_ERROR(Writer.writeEnum(Enum[0]));
354 EXPECT_NO_ERROR(Reader.readEnum(Enum[1]));
355 EXPECT_EQ(Enum[0], Enum[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000356 EXPECT_EQ(std::vector<uint8_t>({0x2C, 0x60, 0x4A, 0, 0, 0, 0, 0, 0, 0}),
357 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000358
359 Reader.setOffset(0);
360 Writer.setOffset(0);
361 ::memset(DataBytes.data(), 0, 10);
362 EXPECT_NO_ERROR(Writer.writeZeroString(ZStr[0]));
363 EXPECT_NO_ERROR(Reader.readZeroString(ZStr[1]));
364 EXPECT_EQ(ZStr[0], ZStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000365 EXPECT_EQ(
366 std::vector<uint8_t>({'r', 'e', 'Z', ' ', 'S', 't', 'o', 'r', 0, 0}),
367 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000368
369 Reader.setOffset(0);
370 Writer.setOffset(0);
371 ::memset(DataBytes.data(), 0, 10);
372 EXPECT_NO_ERROR(Writer.writeFixedString(FStr[0]));
373 EXPECT_NO_ERROR(Reader.readFixedString(FStr[1], FStr[0].size()));
374 EXPECT_EQ(FStr[0], FStr[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000375 EXPECT_EQ(
376 std::vector<uint8_t>({'x', 'i', 'F', 'd', ' ', 'S', 'e', 't', 0, 'r'}),
377 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000378
379 Reader.setOffset(0);
380 Writer.setOffset(0);
381 ::memset(DataBytes.data(), 0, 10);
382 EXPECT_NO_ERROR(Writer.writeArray(byteArray[0]));
383 EXPECT_NO_ERROR(Reader.readArray(byteArray[1], byteArray[0].size()));
384 EXPECT_EQ(byteArray[0], byteArray[1]);
Zachary Turnerd4c1efc2016-06-10 22:12:18 +0000385 EXPECT_EQ(std::vector<uint8_t>({0, 0x32, 0x31, 0, 0, 0, 0, 0, 0, 0}),
386 DataBytes);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000387
388 Reader.setOffset(0);
389 Writer.setOffset(0);
390 ::memset(DataBytes.data(), 0, 10);
391 EXPECT_NO_ERROR(Writer.writeArray(intArray[0]));
392 EXPECT_NO_ERROR(Reader.readArray(intArray[1], intArray[0].size()));
393 EXPECT_EQ(intArray[0], intArray[1]);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000394}
395
396TEST(MappedBlockStreamTest, TestWriteContiguousStreamRef) {
397 std::vector<uint8_t> DestDataBytes(10);
398 MutableArrayRef<uint8_t> DestData(DestDataBytes);
399 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
400
401 std::vector<uint8_t> SrcDataBytes(10);
402 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
403
404 DiscontiguousFile F(DestBlocks, DestData);
Zachary Turner199f48a2016-07-28 19:11:09 +0000405 auto ExpectedS = MappedBlockStream::createIndexedStream(0, F);
406 EXPECT_EXPECTED(ExpectedS);
407 auto &DestStream = *ExpectedS;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000408
409 // First write "Test Str" into the source stream.
410 ByteStream<true> SourceStream(SrcData);
411 StreamWriter SourceWriter(SourceStream);
412 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
413 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
414 {'T', 'e', 's', 't', ' ', 'S', 't', 'r', 0, 0}));
415
416 // Then write the source stream into the dest stream.
Zachary Turner199f48a2016-07-28 19:11:09 +0000417 StreamWriter DestWriter(*DestStream);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000418 EXPECT_NO_ERROR(DestWriter.writeStreamRef(SourceStream));
419 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
420 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
421
422 // Then read the string back out of the dest stream.
423 StringRef Result;
Zachary Turner199f48a2016-07-28 19:11:09 +0000424 StreamReader DestReader(*DestStream);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000425 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
426 EXPECT_EQ(Result, "Test Str");
427}
428
429TEST(MappedBlockStreamTest, TestWriteDiscontiguousStreamRef) {
430 std::vector<uint8_t> DestDataBytes(10);
431 MutableArrayRef<uint8_t> DestData(DestDataBytes);
432 const uint32_t DestBlocks[] = {2, 1, 0, 6, 3, 4, 5, 7, 9, 8};
433
434 std::vector<uint8_t> SrcDataBytes(10);
435 MutableArrayRef<uint8_t> SrcData(SrcDataBytes);
436 const uint32_t SrcBlocks[] = {1, 0, 6, 3, 4, 5, 2, 7, 8, 9};
437
438 DiscontiguousFile DestFile(DestBlocks, DestData);
439 DiscontiguousFile SrcFile(SrcBlocks, SrcData);
440
Zachary Turner199f48a2016-07-28 19:11:09 +0000441 auto ExpectedDest = MappedBlockStream::createIndexedStream(0, DestFile);
442 auto ExpectedSrc = MappedBlockStream::createIndexedStream(0, SrcFile);
443 EXPECT_EXPECTED(ExpectedDest);
444 EXPECT_EXPECTED(ExpectedSrc);
445 auto &DestStream = *ExpectedDest;
446 auto &SrcStream = *ExpectedSrc;
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000447
448 // First write "Test Str" into the source stream.
Zachary Turner199f48a2016-07-28 19:11:09 +0000449 StreamWriter SourceWriter(*SrcStream);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000450 EXPECT_NO_ERROR(SourceWriter.writeZeroString("Test Str"));
451 EXPECT_EQ(SrcDataBytes, std::vector<uint8_t>(
452 {'e', 'T', 't', 't', ' ', 'S', 's', 'r', 0, 0}));
453
454 // Then write the source stream into the dest stream.
Zachary Turner199f48a2016-07-28 19:11:09 +0000455 StreamWriter DestWriter(*DestStream);
456 EXPECT_NO_ERROR(DestWriter.writeStreamRef(*SrcStream));
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000457 EXPECT_EQ(DestDataBytes, std::vector<uint8_t>(
458 {'s', 'e', 'T', ' ', 'S', 't', 't', 'r', 0, 0}));
459
460 // Then read the string back out of the dest stream.
461 StringRef Result;
Zachary Turner199f48a2016-07-28 19:11:09 +0000462 StreamReader DestReader(*DestStream);
Zachary Turner5acb4ac2016-06-10 05:09:12 +0000463 EXPECT_NO_ERROR(DestReader.readZeroString(Result));
464 EXPECT_EQ(Result, "Test Str");
465}
466
Zachary Turner90b8b8d2016-05-31 22:41:52 +0000467} // end anonymous namespace