diff --git a/test/samples/bitstream1.bin b/test/samples/bitstream1.bin index 9e6a9ab..416ba1f 100644 --- a/test/samples/bitstream1.bin +++ b/test/samples/bitstream1.bin @@ -1 +1 @@ -UUUU \ No newline at end of file +UUUU­Vµª \ No newline at end of file diff --git a/test/samples/bitstream2.bin b/test/samples/bitstream2.bin index 5f6afee..a298e2b 100644 Binary files a/test/samples/bitstream2.bin and b/test/samples/bitstream2.bin differ diff --git a/test/src/unit-bitstream.cpp b/test/src/unit-bitstream.cpp index 5e61221..4f56500 100644 --- a/test/src/unit-bitstream.cpp +++ b/test/src/unit-bitstream.cpp @@ -12,15 +12,29 @@ #define KI_TEST_BITSTREAM_BUI5 0b10101 #define KI_TEST_BITSTREAM_BUI6 0b101010 #define KI_TEST_BITSTREAM_BUI7 0b0101010 +#define KI_TEST_BITSTREAM_BI1 -1 +#define KI_TEST_BITSTREAM_BI2 -2 +#define KI_TEST_BITSTREAM_BI3 -3 +#define KI_TEST_BITSTREAM_BI4 -6 +#define KI_TEST_BITSTREAM_BI5 -11 +#define KI_TEST_BITSTREAM_BI6 -22 +#define KI_TEST_BITSTREAM_BI7 -43 #define KI_TEST_BITSTREAM_BOOL true #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_BITSTREAM_I8 -8 +#define KI_TEST_BITSTREAM_I16 -2048 +#define KI_TEST_BITSTREAM_I24 -524288 +#define KI_TEST_BITSTREAM_I32 -134217728 +#define KI_TEST_BITSTREAM_I64 -576460752303423488L #define KI_TEST_WRITE_BUI(n) bit_stream.write>(KI_TEST_BITSTREAM_BUI##n) #define KI_TEST_READ_BUI(n) bit_stream.read>() == KI_TEST_BITSTREAM_BUI##n +#define KI_TEST_WRITE_BI(n) bit_stream.write>(KI_TEST_BITSTREAM_BI##n) +#define KI_TEST_READ_BI(n) bit_stream.read>() == KI_TEST_BITSTREAM_BI##n using namespace ki; @@ -30,16 +44,48 @@ TEST_CASE("BitStream::stream_pos Functionality", "[bit-stream]") SECTION("Increment single bit") { - ++position; + const auto position1 = ++position; REQUIRE(position.get_byte() == 1); REQUIRE(position.get_bit() == 5); + REQUIRE(position1.get_byte() == 1); + REQUIRE(position1.get_bit() == 5); + + const auto position2 = position++; + REQUIRE(position.get_byte() == 1); + REQUIRE(position.get_bit() == 6); + REQUIRE(position2.get_byte() == 1); + REQUIRE(position2.get_bit() == 5); + + const auto position3 = position + 1; + REQUIRE(position3.get_byte() == 1); + REQUIRE(position3.get_bit() == 7); + + const auto position4 = position + BitStream::stream_pos(0, 1); + REQUIRE(position4.get_byte() == 1); + REQUIRE(position4.get_bit() == 7); } SECTION("Decrement single bit") { - --position; + const auto position1 = --position; REQUIRE(position.get_byte() == 1); REQUIRE(position.get_bit() == 3); + REQUIRE(position1.get_byte() == 1); + REQUIRE(position1.get_bit() == 3); + + const auto position2 = position--; + REQUIRE(position.get_byte() == 1); + REQUIRE(position.get_bit() == 2); + REQUIRE(position2.get_byte() == 1); + REQUIRE(position2.get_bit() == 3); + + const auto position3 = position - 1; + REQUIRE(position3.get_byte() == 1); + REQUIRE(position3.get_bit() == 1); + + const auto position4 = position - BitStream::stream_pos(0, 1); + REQUIRE(position4.get_byte() == 1); + REQUIRE(position4.get_bit() == 1); } SECTION("Increment bits and move to next byte") @@ -69,6 +115,66 @@ TEST_CASE("BitStream::stream_pos Functionality", "[bit-stream]") REQUIRE(position.get_byte() == 0); REQUIRE(position.get_bit() == 4); } + + SECTION("As number of bytes") + { + REQUIRE(position.as_bytes() == 2); + position -= 4; + REQUIRE(position.as_bytes() == 1); + } + + SECTION("As number of bits") + { + REQUIRE(position.as_bits() == 12); + position -= 4; + REQUIRE(position.as_bits() == 8); + } +} + +TEST_CASE("BitBuffer Functionality", "[bit-stream]") +{ + BitBuffer bit_buffer(1); + + SECTION("Create valid segment") + { + auto *segment = bit_buffer.segment( + BitBuffer::buffer_pos(0, 0), 8 + ); + REQUIRE(segment->size() == 1); + delete segment; + } + + SECTION("Create invalid segment (invalid position)") + { + try + { + auto *segment = bit_buffer.segment( + BitBuffer::buffer_pos(1, 0), 8 + ); + delete segment; + FAIL(); + } + catch (runtime_error &e) + { + SUCCEED(); + } + } + + SECTION("Create invalid segment (invalid size)") + { + try + { + auto *segment = bit_buffer.segment( + BitBuffer::buffer_pos(0, 0), 16 + ); + delete segment; + FAIL(); + } + catch (runtime_error &e) + { + SUCCEED(); + } + } } TEST_CASE("BitStream Functionality", "[bit-stream]") @@ -88,9 +194,19 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") KI_TEST_WRITE_BUI(7); KI_TEST_WRITE_BUI(4); + // Write signed values + KI_TEST_WRITE_BI(1); + KI_TEST_WRITE_BI(2); + KI_TEST_WRITE_BI(3); + KI_TEST_WRITE_BI(4); + KI_TEST_WRITE_BI(5); + KI_TEST_WRITE_BI(6); + KI_TEST_WRITE_BI(7); + KI_TEST_WRITE_BI(4); + // Make sure tell is reporting the right position auto position = bit_stream.tell(); - REQUIRE(position.get_byte() == 4); + REQUIRE(position.get_byte() == 8); REQUIRE(position.get_bit() == 0); const auto size = position.get_byte(); @@ -110,7 +226,7 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") SECTION("Writing values with a size greater than 8 bits") { - // Write some values + // Write unsigned values bit_stream.write(KI_TEST_BITSTREAM_BOOL); bit_stream.write(KI_TEST_BITSTREAM_U8); bit_stream.write(KI_TEST_BITSTREAM_U16); @@ -118,9 +234,16 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") bit_stream.write(KI_TEST_BITSTREAM_U32); bit_stream.write(KI_TEST_BITSTREAM_U64); + // Write signed values + bit_stream.write(KI_TEST_BITSTREAM_I8); + bit_stream.write(KI_TEST_BITSTREAM_I16); + bit_stream.write>(KI_TEST_BITSTREAM_I24); + bit_stream.write(KI_TEST_BITSTREAM_I32); + bit_stream.write(KI_TEST_BITSTREAM_I64); + // Make sure tell is reporting the right position auto position = bit_stream.tell(); - REQUIRE(position.get_byte() == 19); + REQUIRE(position.get_byte() == 37); REQUIRE(position.get_bit() == 0); const auto size = position.get_byte(); @@ -154,6 +277,7 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") sample.read(stream_data, size); // Read the values and check they are what we are expecting + // Unsigned values REQUIRE(KI_TEST_READ_BUI(1)); REQUIRE(KI_TEST_READ_BUI(2)); REQUIRE(KI_TEST_READ_BUI(3)); @@ -162,6 +286,16 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") REQUIRE(KI_TEST_READ_BUI(6)); REQUIRE(KI_TEST_READ_BUI(7)); REQUIRE(KI_TEST_READ_BUI(4)); + + // Signed values + REQUIRE(KI_TEST_READ_BI(1)); + REQUIRE(KI_TEST_READ_BI(2)); + REQUIRE(KI_TEST_READ_BI(3)); + REQUIRE(KI_TEST_READ_BI(4)); + REQUIRE(KI_TEST_READ_BI(5)); + REQUIRE(KI_TEST_READ_BI(6)); + REQUIRE(KI_TEST_READ_BI(7)); + REQUIRE(KI_TEST_READ_BI(4)); } SECTION("Reading values with a size greater than 8 bits") @@ -180,18 +314,47 @@ TEST_CASE("BitStream Functionality", "[bit-stream]") sample.read(stream_data, size); // Read the values and check they are what we are expecting + // Unsigned values REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_BOOL); REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_U8); REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_U16); REQUIRE(bit_stream.read>() == KI_TEST_BITSTREAM_U24); REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_U32); REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_U64); + + // Signed values + REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_I8); + REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_I16); + REQUIRE(bit_stream.read>() == KI_TEST_BITSTREAM_I24); + REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_I32); + REQUIRE(bit_stream.read() == KI_TEST_BITSTREAM_I64); + } + + SECTION("Copying memory in/out of the stream") + { + // Copy the string into the stream + char *str = "Hello, world!"; + const auto size = bitsizeof::value * (strlen(str) + 1); + bit_stream.write_copy(reinterpret_cast(str), size); + + // Copy the string from the stream into a new buffer + auto *str_copy = new char[size]; + bit_stream.seek(BitStream::stream_pos(0, 0)); + bit_stream.read_copy(reinterpret_cast(str_copy), size); + REQUIRE(strcmp(str, str_copy) == 0); + + delete[] str_copy; } SECTION("Overwriting values") { - bit_stream.write>(0b11); + bit_stream.write>(0b0011); bit_stream.seek(BitStream::stream_pos(0, 0)); + bit_stream.write>(0b1100); + bit_stream.seek(BitStream::stream_pos(0, 0)); + REQUIRE( + static_cast(bit_stream.read>()) == 0b1100 + ); } } @@ -211,8 +374,18 @@ TEST_CASE("BitStream buffer expansion", "[bit-stream]") REQUIRE(bit_stream.read(8) == 0x55); } -/** -* TODO: Test reading outside of buffer (should throw) -* TODO: Test read/write copy on BitStream -* TODO: Test BitStreamSection -*/ +TEST_CASE("BitStream read overflow", "[bit-stream]") +{ + // Create a 1-byte large buffer, and attempt to read a 32-bit value + auto bit_buffer = BitBuffer(1); + auto bit_stream = BitStream(bit_buffer); + try + { + bit_stream.read(); + FAIL(); + } + catch (runtime_error &e) + { + SUCCEED(); + } +}