diff --git a/array/array_test.c b/array/array_test.c index 715085c..f11aa25 100644 --- a/array/array_test.c +++ b/array/array_test.c @@ -75,6 +75,39 @@ static void test1(void) sc_array_destroy(arr); } +void bounds_test() +{ + int *arr, total = 0; + int val; + + sc_array_create(arr, 2); + sc_array_add(arr, 3); + sc_array_add(arr, 4); + + sc_array_foreach (arr, val) { + total += val; + } + + assert(total == 7); + + sc_array_destroy(arr); + + total = 0; + + sc_array_create(arr, 0); + sc_array_foreach (arr, val) { + total += val; + } + + sc_array_foreach (arr, val) { + total += val; + } + + assert(total == 0); + + sc_array_destroy(arr); +} + #ifdef SC_HAVE_WRAP bool fail_realloc = false; @@ -175,39 +208,6 @@ void fail_test() sc_array_destroy(arr); } -void bounds_test() -{ - int *arr, total = 0; - int val; - - sc_array_create(arr, 2); - sc_array_add(arr, 3); - sc_array_add(arr, 4); - - sc_array_foreach (arr, val) { - total += val; - } - - assert(total == 7); - - sc_array_destroy(arr); - - total = 0; - - sc_array_create(arr, 0); - sc_array_foreach (arr, val) { - total += val; - } - - sc_array_foreach (arr, val) { - total += val; - } - - assert(total == 0); - - sc_array_destroy(arr); -} - #else void fail_test(void) { diff --git a/buffer/README.md b/buffer/README.md new file mode 100644 index 0000000..41841c0 --- /dev/null +++ b/buffer/README.md @@ -0,0 +1,64 @@ +# Generic array + +#### Overview + +- Buffer implementation for serializing data/protocol implementation. +- Provides put/get for binary data, 8/16/32/64 bit integers, double and strings. +- Strings are kept length prefixed and null ended. So, no need to copy string + when you are reading, you just get the pointer. This is useful to avoid memory + allocation overhead. +- Integer operations are compiled into bounds check + a single MOV instruction + on x86. Buffer keeps data in Little Endian format, so on big endian systems, + integer put/get is bswap(byte swap) + MOV. +- Just copy sc_buf.h and sc_buf.c to your project. + + +##### Usage + +```c +#include "sc_buf.h" +#include + +void basic() +{ + struct sc_buf buf; + sc_buf_init(&buf, 1024); + + sc_buf_put_32(&buf, 16); + sc_buf_put_str(&buf, "test"); + sc_buf_put_fmt(&buf, "value is %d", 3); + + printf("%d \n", sc_buf_get_32(&buf)); + printf("%s \n", sc_buf_get_str(&buf)); + printf("%s \n", sc_buf_get_str(&buf)); + + sc_buf_term(&buf); +} + +void error_check() +{ + uint32_t val, val2; + struct sc_buf buf; + + sc_buf_init(&buf, 1024); + sc_buf_put_32(&buf, 16); + + val = sc_buf_get_32(&buf); + val2 = sc_buf_get_32(&buf); // This will set error flag in buffer; + + if (sc_buf_valid(&buf) == false) { + printf("buffer is corrupt"); + exit(EXIT_FAILURE); + } + + sc_buf_term(&buf); +} + +int main() +{ + basic(); + error_check(); + + return 0; +} +``` \ No newline at end of file diff --git a/buffer/buf_example.c b/buffer/buf_example.c index 905869d..96236ae 100644 --- a/buffer/buf_example.c +++ b/buffer/buf_example.c @@ -1,4 +1,45 @@ +#include "sc_buf.h" +#include + +void basic() +{ + struct sc_buf buf; + sc_buf_init(&buf, 1024); + + sc_buf_put_32(&buf, 16); + sc_buf_put_str(&buf, "test"); + sc_buf_put_fmt(&buf, "value is %d", 3); + + printf("%d \n", sc_buf_get_32(&buf)); + printf("%s \n", sc_buf_get_str(&buf)); + printf("%s \n", sc_buf_get_str(&buf)); + + sc_buf_term(&buf); +} + +void error_check() +{ + uint32_t val, val2; + struct sc_buf buf; + + sc_buf_init(&buf, 1024); + sc_buf_put_32(&buf, 16); + + val = sc_buf_get_32(&buf); + val2 = sc_buf_get_32(&buf); // This will set error flag in buffer; + + if (sc_buf_valid(&buf) == false) { + printf("buffer is corrupt"); + exit(EXIT_FAILURE); + } + + sc_buf_term(&buf); +} + int main() { + basic(); + error_check(); + return 0; } diff --git a/buffer/sc_buf.h b/buffer/sc_buf.h index 3169d4a..c6eb5db 100644 --- a/buffer/sc_buf.h +++ b/buffer/sc_buf.h @@ -40,8 +40,8 @@ struct sc_buf uint32_t limit; uint32_t rpos; uint32_t wpos; - unsigned int error; + unsigned int error; bool ref; };