#include "axl_memory.h" #include "axl_rle.h" #include "axl_koan.h" #define ASSERT_ARRAY_EQ(expected, actual, size) \ do { \ const u8* _e = (expected); \ const u8* _a = (actual); \ u32 _s = (size); \ for (u32 _i = 0; _i < _s; _i++) { \ if (_e[_i] != _a[_i]) { \ char _r[256]; \ snprintf(_r, sizeof(_r), "Mismatch at index %u: exp 0x%02X, got 0x%02X", \ _i, _e[_i], _a[_i]); \ KOAN_FAIL(_r); \ } \ } \ } while (0) KOAN(encode_empty) { u8 src[] = ""; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_encode(src, 0, dst, sizeof(dst))); } KOAN(encode_single) { u8 src[] = {0xAA}; u8 dst[32]; u32 size = axl_rle_encode(src, 1, dst, sizeof(dst)); ASSERT_UINT_EQ(2, size); ASSERT_UINT_EQ(0x01, dst[0]); ASSERT_UINT_EQ(0xAA, dst[1]); } KOAN(encode_five_repeats) { u8 src[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA}; u8 dst[32]; u32 size = axl_rle_encode(src, 5, dst, sizeof(dst)); ASSERT_UINT_EQ(2, size); ASSERT_UINT_EQ(0x05, dst[0]); ASSERT_UINT_EQ(0xAA, dst[1]); } KOAN(encode_three_runs) { u8 src[] = {0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xCC}; u8 expected[] = {0x03, 0xAA, 0x02, 0xBB, 0x01, 0xCC}; u8 dst[32]; u32 size = axl_rle_encode(src, 6, dst, sizeof(dst)); ASSERT_UINT_EQ(6, size); ASSERT_ARRAY_EQ(expected, dst, 6); } KOAN(encode_interleaved) { u8 src[] = {0xAA, 0xAA, 0xBB, 0xBB, 0xAA, 0xAA}; u8 expected[] = {0x02, 0xAA, 0x02, 0xBB, 0x02, 0xAA}; u8 dst[32]; u32 size = axl_rle_encode(src, 6, dst, sizeof(dst)); ASSERT_UINT_EQ(6, size); ASSERT_ARRAY_EQ(expected, dst, 6); } KOAN(encode_all_different) { u8 src[10]; u8 dst[32]; for (u32 i = 0; i < 10; i++) src[i] = (u8)i; u32 size = axl_rle_encode(src, 10, dst, sizeof(dst)); ASSERT_UINT_EQ(20, size); for (u32 i = 0; i < 10; i++) { ASSERT_UINT_EQ(0x01, dst[i*2]); ASSERT_UINT_EQ((u8)i, dst[i*2+1]); } } KOAN(encode_null_ptr) { u8 src[] = {0xAA}, dst[32]; ASSERT_UINT_EQ(0, axl_rle_encode(NULL, 1, dst, sizeof(dst))); ASSERT_UINT_EQ(0, axl_rle_encode(src, 1, NULL, 32)); } KOAN(encode_zero_size) { u8 src[] = {0xAA}; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_encode(src, 0, dst, sizeof(dst))); ASSERT_UINT_EQ(0, axl_rle_encode(src, 1, dst, 0)); } KOAN(encode_buffer_too_small) { u8 src[] = {0xAA, 0xAA, 0xAA, 0xBB}; u8 dst[3]; ASSERT_UINT_EQ(0, axl_rle_encode(src, 4, dst, sizeof(dst))); } KOAN(encode_max_127) { u8 src[127]; u8 dst[32]; for (u32 i = 0; i < 127; i++) src[i] = 0x77; u32 size = axl_rle_encode(src, 127, dst, sizeof(dst)); ASSERT_UINT_EQ(2, size); ASSERT_UINT_EQ(0x7F, dst[0]); ASSERT_UINT_EQ(0x77, dst[1]); } KOAN(encode_decode_300) { u8 src[300]; u8 encoded[32]; u8 decoded[400]; for (u32 i = 0; i < 300; i++) src[i] = 0x55; u32 encoded_size = axl_rle_encode(src, 300, encoded, sizeof(encoded)); ASSERT_TRUE(encoded_size > 0 && encoded_size <= 6); u32 decoded_size = axl_rle_decode(encoded, encoded_size, decoded, sizeof(decoded)); ASSERT_UINT_EQ(300, decoded_size); ASSERT_ARRAY_EQ(src, decoded, 300); } KOAN(decode_empty) { u8 src[] = ""; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 0, dst, sizeof(dst))); } KOAN(decode_single) { u8 src[] = {0x01, 0xAA}; u8 dst[32]; u32 size = axl_rle_decode(src, 2, dst, sizeof(dst)); ASSERT_UINT_EQ(1, size); ASSERT_UINT_EQ(0xAA, dst[0]); } KOAN(decode_five) { u8 src[] = {0x05, 0xAA}; u8 dst[32]; u32 size = axl_rle_decode(src, 2, dst, sizeof(dst)); ASSERT_UINT_EQ(5, size); for (u32 i = 0; i < 5; i++) ASSERT_UINT_EQ(0xAA, dst[i]); } KOAN(decode_three_runs) { u8 src[] = {0x03, 0xAA, 0x02, 0xBB, 0x01, 0xCC}; u8 expected[] = {0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xCC}; u8 dst[32]; u32 size = axl_rle_decode(src, 6, dst, sizeof(dst)); ASSERT_UINT_EQ(6, size); ASSERT_ARRAY_EQ(expected, dst, 6); } KOAN(decode_null_ptr) { u8 src[] = {0x01, 0xAA}, dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(NULL, 2, dst, sizeof(dst))); ASSERT_UINT_EQ(0, axl_rle_decode(src, 2, NULL, 32)); } KOAN(decode_zero_size) { u8 src[] = {0x01, 0xAA}; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 0, dst, sizeof(dst))); ASSERT_UINT_EQ(0, axl_rle_decode(src, 2, dst, 0)); } KOAN(decode_buffer_too_small) { u8 src[] = {0x05, 0xAA}; u8 dst[3]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 2, dst, sizeof(dst))); } KOAN(decode_incomplete_vlq) { u8 src[] = {0x85}; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 1, dst, sizeof(dst))); } KOAN(decode_missing_value) { u8 src[] = {0x05}; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 1, dst, sizeof(dst))); } KOAN(decode_zero_count) { u8 src[] = {0x00, 0xAA}; u8 dst[32]; ASSERT_UINT_EQ(0, axl_rle_decode(src, 2, dst, sizeof(dst))); } KOAN(roundtrip_simple) { u8 original[] = {0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xCC}; u8 encoded[32]; u8 decoded[32]; u32 encoded_size = axl_rle_encode(original, 9, encoded, sizeof(encoded)); ASSERT_TRUE(encoded_size > 0); u32 decoded_size = axl_rle_decode(encoded, encoded_size, decoded, sizeof(decoded)); ASSERT_UINT_EQ(9, decoded_size); ASSERT_ARRAY_EQ(original, decoded, 9); } KOAN(roundtrip_all_different) { u8 original[10]; u8 encoded[32]; u8 decoded[32]; for (u32 i = 0; i < 10; i++) original[i] = (u8)i; u32 encoded_size = axl_rle_encode(original, 10, encoded, sizeof(encoded)); ASSERT_UINT_EQ(20, encoded_size); u32 decoded_size = axl_rle_decode(encoded, encoded_size, decoded, sizeof(decoded)); ASSERT_UINT_EQ(10, decoded_size); ASSERT_ARRAY_EQ(original, decoded, 10); } int main(void) { axl_init(); return koan_run_all(); }