188a1d9fcSBenjamin Kramer //===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===//
288a1d9fcSBenjamin Kramer //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
688a1d9fcSBenjamin Kramer //
788a1d9fcSBenjamin Kramer //===----------------------------------------------------------------------===//
888a1d9fcSBenjamin Kramer
988a1d9fcSBenjamin Kramer #include "llvm/Support/DataExtractor.h"
10b1f29cecSPavel Labath #include "llvm/Testing/Support/Error.h"
119a67b073SChandler Carruth #include "gtest/gtest.h"
1288a1d9fcSBenjamin Kramer using namespace llvm;
1388a1d9fcSBenjamin Kramer
1488a1d9fcSBenjamin Kramer namespace {
1588a1d9fcSBenjamin Kramer
1688a1d9fcSBenjamin Kramer const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00";
1788a1d9fcSBenjamin Kramer const char leb128data[] = "\xA6\x49";
181b07ab51SBenjamin Kramer const char bigleb128data[] = "\xAA\xA9\xFF\xAA\xFF\xAA\xFF\x4A";
1988a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,OffsetOverflow)2045ee9332SIgor Kudrin TEST(DataExtractorTest, OffsetOverflow) {
2188a1d9fcSBenjamin Kramer DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
2288a1d9fcSBenjamin Kramer EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5));
2388a1d9fcSBenjamin Kramer }
2488a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,UnsignedNumbers)2545ee9332SIgor Kudrin TEST(DataExtractorTest, UnsignedNumbers) {
2688a1d9fcSBenjamin Kramer DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
2745ee9332SIgor Kudrin uint64_t offset = 0;
2888a1d9fcSBenjamin Kramer
2988a1d9fcSBenjamin Kramer EXPECT_EQ(0x80U, DE.getU8(&offset));
3088a1d9fcSBenjamin Kramer EXPECT_EQ(1U, offset);
3188a1d9fcSBenjamin Kramer offset = 0;
3288a1d9fcSBenjamin Kramer EXPECT_EQ(0x8090U, DE.getU16(&offset));
3388a1d9fcSBenjamin Kramer EXPECT_EQ(2U, offset);
3488a1d9fcSBenjamin Kramer offset = 0;
3588a1d9fcSBenjamin Kramer EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset));
3688a1d9fcSBenjamin Kramer EXPECT_EQ(4U, offset);
3788a1d9fcSBenjamin Kramer offset = 0;
380378726aSNAKAMURA Takumi EXPECT_EQ(0x8090FFFF80000000ULL, DE.getU64(&offset));
3988a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
4088a1d9fcSBenjamin Kramer offset = 0;
410378726aSNAKAMURA Takumi EXPECT_EQ(0x8090FFFF80000000ULL, DE.getAddress(&offset));
4288a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
4388a1d9fcSBenjamin Kramer offset = 0;
4488a1d9fcSBenjamin Kramer
4588a1d9fcSBenjamin Kramer uint32_t data[2];
4688a1d9fcSBenjamin Kramer EXPECT_EQ(data, DE.getU32(&offset, data, 2));
4788a1d9fcSBenjamin Kramer EXPECT_EQ(0x8090FFFFU, data[0]);
4888a1d9fcSBenjamin Kramer EXPECT_EQ(0x80000000U, data[1]);
4988a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
5088a1d9fcSBenjamin Kramer offset = 0;
5188a1d9fcSBenjamin Kramer
5288a1d9fcSBenjamin Kramer // Now for little endian.
5388a1d9fcSBenjamin Kramer DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4);
5488a1d9fcSBenjamin Kramer EXPECT_EQ(0x9080U, DE.getU16(&offset));
5588a1d9fcSBenjamin Kramer EXPECT_EQ(2U, offset);
5688a1d9fcSBenjamin Kramer offset = 0;
5788a1d9fcSBenjamin Kramer EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset));
5888a1d9fcSBenjamin Kramer EXPECT_EQ(4U, offset);
5988a1d9fcSBenjamin Kramer offset = 0;
600378726aSNAKAMURA Takumi EXPECT_EQ(0x80FFFF9080ULL, DE.getU64(&offset));
6188a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
6288a1d9fcSBenjamin Kramer offset = 0;
6388a1d9fcSBenjamin Kramer EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset));
6488a1d9fcSBenjamin Kramer EXPECT_EQ(4U, offset);
6588a1d9fcSBenjamin Kramer offset = 0;
6688a1d9fcSBenjamin Kramer
6788a1d9fcSBenjamin Kramer EXPECT_EQ(data, DE.getU32(&offset, data, 2));
6888a1d9fcSBenjamin Kramer EXPECT_EQ(0xFFFF9080U, data[0]);
6988a1d9fcSBenjamin Kramer EXPECT_EQ(0x80U, data[1]);
7088a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
7188a1d9fcSBenjamin Kramer }
7288a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,SignedNumbers)7345ee9332SIgor Kudrin TEST(DataExtractorTest, SignedNumbers) {
7488a1d9fcSBenjamin Kramer DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8);
7545ee9332SIgor Kudrin uint64_t offset = 0;
7688a1d9fcSBenjamin Kramer
7788a1d9fcSBenjamin Kramer EXPECT_EQ(-128, DE.getSigned(&offset, 1));
7888a1d9fcSBenjamin Kramer EXPECT_EQ(1U, offset);
7988a1d9fcSBenjamin Kramer offset = 0;
8088a1d9fcSBenjamin Kramer EXPECT_EQ(-32624, DE.getSigned(&offset, 2));
8188a1d9fcSBenjamin Kramer EXPECT_EQ(2U, offset);
8288a1d9fcSBenjamin Kramer offset = 0;
8388a1d9fcSBenjamin Kramer EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4));
8488a1d9fcSBenjamin Kramer EXPECT_EQ(4U, offset);
8588a1d9fcSBenjamin Kramer offset = 0;
8688a1d9fcSBenjamin Kramer EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8));
8788a1d9fcSBenjamin Kramer EXPECT_EQ(8U, offset);
8888a1d9fcSBenjamin Kramer }
8988a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,Strings)9045ee9332SIgor Kudrin TEST(DataExtractorTest, Strings) {
91a16fffa3SPavel Labath const char stringData[] = "hellohello\0hello";
9288a1d9fcSBenjamin Kramer DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8);
9345ee9332SIgor Kudrin uint64_t offset = 0;
9488a1d9fcSBenjamin Kramer
9588a1d9fcSBenjamin Kramer EXPECT_EQ(stringData, DE.getCStr(&offset));
9688a1d9fcSBenjamin Kramer EXPECT_EQ(11U, offset);
9766f09ad0SCraig Topper EXPECT_EQ(nullptr, DE.getCStr(&offset));
9888a1d9fcSBenjamin Kramer EXPECT_EQ(11U, offset);
99a16fffa3SPavel Labath
100a16fffa3SPavel Labath DataExtractor::Cursor C(0);
101a16fffa3SPavel Labath EXPECT_EQ(stringData, DE.getCStr(C));
102a16fffa3SPavel Labath EXPECT_EQ(11U, C.tell());
103a16fffa3SPavel Labath EXPECT_EQ(nullptr, DE.getCStr(C));
104a16fffa3SPavel Labath EXPECT_EQ(11U, C.tell());
10504aea769SPavel Labath EXPECT_THAT_ERROR(
10604aea769SPavel Labath C.takeError(),
10704aea769SPavel Labath FailedWithMessage("no null terminated string at offset 0xb"));
10888a1d9fcSBenjamin Kramer }
10988a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,LEB128)11045ee9332SIgor Kudrin TEST(DataExtractorTest, LEB128) {
11188a1d9fcSBenjamin Kramer DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8);
11245ee9332SIgor Kudrin uint64_t offset = 0;
11388a1d9fcSBenjamin Kramer
11488a1d9fcSBenjamin Kramer EXPECT_EQ(9382ULL, DE.getULEB128(&offset));
11588a1d9fcSBenjamin Kramer EXPECT_EQ(2U, offset);
11688a1d9fcSBenjamin Kramer offset = 0;
11788a1d9fcSBenjamin Kramer EXPECT_EQ(-7002LL, DE.getSLEB128(&offset));
11888a1d9fcSBenjamin Kramer EXPECT_EQ(2U, offset);
1191b07ab51SBenjamin Kramer
1201b07ab51SBenjamin Kramer DataExtractor BDE(StringRef(bigleb128data, sizeof(bigleb128data)-1), false,8);
1211b07ab51SBenjamin Kramer offset = 0;
1221b07ab51SBenjamin Kramer EXPECT_EQ(42218325750568106ULL, BDE.getULEB128(&offset));
1231b07ab51SBenjamin Kramer EXPECT_EQ(8U, offset);
1241b07ab51SBenjamin Kramer offset = 0;
1251b07ab51SBenjamin Kramer EXPECT_EQ(-29839268287359830LL, BDE.getSLEB128(&offset));
1261b07ab51SBenjamin Kramer EXPECT_EQ(8U, offset);
12788a1d9fcSBenjamin Kramer }
12888a1d9fcSBenjamin Kramer
TEST(DataExtractorTest,LEB128_error)12945ee9332SIgor Kudrin TEST(DataExtractorTest, LEB128_error) {
130bb6d0b8eSPavel Labath DataExtractor DE(StringRef("\x81"), false, 8);
13145ee9332SIgor Kudrin uint64_t Offset = 0;
132bb6d0b8eSPavel Labath EXPECT_EQ(0U, DE.getULEB128(&Offset));
133bb6d0b8eSPavel Labath EXPECT_EQ(0U, Offset);
134bb6d0b8eSPavel Labath
135bb6d0b8eSPavel Labath Offset = 0;
136bb6d0b8eSPavel Labath EXPECT_EQ(0U, DE.getSLEB128(&Offset));
137bb6d0b8eSPavel Labath EXPECT_EQ(0U, Offset);
1389154a639SPavel Labath
1399154a639SPavel Labath DataExtractor::Cursor C(0);
1409154a639SPavel Labath EXPECT_EQ(0U, DE.getULEB128(C));
1418d9070e0SJames Henderson EXPECT_THAT_ERROR(
1428d9070e0SJames Henderson C.takeError(),
1438d9070e0SJames Henderson FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
1448d9070e0SJames Henderson "malformed uleb128, extends past end"));
1459154a639SPavel Labath
1469154a639SPavel Labath C = DataExtractor::Cursor(0);
1479154a639SPavel Labath EXPECT_EQ(0U, DE.getSLEB128(C));
1488d9070e0SJames Henderson EXPECT_THAT_ERROR(
1498d9070e0SJames Henderson C.takeError(),
1508d9070e0SJames Henderson FailedWithMessage("unable to decode LEB128 at offset 0x00000000: "
1518d9070e0SJames Henderson "malformed sleb128, extends past end"));
1528d9070e0SJames Henderson
1538d9070e0SJames Henderson // Show non-zero offsets are reported appropriately.
1548d9070e0SJames Henderson C = DataExtractor::Cursor(1);
1558d9070e0SJames Henderson EXPECT_EQ(0U, DE.getULEB128(C));
1568d9070e0SJames Henderson EXPECT_THAT_ERROR(
1578d9070e0SJames Henderson C.takeError(),
1588d9070e0SJames Henderson FailedWithMessage("unable to decode LEB128 at offset 0x00000001: "
1598d9070e0SJames Henderson "malformed uleb128, extends past end"));
160bb6d0b8eSPavel Labath }
161b1f29cecSPavel Labath
TEST(DataExtractorTest,Cursor_tell)162b1f29cecSPavel Labath TEST(DataExtractorTest, Cursor_tell) {
163b1f29cecSPavel Labath DataExtractor DE(StringRef("AB"), false, 8);
164b1f29cecSPavel Labath DataExtractor::Cursor C(0);
165b1f29cecSPavel Labath // A successful read operation advances the cursor
166b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(C));
167b1f29cecSPavel Labath EXPECT_EQ(1u, C.tell());
168b1f29cecSPavel Labath
169b1f29cecSPavel Labath // An unsuccessful one doesn't.
170b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU16(C));
171b1f29cecSPavel Labath EXPECT_EQ(1u, C.tell());
172b1f29cecSPavel Labath
173b1f29cecSPavel Labath // And neither do any subsequent operations.
174b1f29cecSPavel Labath EXPECT_EQ(0, DE.getU8(C));
175b1f29cecSPavel Labath EXPECT_EQ(1u, C.tell());
176b1f29cecSPavel Labath
177b1f29cecSPavel Labath consumeError(C.takeError());
178b1f29cecSPavel Labath }
179b1f29cecSPavel Labath
TEST(DataExtractorTest,Cursor_seek)180*baa18ee6Szhijian TEST(DataExtractorTest, Cursor_seek) {
181*baa18ee6Szhijian DataExtractor::Cursor C(5);
182*baa18ee6Szhijian
183*baa18ee6Szhijian C.seek(3);
184*baa18ee6Szhijian EXPECT_EQ(3u, C.tell());
185*baa18ee6Szhijian
186*baa18ee6Szhijian C.seek(8);
187*baa18ee6Szhijian EXPECT_EQ(8u, C.tell());
188*baa18ee6Szhijian
189*baa18ee6Szhijian EXPECT_THAT_ERROR(C.takeError(), Succeeded());
190*baa18ee6Szhijian }
191*baa18ee6Szhijian
TEST(DataExtractorTest,Cursor_takeError)192b1f29cecSPavel Labath TEST(DataExtractorTest, Cursor_takeError) {
193b1f29cecSPavel Labath DataExtractor DE(StringRef("AB"), false, 8);
194b1f29cecSPavel Labath DataExtractor::Cursor C(0);
195b1f29cecSPavel Labath // Initially, the cursor is in the "success" state.
196b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
197b1f29cecSPavel Labath
198b1f29cecSPavel Labath // It remains "success" after a successful read.
199b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(C));
200b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
201b1f29cecSPavel Labath
202b1f29cecSPavel Labath // An unsuccessful read sets the error state.
203b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU32(C));
204b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
205b1f29cecSPavel Labath
206b1f29cecSPavel Labath // Once set the error sticks until explicitly cleared.
207b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU32(C));
208b1f29cecSPavel Labath EXPECT_EQ(0, DE.getU8(C));
209b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
210b1f29cecSPavel Labath
211b1f29cecSPavel Labath // At which point reads can be succeed again.
212b1f29cecSPavel Labath EXPECT_EQ('B', DE.getU8(C));
213b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
214b1f29cecSPavel Labath }
215b1f29cecSPavel Labath
TEST(DataExtractorTest,Cursor_chaining)216b1f29cecSPavel Labath TEST(DataExtractorTest, Cursor_chaining) {
217b1f29cecSPavel Labath DataExtractor DE(StringRef("ABCD"), false, 8);
218b1f29cecSPavel Labath DataExtractor::Cursor C(0);
219b1f29cecSPavel Labath
220b1f29cecSPavel Labath // Multiple reads can be chained without trigerring any assertions.
221b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(C));
222b1f29cecSPavel Labath EXPECT_EQ('B', DE.getU8(C));
223b1f29cecSPavel Labath EXPECT_EQ('C', DE.getU8(C));
224b1f29cecSPavel Labath EXPECT_EQ('D', DE.getU8(C));
225b1f29cecSPavel Labath // And the error checked at the end.
226b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
227b1f29cecSPavel Labath }
228b1f29cecSPavel Labath
2293503c856SDavid Blaikie #if defined(GTEST_HAS_DEATH_TEST) && defined(_DEBUG) && \
2303503c856SDavid Blaikie LLVM_ENABLE_ABI_BREAKING_CHECKS
TEST(DataExtractorDeathTest,Cursor)231b1f29cecSPavel Labath TEST(DataExtractorDeathTest, Cursor) {
232b1f29cecSPavel Labath DataExtractor DE(StringRef("AB"), false, 8);
233b1f29cecSPavel Labath
234b1f29cecSPavel Labath // Even an unused cursor must be checked for errors:
235b1f29cecSPavel Labath EXPECT_DEATH(DataExtractor::Cursor(0),
236b1f29cecSPavel Labath "Success values must still be checked prior to being destroyed");
237b1f29cecSPavel Labath
238b1f29cecSPavel Labath {
239b1f29cecSPavel Labath auto C = std::make_unique<DataExtractor::Cursor>(0);
240b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU32(*C));
241b1f29cecSPavel Labath // It must also be checked after an unsuccessful operation.
242b1f29cecSPavel Labath // destruction.
243b1f29cecSPavel Labath EXPECT_DEATH(C.reset(), "unexpected end of data");
244b1f29cecSPavel Labath EXPECT_THAT_ERROR(C->takeError(), Failed());
245b1f29cecSPavel Labath }
246b1f29cecSPavel Labath {
247b1f29cecSPavel Labath auto C = std::make_unique<DataExtractor::Cursor>(0);
248b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(*C));
249b1f29cecSPavel Labath // Same goes for a successful one.
250b1f29cecSPavel Labath EXPECT_DEATH(
251b1f29cecSPavel Labath C.reset(),
252b1f29cecSPavel Labath "Success values must still be checked prior to being destroyed");
253b1f29cecSPavel Labath EXPECT_THAT_ERROR(C->takeError(), Succeeded());
254b1f29cecSPavel Labath }
255b1f29cecSPavel Labath {
256b1f29cecSPavel Labath auto C = std::make_unique<DataExtractor::Cursor>(0);
257b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(*C));
258b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU32(*C));
259b1f29cecSPavel Labath // Even if a successful operation is followed by an unsuccessful one.
260b1f29cecSPavel Labath EXPECT_DEATH(C.reset(), "unexpected end of data");
261b1f29cecSPavel Labath EXPECT_THAT_ERROR(C->takeError(), Failed());
262b1f29cecSPavel Labath }
263b1f29cecSPavel Labath {
264b1f29cecSPavel Labath auto C = std::make_unique<DataExtractor::Cursor>(0);
265b1f29cecSPavel Labath EXPECT_EQ(0u, DE.getU32(*C));
266b1f29cecSPavel Labath EXPECT_EQ(0, DE.getU8(*C));
267b1f29cecSPavel Labath // Even if an unsuccessful operation is followed by one that would normally
268b1f29cecSPavel Labath // succeed.
269b1f29cecSPavel Labath EXPECT_DEATH(C.reset(), "unexpected end of data");
270b1f29cecSPavel Labath EXPECT_THAT_ERROR(C->takeError(), Failed());
271b1f29cecSPavel Labath }
272b1f29cecSPavel Labath }
273b1f29cecSPavel Labath #endif
274b1f29cecSPavel Labath
TEST(DataExtractorTest,getU8_vector)275b1f29cecSPavel Labath TEST(DataExtractorTest, getU8_vector) {
276b1f29cecSPavel Labath DataExtractor DE(StringRef("AB"), false, 8);
277b1f29cecSPavel Labath DataExtractor::Cursor C(0);
278b1f29cecSPavel Labath SmallVector<uint8_t, 2> S;
279b1f29cecSPavel Labath
280b1f29cecSPavel Labath DE.getU8(C, S, 4);
281b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
282b1f29cecSPavel Labath EXPECT_EQ("", toStringRef(S));
283b1f29cecSPavel Labath
284b1f29cecSPavel Labath DE.getU8(C, S, 2);
285b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
286b1f29cecSPavel Labath EXPECT_EQ("AB", toStringRef(S));
28704aea769SPavel Labath
28804aea769SPavel Labath C = DataExtractor::Cursor(0x47);
28904aea769SPavel Labath DE.getU8(C, S, 2);
29004aea769SPavel Labath EXPECT_THAT_ERROR(
29104aea769SPavel Labath C.takeError(),
29204aea769SPavel Labath FailedWithMessage("offset 0x47 is beyond the end of data at 0x2"));
293b1f29cecSPavel Labath }
294b1f29cecSPavel Labath
TEST(DataExtractorTest,getU24)2959154a639SPavel Labath TEST(DataExtractorTest, getU24) {
2969154a639SPavel Labath DataExtractor DE(StringRef("ABCD"), false, 8);
2979154a639SPavel Labath DataExtractor::Cursor C(0);
2989154a639SPavel Labath
2999154a639SPavel Labath EXPECT_EQ(0x414243u, DE.getU24(C));
3009154a639SPavel Labath EXPECT_EQ(0u, DE.getU24(C));
3019154a639SPavel Labath EXPECT_EQ(3u, C.tell());
3029154a639SPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
3039154a639SPavel Labath }
3049154a639SPavel Labath
TEST(DataExtractorTest,skip)305b1f29cecSPavel Labath TEST(DataExtractorTest, skip) {
306b1f29cecSPavel Labath DataExtractor DE(StringRef("AB"), false, 8);
307b1f29cecSPavel Labath DataExtractor::Cursor C(0);
308b1f29cecSPavel Labath
309b1f29cecSPavel Labath DE.skip(C, 4);
310b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
311b1f29cecSPavel Labath EXPECT_EQ(0u, C.tell());
312b1f29cecSPavel Labath
313b1f29cecSPavel Labath DE.skip(C, 2);
314b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
315b1f29cecSPavel Labath EXPECT_EQ(2u, C.tell());
316b1f29cecSPavel Labath }
317b1f29cecSPavel Labath
TEST(DataExtractorTest,eof)318b1f29cecSPavel Labath TEST(DataExtractorTest, eof) {
319b1f29cecSPavel Labath DataExtractor DE(StringRef("A"), false, 8);
320b1f29cecSPavel Labath DataExtractor::Cursor C(0);
321b1f29cecSPavel Labath
322b1f29cecSPavel Labath EXPECT_FALSE(DE.eof(C));
323b1f29cecSPavel Labath
324b1f29cecSPavel Labath EXPECT_EQ(0, DE.getU16(C));
325b1f29cecSPavel Labath EXPECT_FALSE(DE.eof(C));
326b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
327b1f29cecSPavel Labath
328b1f29cecSPavel Labath EXPECT_EQ('A', DE.getU8(C));
329b1f29cecSPavel Labath EXPECT_TRUE(DE.eof(C));
330b1f29cecSPavel Labath EXPECT_THAT_ERROR(C.takeError(), Succeeded());
331b1f29cecSPavel Labath }
332b6ffa2feSJames Henderson
TEST(DataExtractorTest,size)333b6ffa2feSJames Henderson TEST(DataExtractorTest, size) {
334b6ffa2feSJames Henderson uint8_t Data[] = {'A', 'B', 'C', 'D'};
335b6ffa2feSJames Henderson DataExtractor DE1(StringRef(reinterpret_cast<char *>(Data), sizeof(Data)),
336b6ffa2feSJames Henderson false, 8);
337b6ffa2feSJames Henderson EXPECT_EQ(DE1.size(), sizeof(Data));
338b6ffa2feSJames Henderson DataExtractor DE2(ArrayRef<uint8_t>(Data), false, 8);
339b6ffa2feSJames Henderson EXPECT_EQ(DE2.size(), sizeof(Data));
340b6ffa2feSJames Henderson }
341df8dda67SGreg Clayton
TEST(DataExtractorTest,FixedLengthString)342df8dda67SGreg Clayton TEST(DataExtractorTest, FixedLengthString) {
343df8dda67SGreg Clayton const char Data[] = "hello\x00\x00\x00world \thola\x00";
344df8dda67SGreg Clayton DataExtractor DE(StringRef(Data, sizeof(Data)-1), false, 8);
345df8dda67SGreg Clayton uint64_t Offset = 0;
346df8dda67SGreg Clayton StringRef Str;
347df8dda67SGreg Clayton // Test extracting too many bytes doesn't modify Offset and returns None.
348df8dda67SGreg Clayton Str = DE.getFixedLengthString(&Offset, sizeof(Data));
349df8dda67SGreg Clayton EXPECT_TRUE(Str.empty());
350df8dda67SGreg Clayton EXPECT_EQ(Offset, 0u);
351df8dda67SGreg Clayton
352df8dda67SGreg Clayton // Test extracting a fixed width C string with trailing NULL characters.
353df8dda67SGreg Clayton Str = DE.getFixedLengthString(&Offset, 8);
354df8dda67SGreg Clayton EXPECT_EQ(Offset, 8u);
355df8dda67SGreg Clayton EXPECT_EQ(Str.size(), 5u);
356df8dda67SGreg Clayton EXPECT_EQ(Str, "hello");
357df8dda67SGreg Clayton // Test extracting a fixed width C string with trailing space and tab
358df8dda67SGreg Clayton // characters.
359df8dda67SGreg Clayton Str = DE.getFixedLengthString(&Offset, 8, " \t");
360df8dda67SGreg Clayton EXPECT_EQ(Offset, 16u);
361df8dda67SGreg Clayton EXPECT_EQ(Str.size(), 5u);
362df8dda67SGreg Clayton EXPECT_EQ(Str, "world");
363df8dda67SGreg Clayton // Now extract a normal C string.
364df8dda67SGreg Clayton Str = DE.getCStrRef(&Offset);
365df8dda67SGreg Clayton EXPECT_EQ(Str.size(), 4u);
366df8dda67SGreg Clayton EXPECT_EQ(Str, "hola");
367df8dda67SGreg Clayton }
368df8dda67SGreg Clayton
369df8dda67SGreg Clayton
TEST(DataExtractorTest,GetBytes)370df8dda67SGreg Clayton TEST(DataExtractorTest, GetBytes) {
371df8dda67SGreg Clayton // Use data with an embedded NULL character for good measure.
372df8dda67SGreg Clayton const char Data[] = "\x01\x02\x00\x04";
373df8dda67SGreg Clayton StringRef Bytes(Data, sizeof(Data)-1);
374df8dda67SGreg Clayton DataExtractor DE(Bytes, false, 8);
375df8dda67SGreg Clayton uint64_t Offset = 0;
376df8dda67SGreg Clayton StringRef Str;
377df8dda67SGreg Clayton // Test extracting too many bytes doesn't modify Offset and returns None.
378df8dda67SGreg Clayton Str = DE.getBytes(&Offset, sizeof(Data));
379df8dda67SGreg Clayton EXPECT_TRUE(Str.empty());
380df8dda67SGreg Clayton EXPECT_EQ(Offset, 0u);
381df8dda67SGreg Clayton // Test extracting 4 bytes from the stream.
382df8dda67SGreg Clayton Str = DE.getBytes(&Offset, 4);
383df8dda67SGreg Clayton EXPECT_EQ(Offset, 4u);
384df8dda67SGreg Clayton EXPECT_EQ(Str.size(), 4u);
385df8dda67SGreg Clayton EXPECT_EQ(Str, Bytes);
3869154a639SPavel Labath
3879154a639SPavel Labath DataExtractor::Cursor C(0);
3889154a639SPavel Labath EXPECT_EQ(StringRef("\x01\x02"), DE.getBytes(C, 2));
3899154a639SPavel Labath EXPECT_EQ(StringRef("\x00\x04", 2), DE.getBytes(C, 2));
3909154a639SPavel Labath EXPECT_EQ(StringRef(), DE.getBytes(C, 2));
3919154a639SPavel Labath EXPECT_EQ(StringRef(), DE.getBytes(C, 2));
3929154a639SPavel Labath EXPECT_EQ(4u, C.tell());
3939154a639SPavel Labath EXPECT_THAT_ERROR(C.takeError(), Failed());
394df8dda67SGreg Clayton }
395df8dda67SGreg Clayton
39688a1d9fcSBenjamin Kramer }
397