X-Git-Url: https://git.sesse.net/?p=fjl;a=blobdiff_plain;f=bitsource_test.c;fp=bitsource_test.c;h=2b5217ff91a283fee9c544430bf73271cb565cfc;hp=0000000000000000000000000000000000000000;hb=0b02847989970a190c2cfaec4d1abaa1f616284a;hpb=cc0c0e56d8269e91f23739b57faf67d5b5cc0794 diff --git a/bitsource_test.c b/bitsource_test.c new file mode 100644 index 0000000..2b5217f --- /dev/null +++ b/bitsource_test.c @@ -0,0 +1,130 @@ +#include +#include +#include +#include +#include + +#include "bitsource.h" + +struct custom_read_userdata { + uint8_t* bytes; + unsigned bytes_left; +}; + +ssize_t custom_read(void* userdata, uint8_t* buf, size_t count) +{ + struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata; + size_t num_to_read = (ud->bytes_left > count ? count : ud->bytes_left); + memcpy(buf, ud->bytes, num_to_read); + ud->bytes += num_to_read; + ud->bytes_left -= num_to_read; + return num_to_read; +} + +ssize_t custom_read_slow(void* userdata, uint8_t* buf, size_t count) +{ + struct custom_read_userdata* ud = (struct custom_read_userdata*)userdata; + size_t num_to_read = ((count > 0 && ud->bytes_left > 0) ? 1 : 0); + memcpy(buf, ud->bytes, num_to_read); + ud->bytes += num_to_read; + ud->bytes_left -= num_to_read; + return num_to_read; +} + +// Read 6 bits at a time. We should get 0b101010 every time. +void test_basic_reading() +{ + uint8_t bytes[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; + struct custom_read_userdata ud; + ud.bytes = bytes; + ud.bytes_left = sizeof(bytes); + + struct bit_source source; + init_bit_source(&source, custom_read, &ud); + + for (unsigned i = 0; i < sizeof(bytes) * 8 / 6; ++i) { + possibly_refill(&source, 6); + unsigned ret = read_bits(&source, 6); + assert(ret == 0x2a); + } + + assert(ud.bytes_left == 0); +} + +// Same, but with an input source that gives back only one byte at a time. +void test_slow_source() +{ + uint8_t bytes[] = { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }; + struct custom_read_userdata ud; + ud.bytes = bytes; + ud.bytes_left = sizeof(bytes); + + struct bit_source source; + init_bit_source(&source, custom_read_slow, &ud); + + for (unsigned i = 0; i < sizeof(bytes) * 8 / 6; ++i) { + possibly_refill(&source, 6); + unsigned ret = read_bits(&source, 6); + assert(ret == 0x2a); + } + + assert(ud.bytes_left == 0); +} + +// Read a few different bit sizes. +void test_variable_size() +{ + uint8_t bytes[] = { 0x12, 0x34, 0x56, 0x78, 0xff }; + struct custom_read_userdata ud; + ud.bytes = bytes; + ud.bytes_left = sizeof(bytes); + + struct bit_source source; + init_bit_source(&source, custom_read, &ud); + + { + possibly_refill(&source, 4); + unsigned ret = read_bits(&source, 1); + assert(ret == 0x0); + ret = read_bits(&source, 1); + assert(ret == 0x0); + ret = read_bits(&source, 1); + assert(ret == 0x0); + ret = read_bits(&source, 1); + assert(ret == 0x1); + } + { + possibly_refill(&source, 4); + unsigned ret = read_bits(&source, 4); + assert(ret == 0x2); + } + { + possibly_refill(&source, 12); + unsigned ret = read_bits(&source, 12); + assert(ret == 0x345); + } + { + possibly_refill(&source, 20); + unsigned ret = read_bits(&source, 16); + assert(ret == 0x678f); + ret = read_bits(&source, 4); + assert(ret == 0xf); + } + + assert(ud.bytes_left == 0); +} + +int main(void) +{ + printf("test_basic_reading()\n"); + test_basic_reading(); + + printf("test_slow_source()\n"); + test_slow_source(); + + printf("test_variable_size()\n"); + test_variable_size(); + + printf("All tests pass.\n"); + return 0; +}