Skip to content

Commit 0ccacf6

Browse files
committed
Add tests for some weird bitreader cases
1 parent 872c1c2 commit 0ccacf6

File tree

4 files changed

+152
-1
lines changed

4 files changed

+152
-1
lines changed

bitreader/src/data_source/file_byte_source.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ file_byte_source::file_byte_source(std::shared_ptr<file_reader> reader)
1515

1616
//----------------------------------------------------------------------
1717
size_t file_byte_source::get_n(uint64_t& buf, size_t bytes) {
18+
if (bytes == 0) {
19+
return 0;
20+
}
21+
1822
if (
1923
_position < _last ||
2024
_position + bytes >= _last + _buffer.size() ||

bitreader/src/data_source/memory_byte_source.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ memory_byte_source::memory_byte_source(const uint8_t* data, size_t size)
1818
//----------------------------------------------------------------------
1919
size_t memory_byte_source::get_n(uint64_t& buf, size_t bytes)
2020
{
21+
if (bytes == 0) {
22+
return 0;
23+
}
24+
2125
if (_current == _data.end()) {
2226
throw std::runtime_error("Access beyond data buffer boundaries");
2327
}

bitreader/test/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ cmake_minimum_required(VERSION 3.15)
33
enable_testing()
44

55
############# Bitreader gtest
6-
add_executable(bitreader_gtest bitreader_gtest.cpp bitwriter_gtest.cpp)
6+
add_executable(
7+
bitreader_gtest
8+
bitreader_gtest.cpp
9+
bitwriter_gtest.cpp
10+
)
711

812
target_include_directories(bitreader_gtest PRIVATE ${GTEST_INCLUDE_DIRS})
913

bitreader/test/bitreader_gtest.cpp

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,142 @@ TEST(bitreaderTest, exp_golomb_k0)
277277
EXPECT_EQ(2, br.read<egc>());
278278
EXPECT_EQ(3, br.read<egc>());
279279
}
280+
281+
//------------------------------------------------------------------------------
282+
TEST(bitreaderTest, read_zero_bits)
283+
{
284+
const uint8_t data[] = {0xAB, 0xCD};
285+
auto source = std::make_shared<source_t>(data, sizeof(data));
286+
bitreader<source_t> br(source);
287+
EXPECT_EQ(0, br.read<uint8_t>(0));
288+
EXPECT_EQ(0, br.position());
289+
EXPECT_EQ(16, br.available());
290+
}
291+
292+
//------------------------------------------------------------------------------
293+
TEST(bitreaderTest, read_more_than_available)
294+
{
295+
const uint8_t data[] = {0xAB, 0xCD};
296+
auto source = std::make_shared<source_t>(data, sizeof(data));
297+
bitreader<source_t> br(source);
298+
EXPECT_THROW(br.read<uint32_t>(24), std::exception);
299+
}
300+
301+
//------------------------------------------------------------------------------
302+
TEST(bitreaderTest, read_from_empty_source)
303+
{
304+
const uint8_t data[] = {0x00};
305+
auto source = std::make_shared<source_t>(data, 0);
306+
bitreader<source_t> br(source);
307+
EXPECT_EQ(0, br.available());
308+
EXPECT_THROW(br.read<uint8_t>(1), std::exception);
309+
}
310+
311+
//------------------------------------------------------------------------------
312+
TEST(bitreaderTest, skip_more_than_available)
313+
{
314+
const uint8_t data[] = {0xAB, 0xCD};
315+
auto source = std::make_shared<source_t>(data, sizeof(data));
316+
bitreader<source_t> br(source);
317+
EXPECT_THROW(br.skip(17), std::exception);
318+
}
319+
320+
//------------------------------------------------------------------------------
321+
TEST(bitreaderTest, peek_after_end)
322+
{
323+
const uint8_t data[] = {0xAB, 0xCD};
324+
auto source = std::make_shared<source_t>(data, sizeof(data));
325+
bitreader<source_t> br(source);
326+
EXPECT_NO_THROW(br.skip(16));
327+
EXPECT_EQ(0, br.available());
328+
EXPECT_THROW(br.peek<uint8_t>(1), std::exception);
329+
}
330+
331+
//------------------------------------------------------------------------------
332+
TEST(bitreaderTest, align_at_end)
333+
{
334+
const uint8_t data[] = {0xAB, 0xCD};
335+
auto source = std::make_shared<source_t>(data, sizeof(data));
336+
bitreader<source_t> br(source);
337+
EXPECT_NO_THROW(br.skip(16));
338+
EXPECT_EQ(16, br.position());
339+
EXPECT_NO_THROW(br.align(8));
340+
EXPECT_EQ(16, br.position());
341+
}
342+
343+
//------------------------------------------------------------------------------
344+
TEST(bitreaderTest, read_exact_64_then_one)
345+
{
346+
const uint8_t data[] = {
347+
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08
348+
};
349+
auto source = std::make_shared<source_t>(data, sizeof(data));
350+
bitreader<source_t> br(source);
351+
EXPECT_EQ(0x0102030405060708, br.read<uint64_t>(64));
352+
EXPECT_EQ(64, br.position());
353+
EXPECT_EQ(0, br.available());
354+
EXPECT_THROW(br.read<uint8_t>(1), std::exception);
355+
}
356+
357+
//------------------------------------------------------------------------------
358+
TEST(bitreaderTest, read_various_types)
359+
{
360+
const uint8_t data[] = {0x12, 0x34, 0x56, 0x78};
361+
auto source = std::make_shared<source_t>(data, sizeof(data));
362+
bitreader<source_t> br(source);
363+
EXPECT_EQ(0x1234, br.read<uint16_t>(16));
364+
EXPECT_EQ(16, br.position());
365+
EXPECT_EQ(0x5678, br.read<uint16_t>(16));
366+
EXPECT_EQ(32, br.position());
367+
}
368+
369+
//------------------------------------------------------------------------------
370+
TEST(bitreaderTest, read_signed_cross_boundary)
371+
{
372+
const uint8_t data[] = {0xFF, 0x7F}; // -1, 127
373+
auto source = std::make_shared<source_t>(data, sizeof(data));
374+
bitreader<source_t> br(source);
375+
EXPECT_EQ(-1, br.read<int8_t>(8));
376+
EXPECT_EQ(8, br.position());
377+
EXPECT_EQ(127, br.read<int8_t>(8));
378+
EXPECT_EQ(16, br.position());
379+
}
380+
381+
//------------------------------------------------------------------------------
382+
TEST(bitreaderTest, skip_to_end_and_read)
383+
{
384+
const uint8_t data[] = {0xAA, 0xBB, 0xCC};
385+
auto source = std::make_shared<source_t>(data, sizeof(data));
386+
bitreader<source_t> br(source);
387+
EXPECT_NO_THROW(br.skip(24));
388+
EXPECT_EQ(24, br.position());
389+
EXPECT_EQ(0, br.available());
390+
EXPECT_THROW(br.read<uint8_t>(1), std::exception);
391+
}
392+
393+
//------------------------------------------------------------------------------
394+
TEST(bitreaderTest, peek_various_types)
395+
{
396+
const uint8_t data[] = {0xDE, 0xAD, 0xBE, 0xEF};
397+
auto source = std::make_shared<source_t>(data, sizeof(data));
398+
bitreader<source_t> br(source);
399+
EXPECT_EQ(0xDEADBEEF, br.peek<uint32_t>(32));
400+
EXPECT_EQ(0, br.position());
401+
EXPECT_EQ(0xDEAD, br.peek<uint16_t>(16));
402+
EXPECT_EQ(0, br.position());
403+
EXPECT_EQ(0xDE, br.peek<uint8_t>(8));
404+
EXPECT_EQ(0, br.position());
405+
}
406+
407+
//------------------------------------------------------------------------------
408+
TEST(bitreaderTest, align_to_non_byte_boundary)
409+
{
410+
const uint8_t data[] = {0xF0, 0x0F};
411+
auto source = std::make_shared<source_t>(data, sizeof(data));
412+
bitreader<source_t> br(source);
413+
EXPECT_NO_THROW(br.skip(3));
414+
EXPECT_EQ(3, br.position());
415+
EXPECT_NO_THROW(br.align(5));
416+
EXPECT_EQ(5, br.position());
417+
EXPECT_EQ(11, br.available());
418+
}

0 commit comments

Comments
 (0)