diff --git a/axl.h b/axl.h index 844aefd..f3a5989 100644 --- a/axl.h +++ b/axl.h @@ -5,5 +5,6 @@ #include "axl_memory.h" #include "axl_string.h" #include "axl_io.h" +#include "axl_vlq.h" #endif diff --git a/axl_vlq.c b/axl_vlq.c new file mode 100644 index 0000000..dca140e --- /dev/null +++ b/axl_vlq.c @@ -0,0 +1,57 @@ +#include "axl_vlq.h" + +u32 axl_vlq_encode(u32 num, u8* out) +{ + u8 buf[5]; + int pos = 0; + + if(num == 0) + { + out[0] = 0; + return 1; + } + + while(num > 0) + { + buf[pos] = num & 0x7F; + num >>= 7; + pos++; + } + + for(int j = pos - 1; j > 0; j--) + { + buf[j] |= 0x80; + } + + for(int j = pos - 1; j >= 0; j--) + { + *out++ = buf[j]; + } + + return pos; +} + +u32 axl_vlq_decode(const u8* in, u32* num) +{ + *num = 0; + u32 pos = 0; + + while(pos < AXL_VLQ_MAX_LEN) + { + u8 b = in[pos++]; + + *num = (*num << 7) | (b & 0x7F); + + if(!(b & 0x80)) + { + return pos; + } + + if(*num > (U32_MAX >> 7)) + { + return 0; + } + } + + return 0; //incomplete +} diff --git a/axl_vlq.h b/axl_vlq.h new file mode 100644 index 0000000..10126d5 --- /dev/null +++ b/axl_vlq.h @@ -0,0 +1,11 @@ +#ifndef AXL_VLQ_H +#define AXL_VLQ_H + +#include "axl_types.h" + +#define AXL_VLQ_MAX_LEN 5 + +u32 axl_vlq_encode(u32 num, u8* out); +u32 axl_vlq_decode(const u8* in, u32* num); + +#endif // !AXL_VLQ_H diff --git a/axl_vlq_test.c b/axl_vlq_test.c new file mode 100644 index 0000000..5ada1cc --- /dev/null +++ b/axl_vlq_test.c @@ -0,0 +1,30 @@ +#include "axl_koan.h" +#include "axl_memory.h" +#include "axl_types.h" +#include "axl_vlq.h" + +KOAN(vlq_basic_encode_decode) +{ + u32 expected[] = {0, 126, 129, 256, 65535, 70000, 9999999, U32_MAX}; + u32 expected_len[] = {1, 1, 2, 2, 3, 3, 4, 5 }; + + u8 encoded[AXL_VLQ_MAX_LEN]; + + for(u32 i = 0; i < sizeof(expected) / sizeof(expected[0]); i++) + { + u32 encoded_len = axl_vlq_encode(expected[i], encoded); + + u32 decoded = 0; + u32 decoded_len = axl_vlq_decode(encoded, &decoded); + + ASSERT_UINT_EQ(expected_len[i], encoded_len); + ASSERT_UINT_EQ(expected_len[i], decoded_len); + ASSERT_UINT_EQ(expected[i], decoded); + } +} + +int main(void) +{ + axl_init(); + return koan_run_all(); +} diff --git a/main.c b/main.c index 71d97ca..45d3edb 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ #include "axl.h" +#include "axl_vlq.h" #include int _start(void) @@ -29,5 +30,19 @@ int _start(void) (void)fds; (void)f; + + u8 src[] = "Bonjour le monde!"; + u32 src_len = axl_strlen((i8*)src); + for(u32 i = 0; i < src_len; i += 4) + { + u8 buff[AXL_VLQ_MAX_LEN + 1]; + + u32 encoded_l = axl_vlq_encode(*((u32*)(src + i)), buff); + + buff[encoded_l] = '\0'; + + axl_puts((i8*)buff); + } + return 0; }