From 278f9f2135ab4ac0152e41f3320d60e024c4158a Mon Sep 17 00:00:00 2001 From: Ahmet Artu Yildirim Date: Thu, 22 Dec 2022 11:14:17 -0800 Subject: [PATCH] Add setter and getter functions for int array --- src/check_progbuf.c | 58 +++++++++++++++++++- src/common.h | 13 +++-- src/progbuf.c | 130 +++++++++++++++++++++++++++++++++++++++++--- src/progbuf.h | 6 ++ 4 files changed, 192 insertions(+), 15 deletions(-) diff --git a/src/check_progbuf.c b/src/check_progbuf.c index b02dcfa..cabfd60 100644 --- a/src/check_progbuf.c +++ b/src/check_progbuf.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "common.h" @@ -497,11 +498,62 @@ START_TEST (test_progbuf_write_read_double) ck_assert (ret == PROGBUF_SUCCESS); } +START_TEST (test_progbuf_write_read_int_array) +{ + progbuf_h buf = progbuf_alloc (1); + + ck_assert (buf); + + const int val[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + const size_t actual_size = sizeof (val) / sizeof (int); + + int ret = progbuf_set_int_array (buf, val, actual_size); + + ck_assert (ret == PROGBUF_SUCCESS); + + size_t size; + + ret = progbuf_buffer_size (buf, &size); + ck_assert (ret == PROGBUF_SUCCESS); + + ck_assert (size == 12); + + progbuf_it_h iter = progbuf_iter_alloc (buf); + + ck_assert (iter); + + int *p_val; + size_t p_size; + ret = progbuf_get_int_array (iter, &p_val, &p_size); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (p_val); + ck_assert (p_size == actual_size); + + for (int i = 0; i < actual_size; ++i) + { + ck_assert (val[i] == p_val[i]); + } + + struct progbuf_it_s *iter_internal = iter; + + ck_assert (iter_internal->read_pos == 12); + + free (p_val); + + ret = progbuf_iter_free (iter); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf); + ck_assert (ret == PROGBUF_SUCCESS); +} +END_TEST + static Suite * progbuf_suite (void) { Suite *s; - TCase *tc_basic, *tc_long, *tc_longlong, *tc_load, *tc_float; + TCase *tc_basic, *tc_long, *tc_longlong, *tc_load, *tc_float, *tc_array; s = suite_create ("progbuf test suite"); @@ -525,11 +577,15 @@ progbuf_suite (void) tcase_add_test (tc_float, test_progbuf_write_read_float); tcase_add_test (tc_float, test_progbuf_write_read_double); + tc_array = tcase_create ("encode_array"); + tcase_add_test (tc_array, test_progbuf_write_read_int_array); + suite_add_tcase (s, tc_basic); suite_add_tcase (s, tc_long); suite_add_tcase (s, tc_longlong); suite_add_tcase (s, tc_load); suite_add_tcase (s, tc_float); + suite_add_tcase (s, tc_array); return s; } diff --git a/src/common.h b/src/common.h index 5d63f7e..83cd8e9 100644 --- a/src/common.h +++ b/src/common.h @@ -5,13 +5,14 @@ #define ABS(N) ((N<0)?(-N):(N)) -#define PROGBUF_INIT_BUFSIZ 128 +#define PROGBUF_INIT_BUFSIZ 128 -#define PROGBUF_TYPE_VAR_INT 0x00 -#define PROGBUF_TYPE_FLOAT32 0x01 -#define PROGBUF_TYPE_FLOAT64 0x02 -#define PROGBUF_TYPE_BYTE 0x03 -#define PROGBUF_TYPE_ARRAY 0x04 +#define PROGBUF_TYPE_VAR_INT 0x01 +#define PROGBUF_TYPE_FLOAT32 0x02 +#define PROGBUF_TYPE_FLOAT64 0x03 +#define PROGBUF_TYPE_BYTE 0x04 +#define PROGBUF_TYPE_ARRAY 0x10 +#define PROGBUF_TYPE_VAR_INT_ARRAY 0x11 struct progbuf_s { diff --git a/src/progbuf.c b/src/progbuf.c index 56f17ec..2037e60 100644 --- a/src/progbuf.c +++ b/src/progbuf.c @@ -134,6 +134,10 @@ DETERMINE_VAR_SIZE (ulonglong) READ_VAR_SIZE (ulonglong) WRITE_VAR_SIZE (ulonglong) +DETERMINE_VAR_SIZE (size_t) +READ_VAR_SIZE (size_t) +WRITE_VAR_SIZE (size_t) + #define PROGBUF_SET(type, utype) \ int progbuf_set_##type (progbuf_h buf, type value) \ { \ @@ -158,7 +162,7 @@ WRITE_VAR_SIZE (ulonglong) return PROGBUF_SUCCESS; \ } -#define PROGBUF_GET(type, utype) \ +#define PROGBUF_GET(type, utype, type_signed) \ int progbuf_get_##type (progbuf_it_h iter, type *value) \ { \ if (!iter || !value) \ @@ -185,28 +189,138 @@ WRITE_VAR_SIZE (ulonglong) return PROGBUF_ERROR_READ; \ } \ \ - *value = (negative ? -u_value : u_value); \ + if (type_signed) \ + { \ + *value = (negative ? -u_value : u_value); \ + } \ + else \ + { \ + *value = u_value; \ + } \ \ return PROGBUF_SUCCESS; \ } PROGBUF_SET (int, uint) -PROGBUF_GET (int, uint) +PROGBUF_GET (int, uint, 1) PROGBUF_SET (uint, uint) -PROGBUF_GET (uint, uint) +PROGBUF_GET (uint, uint, 0) PROGBUF_SET (long, ulong) -PROGBUF_GET (long, ulong) +PROGBUF_GET (long, ulong, 1) PROGBUF_SET (ulong, ulong) -PROGBUF_GET (ulong, ulong) +PROGBUF_GET (ulong, ulong, 0) PROGBUF_SET (longlong, ulonglong) -PROGBUF_GET (longlong, ulonglong) +PROGBUF_GET (longlong, ulonglong, 1) PROGBUF_SET (ulonglong, ulonglong) -PROGBUF_GET (ulonglong, ulonglong) +PROGBUF_GET (ulonglong, ulonglong, 0) + +PROGBUF_SET (size_t, size_t) +PROGBUF_GET (size_t, size_t, 0) + +int +progbuf_set_int_array (progbuf_h buf, const int *arr, size_t len) +{ + int val_size, ret; + + if (!buf || !arr) + return PROGBUF_ERROR_NULL_PARAM; + + if (!buf->buffer) + return PROGBUF_ERROR_NOT_OWNING; + + val_size = determine_var_size_t_size (len); + ret = check_buffer_and_expand (buf, val_size + 1); + if (ret != 0) + return ret; + + buf->buffer[buf->size] = PROGBUF_TYPE_VAR_INT_ARRAY; + buf->size++; + + write_var_size_t (buf, len, val_size, 0); + size_t total_written = 1 + val_size; + + for (size_t i = 0; i < len; ++i) + { + int value = arr[i]; + val_size = determine_var_uint_size (ABS (value)); + ret = check_buffer_and_expand (buf, val_size); + + if (ret != 0) + { + buf->size -= total_written; + return ret; + } + + write_var_uint (buf, ABS (value), val_size, value < 0); + total_written += val_size; + } + + return PROGBUF_SUCCESS; +} + +int +progbuf_get_int_array (progbuf_it_h iter, int **arr, size_t *len) +{ + if (!iter || !arr || !len) + return PROGBUF_ERROR_NULL_PARAM; + + if (!iter->buf->buffer) + return PROGBUF_ERROR_NOT_OWNING; + + if (iter->read_pos >= iter->buf->size) + return PROGBUF_ERROR_END_OF_ITER; + + char val_type = iter->buf->buffer[iter->read_pos]; + + if ((val_type & PROGBUF_TYPE_VAR_INT_ARRAY) != PROGBUF_TYPE_VAR_INT_ARRAY) + return PROGBUF_ERROR_UNEXPECTED_TYPE; + + iter->read_pos++; + + size_t u_len; + size_t total_read = 1; + size_t prev_read_pos = iter->read_pos; + int negative; + if (read_var_size_t (iter, &u_len, &negative) != 0) + { + iter->read_pos -= total_read; + return PROGBUF_ERROR_READ; + } + + total_read += (iter->read_pos - prev_read_pos); + int *l_arr = malloc (sizeof (int) * u_len); + + if (!l_arr) + { + iter->read_pos -= total_read; + return PROGBUF_ERROR_MEM_ALLOC; + } + + uint u_value; + prev_read_pos = iter->read_pos; + for (size_t i = 0; i < u_len; ++i) + { + if (read_var_uint (iter, &u_value, &negative) != 0) + { + total_read += (iter->read_pos - prev_read_pos); + iter->read_pos -= total_read; + free (l_arr); + return PROGBUF_ERROR_READ; + } + + l_arr[i] = (negative ? -u_value : u_value); + } + + *arr = l_arr; + *len = u_len; + + return PROGBUF_SUCCESS; +} progbuf_h progbuf_alloc (long message_tag) diff --git a/src/progbuf.h b/src/progbuf.h index 0cff17c..43bb3de 100644 --- a/src/progbuf.h +++ b/src/progbuf.h @@ -39,12 +39,18 @@ int progbuf_get_longlong (progbuf_it_h iter, long long *value); int progbuf_set_ulonglong (progbuf_h buf, unsigned long long value); int progbuf_get_ulonglong (progbuf_it_h iter, unsigned long long *value); +int progbuf_set_size_t (progbuf_h buf, size_t value); +int progbuf_get_size_t (progbuf_it_h iter, size_t *value); + int progbuf_set_float (progbuf_h buf, float value); int progbuf_get_float (progbuf_it_h iter, float *value); int progbuf_set_double (progbuf_h buf, double value); int progbuf_get_double (progbuf_it_h iter, double *value); +int progbuf_set_int_array (progbuf_h buf, const int *arr, size_t len); +int progbuf_get_int_array (progbuf_it_h iter, int **arr, size_t *len); + progbuf_it_h progbuf_iter_alloc (progbuf_h buf); int progbuf_iter_free (progbuf_it_h iter); int progbuf_iter_reset (progbuf_it_h iter); -- 2.20.1