mirror of https://github.com/SeanOMik/libki.git
util: Fix buffer expansion and reformat unit tests
This commit is contained in:
parent
5183131b69
commit
3f5450c64e
|
@ -21,4 +21,4 @@ steps:
|
||||||
- task: PublishTestResults@2
|
- task: PublishTestResults@2
|
||||||
inputs:
|
inputs:
|
||||||
testResultsFormat: 'JUnit'
|
testResultsFormat: 'JUnit'
|
||||||
testResultsFiles: 'build/**/test-*.xml'
|
testResultsFiles: 'build/Testing/reports/test-*.xml'
|
||||||
|
|
|
@ -56,6 +56,11 @@ namespace ki
|
||||||
*/
|
*/
|
||||||
void seek(stream_pos position);
|
void seek(stream_pos position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The current size of the internal buffer.
|
||||||
|
*/
|
||||||
|
std::size_t capacity() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A pointer to the start of the internal buffer.
|
* @return A pointer to the start of the internal buffer.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -141,7 +141,12 @@ namespace ki
|
||||||
validate_buffer();
|
validate_buffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* BitStream::data() const
|
std::size_t BitStream::capacity() const
|
||||||
|
{
|
||||||
|
return m_buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t *BitStream::data() const
|
||||||
{
|
{
|
||||||
return m_buffer;
|
return m_buffer;
|
||||||
}
|
}
|
||||||
|
@ -149,7 +154,7 @@ namespace ki
|
||||||
void BitStream::expand_buffer()
|
void BitStream::expand_buffer()
|
||||||
{
|
{
|
||||||
// Work out a new buffer size
|
// Work out a new buffer size
|
||||||
auto new_size = (2 << (uint64_t)log2(m_position.get_byte())) + 2;
|
auto new_size = (2 << (uint64_t)log2(m_position.get_byte()) + 1) + 2;
|
||||||
if (new_size < m_buffer_size)
|
if (new_size < m_buffer_size)
|
||||||
new_size = std::numeric_limits<size_t>::max();
|
new_size = std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
|
@ -162,6 +167,7 @@ namespace ki
|
||||||
std::memcpy(new_buffer, m_buffer, m_buffer_size);
|
std::memcpy(new_buffer, m_buffer, m_buffer_size);
|
||||||
delete[] m_buffer;
|
delete[] m_buffer;
|
||||||
m_buffer = new_buffer;
|
m_buffer = new_buffer;
|
||||||
|
m_buffer_size = new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitStream::validate_buffer()
|
void BitStream::validate_buffer()
|
||||||
|
|
|
@ -3,6 +3,7 @@ add_library(Catch INTERFACE)
|
||||||
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
|
target_include_directories(Catch INTERFACE ${CATCH_INCLUDE_DIR})
|
||||||
|
|
||||||
file(COPY "samples" DESTINATION "${PROJECT_BINARY_DIR}/test")
|
file(COPY "samples" DESTINATION "${PROJECT_BINARY_DIR}/test")
|
||||||
|
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/reports/")
|
||||||
|
|
||||||
file(GLOB files "src/unit-*.cpp")
|
file(GLOB files "src/unit-*.cpp")
|
||||||
foreach (file ${files})
|
foreach (file ${files})
|
||||||
|
@ -15,5 +16,5 @@ foreach (file ${files})
|
||||||
CXX_STANDARD 11
|
CXX_STANDARD 11
|
||||||
)
|
)
|
||||||
target_link_libraries(${testcase} Catch ${PROJECT_NAME})
|
target_link_libraries(${testcase} Catch ${PROJECT_NAME})
|
||||||
add_test(${testcase} ${testcase} -s -r junit -o ${PROJECT_BINARY_DIR}/Testing/${testcase}.xml)
|
add_test(${testcase} ${testcase} -s -r junit -o "${PROJECT_BINARY_DIR}/Testing/reports/${testcase}.xml")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
|
@ -1,147 +1,199 @@
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include <ki/util/BitStream.h>
|
#include <ki/util/BitStream.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define values we expect during testing.
|
||||||
|
*/
|
||||||
|
#define KI_TEST_BITSTREAM_BUI1 0b1
|
||||||
|
#define KI_TEST_BITSTREAM_BUI2 0b10
|
||||||
|
#define KI_TEST_BITSTREAM_BUI3 0b010
|
||||||
|
#define KI_TEST_BITSTREAM_BUI4 0b0101
|
||||||
|
#define KI_TEST_BITSTREAM_BUI5 0b10101
|
||||||
|
#define KI_TEST_BITSTREAM_BUI6 0b101010
|
||||||
|
#define KI_TEST_BITSTREAM_BUI7 0b0101010
|
||||||
|
#define KI_TEST_BITSTREAM_U8 0x01
|
||||||
|
#define KI_TEST_BITSTREAM_U16 0x0302
|
||||||
|
#define KI_TEST_BITSTREAM_U24 0x060504
|
||||||
|
#define KI_TEST_BITSTREAM_U32 0x0A090807
|
||||||
|
#define KI_TEST_BITSTREAM_U64 0x1211100F0E0D0C0BL
|
||||||
|
|
||||||
|
#define KI_TEST_WRITE_BUI(n) bit_stream->write(KI_TEST_BITSTREAM_BUI##n, n)
|
||||||
|
#define KI_TEST_READ_BUI(n) bit_stream->read<uint8_t>(n) == KI_TEST_BITSTREAM_BUI##n
|
||||||
|
|
||||||
using namespace ki;
|
using namespace ki;
|
||||||
|
|
||||||
TEST_CASE("Write bits", "[bit-stream]")
|
TEST_CASE("BitStream Functionality", "[bit-stream]")
|
||||||
{
|
{
|
||||||
auto *bit_stream = new BitStream();
|
auto *bit_stream = new BitStream();
|
||||||
|
|
||||||
// Write an alternating pattern of bits
|
SECTION("Writing values with a size less than 8 bits")
|
||||||
bit_stream->write(0b1, 1);
|
{
|
||||||
bit_stream->write(0b10, 2);
|
// Write an alternating pattern of bits
|
||||||
bit_stream->write(0b010, 3);
|
KI_TEST_WRITE_BUI(1);
|
||||||
bit_stream->write(0b0101, 4);
|
KI_TEST_WRITE_BUI(2);
|
||||||
bit_stream->write(0b10101, 5);
|
KI_TEST_WRITE_BUI(3);
|
||||||
bit_stream->write(0b101010, 6);
|
KI_TEST_WRITE_BUI(4);
|
||||||
bit_stream->write(0b0101010, 7);
|
KI_TEST_WRITE_BUI(5);
|
||||||
bit_stream->write(0b0101, 4);
|
KI_TEST_WRITE_BUI(6);
|
||||||
|
KI_TEST_WRITE_BUI(7);
|
||||||
|
KI_TEST_WRITE_BUI(4);
|
||||||
|
|
||||||
// Make sure tell is reporting the right position
|
// Make sure tell is reporting the right position
|
||||||
auto position = bit_stream->tell();
|
auto position = bit_stream->tell();
|
||||||
if (position.get_byte() != 4 || position.get_bit() != 0)
|
if (position.get_byte() != 4 || position.get_bit() != 0)
|
||||||
FAIL();
|
FAIL();
|
||||||
const auto size = position.get_byte();
|
const auto size = position.get_byte();
|
||||||
|
|
||||||
// Validate what we've got here with a hand-written sample
|
// Validate what we've got here with a hand-written sample
|
||||||
std::ifstream sample("samples/bitstream1.bin", std::ios::binary);
|
std::ifstream sample("samples/bitstream1.bin", std::ios::binary);
|
||||||
if (!sample.is_open())
|
if (!sample.is_open())
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|
||||||
// Load the sample data and compare
|
// Load the sample data and compare
|
||||||
auto *sample_data = new char[size + 1] { 0 };
|
auto *sample_data = new char[size + 1]{ 0 };
|
||||||
sample.read(sample_data, size);
|
sample.read(sample_data, size);
|
||||||
if (strcmp(sample_data, (char *)bit_stream->data()) != 0)
|
if (strcmp(sample_data, (char *)bit_stream->data()) != 0)
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|
||||||
// Free resources
|
// Free resources
|
||||||
delete bit_stream;
|
delete[] sample_data;
|
||||||
delete[] sample_data;
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Write bytes", "[bit-stream]")
|
SECTION("Writing values with a size greater than 8 bits")
|
||||||
{
|
{
|
||||||
auto *bit_stream = new BitStream();
|
// Write some values
|
||||||
|
bit_stream->write<uint8_t>(KI_TEST_BITSTREAM_U8, 8);
|
||||||
|
bit_stream->write<uint16_t>(KI_TEST_BITSTREAM_U16, 16);
|
||||||
|
bit_stream->write<uint32_t>(KI_TEST_BITSTREAM_U24, 24);
|
||||||
|
bit_stream->write<uint32_t>(KI_TEST_BITSTREAM_U32, 32);
|
||||||
|
bit_stream->write<uint64_t>(KI_TEST_BITSTREAM_U64, 64);
|
||||||
|
|
||||||
// Write an alternating pattern of bits
|
// Make sure tell is reporting the right position
|
||||||
bit_stream->write<uint8_t>(0x01, 8);
|
auto position = bit_stream->tell();
|
||||||
bit_stream->write<uint16_t>(0x0302, 16);
|
if (position.get_byte() != 18 || position.get_bit() != 0)
|
||||||
bit_stream->write<uint32_t>(0x060504, 24);
|
FAIL();
|
||||||
bit_stream->write<uint32_t>(0x0A090807, 32);
|
const auto size = position.get_byte();
|
||||||
bit_stream->write<uint64_t>(0x1211100F0E0D0C0BL, 64);
|
|
||||||
|
|
||||||
// Make sure tell is reporting the right position
|
// Validate what we've got here with a hand-written sample
|
||||||
auto position = bit_stream->tell();
|
std::ifstream sample("samples/bitstream2.bin", std::ios::binary);
|
||||||
if (position.get_byte() != 18 || position.get_bit() != 0)
|
if (!sample.is_open())
|
||||||
FAIL();
|
FAIL();
|
||||||
const auto size = position.get_byte();
|
|
||||||
|
|
||||||
// Validate what we've got here with a hand-written sample
|
// Load the sample data and compare
|
||||||
std::ifstream sample("samples/bitstream2.bin", std::ios::binary);
|
auto *sample_data = new char[size + 1]{ 0 };
|
||||||
if (!sample.is_open())
|
sample.read(sample_data, size);
|
||||||
FAIL();
|
if (strcmp(sample_data, (char *)bit_stream->data()) != 0)
|
||||||
|
FAIL();
|
||||||
|
|
||||||
// Load the sample data and compare
|
// Free resources
|
||||||
auto *sample_data = new char[size + 1]{ 0 };
|
delete[] sample_data;
|
||||||
sample.read(sample_data, size);
|
SUCCEED();
|
||||||
if (strcmp(sample_data, (char *)bit_stream->data()) != 0)
|
}
|
||||||
FAIL();
|
|
||||||
|
|
||||||
// Free resources
|
SECTION("Reading values with a size lower than 8 bits")
|
||||||
delete bit_stream;
|
{
|
||||||
delete[] sample_data;
|
// Open a previously hand-written sample
|
||||||
}
|
std::ifstream sample("samples/bitstream1.bin", std::ios::binary);
|
||||||
|
if (!sample.is_open())
|
||||||
|
FAIL();
|
||||||
|
|
||||||
TEST_CASE("Read bits", "[bit-stream]")
|
// Load the sample data into the bit stream
|
||||||
{
|
const auto begin = sample.tellg();
|
||||||
auto *bit_stream = new BitStream();
|
sample.seekg(0, std::ios::end);
|
||||||
|
const auto end = sample.tellg();
|
||||||
|
const size_t size = end - begin;
|
||||||
|
sample.seekg(std::ios::beg);
|
||||||
|
sample.read((char *)bit_stream->data(), size);
|
||||||
|
|
||||||
// Validate what we've got here with a hand-written sample
|
// Read the values and check they are what we are expecting
|
||||||
std::ifstream sample("samples/bitstream1.bin", std::ios::binary);
|
if (!KI_TEST_READ_BUI(1))
|
||||||
if (!sample.is_open())
|
FAIL();
|
||||||
FAIL();
|
if (!KI_TEST_READ_BUI(2))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(3))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(4))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(5))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(6))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(7))
|
||||||
|
FAIL();
|
||||||
|
if (!KI_TEST_READ_BUI(4))
|
||||||
|
FAIL();
|
||||||
|
|
||||||
// Load the sample data into the bit stream
|
SUCCEED();
|
||||||
const auto begin = sample.tellg();
|
}
|
||||||
sample.seekg(0, std::ios::end);
|
|
||||||
const auto end = sample.tellg();
|
|
||||||
const size_t size = end - begin;
|
|
||||||
sample.seekg(std::ios::beg);
|
|
||||||
sample.read((char *)bit_stream->data(), size);
|
|
||||||
|
|
||||||
// Read the values and check they are what we are expecting
|
SECTION("Reading values with a size greater than 8 bits")
|
||||||
if (bit_stream->read<uint8_t>(1) != 0b1)
|
{
|
||||||
FAIL();
|
// Open a previously hand-written sample
|
||||||
if (bit_stream->read<uint8_t>(2) != 0b10)
|
std::ifstream sample("samples/bitstream2.bin", std::ios::binary);
|
||||||
FAIL();
|
if (!sample.is_open())
|
||||||
if (bit_stream->read<uint8_t>(3) != 0b010)
|
FAIL();
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint8_t>(4) != 0b0101)
|
// Load the sample data into the bit stream
|
||||||
FAIL();
|
const auto begin = sample.tellg();
|
||||||
if (bit_stream->read<uint8_t>(5) != 0b10101)
|
sample.seekg(0, std::ios::end);
|
||||||
FAIL();
|
const auto end = sample.tellg();
|
||||||
if (bit_stream->read<uint8_t>(6) != 0b101010)
|
const size_t size = end - begin;
|
||||||
FAIL();
|
sample.seekg(std::ios::beg);
|
||||||
if (bit_stream->read<uint8_t>(7) != 0b0101010)
|
sample.read((char *)bit_stream->data(), size);
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint8_t>(4) != 0b0101)
|
// Read the values and check they are what we are expecting
|
||||||
FAIL();
|
if (bit_stream->read<uint8_t>(8) != KI_TEST_BITSTREAM_U8)
|
||||||
|
FAIL();
|
||||||
|
if (bit_stream->read<uint16_t>(16) != KI_TEST_BITSTREAM_U16)
|
||||||
|
FAIL();
|
||||||
|
if (bit_stream->read<uint32_t>(24) != KI_TEST_BITSTREAM_U24)
|
||||||
|
FAIL();
|
||||||
|
if (bit_stream->read<uint32_t>(32) != KI_TEST_BITSTREAM_U32)
|
||||||
|
FAIL();
|
||||||
|
if (bit_stream->read<uint64_t>(64) != KI_TEST_BITSTREAM_U64)
|
||||||
|
FAIL();
|
||||||
|
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Buffer underflow")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Attempt to set the position less than 0
|
||||||
|
bit_stream->seek(BitStream::stream_pos(-1, 0));
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
catch (std::runtime_error &e)
|
||||||
|
{
|
||||||
|
// An exception was thrown, which is intended behaviour
|
||||||
|
SUCCEED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Free resources
|
// Free resources
|
||||||
delete bit_stream;
|
delete bit_stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Read bytes", "[bit-stream]")
|
TEST_CASE("BitStream buffer expansion", "[bit-stream]")
|
||||||
{
|
{
|
||||||
auto *bit_stream = new BitStream();
|
// Create a very small buffer that we know is going to expand
|
||||||
|
auto *bit_stream = new BitStream(1);
|
||||||
|
|
||||||
// Validate what we've got here with a hand-written sample
|
// Write a byte, and then check if the capacity grows
|
||||||
std::ifstream sample("samples/bitstream2.bin", std::ios::binary);
|
bit_stream->write<uint8_t>(0x55, 8);
|
||||||
if (!sample.is_open())
|
if (bit_stream->capacity() != 6)
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|
||||||
// Load the sample data into the bit stream
|
// Go back to the first byte, and make sure what we wrote stuck
|
||||||
const auto begin = sample.tellg();
|
// around after the expansion
|
||||||
sample.seekg(0, std::ios::end);
|
bit_stream->seek(BitStream::stream_pos(0, 0));
|
||||||
const auto end = sample.tellg();
|
if (bit_stream->read<uint8_t>(8) != 0x55)
|
||||||
const size_t size = end - begin;
|
|
||||||
sample.seekg(std::ios::beg);
|
|
||||||
sample.read((char *)bit_stream->data(), size);
|
|
||||||
|
|
||||||
// Read the values and check they are what we are expecting
|
|
||||||
if (bit_stream->read<uint8_t>(8) != 0x01)
|
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint16_t>(16) != 0x0302)
|
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint32_t>(24) != 0x060504)
|
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint32_t>(32) != 0x0A090807)
|
|
||||||
FAIL();
|
|
||||||
if (bit_stream->read<uint64_t>(64) != 0x1211100F0E0D0C0BU)
|
|
||||||
FAIL();
|
FAIL();
|
||||||
|
|
||||||
// Free resources
|
// Free resources
|
||||||
delete bit_stream;
|
delete bit_stream;
|
||||||
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue