From aee0a1b998b3396637a4a3b9e24a5c8226f5b28b Mon Sep 17 00:00:00 2001 From: Ahmet Artu Yildirim Date: Fri, 23 Dec 2022 13:41:50 -0800 Subject: [PATCH] Add string getter and setter; improve float and double functions --- src/check_progbuf.c | 152 ++++++++++++++++++++++++++++++++++++++++++++ src/common.h | 3 +- src/progbuf.c | 136 +++++++++++++++++++++++++-------------- src/progbuf.h | 3 + 4 files changed, 245 insertions(+), 49 deletions(-) diff --git a/src/check_progbuf.c b/src/check_progbuf.c index ac77653..663e12d 100644 --- a/src/check_progbuf.c +++ b/src/check_progbuf.c @@ -550,6 +550,155 @@ START_TEST (test_progbuf_write_read_int_array) } END_TEST +START_TEST (test_progbuf_write_read_float_array) +{ + progbuf_h buf = progbuf_alloc (1); + + ck_assert (buf); + + const float val[] = { FLT_MIN, FLT_MAX }; + const size_t actual_size = 2; + + int ret = progbuf_set_float_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 == 11); + + progbuf_it_h iter = progbuf_iter_alloc (buf); + + ck_assert (iter); + + float *p_val; + size_t p_size; + ret = progbuf_get_float_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 == 11); + + free (p_val); + + ret = progbuf_iter_free (iter); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf); + ck_assert (ret == PROGBUF_SUCCESS); +} +END_TEST + +START_TEST (test_progbuf_write_read_double_array) +{ + progbuf_h buf = progbuf_alloc (1); + + ck_assert (buf); + + const double val[] = { DBL_MIN, DBL_MAX }; + const size_t actual_size = 2; + + int ret = progbuf_set_double_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 == 19); + + progbuf_it_h iter = progbuf_iter_alloc (buf); + + ck_assert (iter); + + double *p_val; + size_t p_size; + ret = progbuf_get_double_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 == 19); + + free (p_val); + + ret = progbuf_iter_free (iter); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf); + ck_assert (ret == PROGBUF_SUCCESS); +} +END_TEST + +START_TEST (test_progbuf_write_read_string) +{ + progbuf_h buf = progbuf_alloc (1); + + ck_assert (buf); + + const char *val = "abcdefghij"; + const size_t actual_size = 10; + + int ret = progbuf_set_string (buf, val); + + ck_assert (ret == PROGBUF_SUCCESS); + + size_t size; + + ret = progbuf_buffer_size (buf, &size); + ck_assert (ret == PROGBUF_SUCCESS); + + ck_assert (size == actual_size + 1 + 3); + + progbuf_it_h iter = progbuf_iter_alloc (buf); + + ck_assert (iter); + + char *p_val; + size_t p_size; + ret = progbuf_get_string (iter, &p_val); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (p_val); + ck_assert (strlen (val) == strlen (p_val)); + ck_assert (strcmp (val, p_val) == 0); + + struct progbuf_it_s *iter_internal = iter; + + ck_assert (iter_internal->read_pos == actual_size + 1 + 3); + + free (p_val); + + ret = progbuf_iter_free (iter); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf); + ck_assert (ret == PROGBUF_SUCCESS); +} +END_TEST + START_TEST (test_progbuf_write_read_multiple_arrays) { progbuf_h buf = progbuf_alloc (1); @@ -667,6 +816,9 @@ progbuf_suite (void) tc_array = tcase_create ("encode_array"); tcase_add_test (tc_array, test_progbuf_write_read_int_array); + tcase_add_test (tc_array, test_progbuf_write_read_float_array); + tcase_add_test (tc_array, test_progbuf_write_read_double_array); + tcase_add_test (tc_array, test_progbuf_write_read_string); tcase_add_test (tc_array, test_progbuf_write_read_multiple_arrays); suite_add_tcase (s, tc_basic); diff --git a/src/common.h b/src/common.h index a1f6b66..9e84a27 100644 --- a/src/common.h +++ b/src/common.h @@ -10,11 +10,12 @@ #define PROGBUF_TYPE_VAR_INT 0x01 #define PROGBUF_TYPE_FLOAT32 0x02 #define PROGBUF_TYPE_FLOAT64 0x03 -#define PROGBUF_TYPE_BYTE 0x04 +#define PROGBUF_TYPE_CHAR 0x04 #define PROGBUF_TYPE_ARRAY 0x10 #define PROGBUF_TYPE_VAR_INT_ARRAY 0x11 #define PROGBUF_TYPE_VAR_FLOAT32_ARRAY 0x12 #define PROGBUF_TYPE_VAR_FLOAT64_ARRAY 0x13 +#define PROGBUF_TYPE_STRING 0x14 struct progbuf_s { diff --git a/src/progbuf.c b/src/progbuf.c index a696628..81a7f95 100644 --- a/src/progbuf.c +++ b/src/progbuf.c @@ -506,7 +506,8 @@ progbuf_set_float_array (progbuf_h buf, const float *arr, size_t len) return PROGBUF_ERROR_NOT_OWNING; val_size = determine_var_size_t_size (len); - ret = check_buffer_and_expand (buf, val_size + 1); + const size_t len_bytes = len * sizeof (float); + ret = check_buffer_and_expand (buf, 1 + val_size + len_bytes); if (ret != 0) return ret; @@ -514,21 +515,8 @@ progbuf_set_float_array (progbuf_h buf, const float *arr, size_t len) buf->size++; write_var_size_t (buf, len, val_size, 0); - - for (size_t i = 0; i < len; ++i) - { - float value = arr[i]; - ret = check_buffer_and_expand (buf, 4); - - if (ret != 0) - { - buf->size -= (1 + val_size + (i * 4)); - return ret; - } - - memcpy (buf->buffer + buf->size, &value, 4); - buf->size += 4; - } + memcpy (buf->buffer + buf->size, arr, len_bytes); + buf->size += len_bytes; return PROGBUF_SUCCESS; } @@ -562,7 +550,8 @@ progbuf_get_float_array (progbuf_it_h iter, float **arr, size_t *len) return PROGBUF_ERROR_READ; } - float *l_arr = malloc (sizeof (float) * u_len); + const size_t len_bytes = u_len * sizeof (float); + float *l_arr = malloc (len_bytes); if (!l_arr) { @@ -570,13 +559,8 @@ progbuf_get_float_array (progbuf_it_h iter, float **arr, size_t *len) return PROGBUF_ERROR_MEM_ALLOC; } - float value; - for (size_t i = 0; i < u_len; ++i) - { - memcpy (&value, iter->buf->buffer + iter->read_pos, 4); - l_arr[i] = value; - iter->read_pos += 4; - } + memcpy (l_arr, iter->buf->buffer + iter->read_pos, len_bytes); + iter->read_pos += len_bytes; *arr = l_arr; *len = u_len; @@ -596,7 +580,8 @@ progbuf_set_double_array (progbuf_h buf, const double *arr, size_t len) return PROGBUF_ERROR_NOT_OWNING; val_size = determine_var_size_t_size (len); - ret = check_buffer_and_expand (buf, val_size + 1); + const size_t len_bytes = len * sizeof (double); + ret = check_buffer_and_expand (buf, 1 + val_size + len_bytes); if (ret != 0) return ret; @@ -604,21 +589,8 @@ progbuf_set_double_array (progbuf_h buf, const double *arr, size_t len) buf->size++; write_var_size_t (buf, len, val_size, 0); - - for (size_t i = 0; i < len; ++i) - { - double value = arr[i]; - ret = check_buffer_and_expand (buf, 8); - - if (ret != 0) - { - buf->size -= (1 + val_size + (i * 8)); - return ret; - } - - memcpy (buf->buffer + buf->size, &value, 8); - buf->size += 8; - } + memcpy (buf->buffer + buf->size, arr, len_bytes); + buf->size += len_bytes; return PROGBUF_SUCCESS; } @@ -652,7 +624,8 @@ progbuf_get_double_array (progbuf_it_h iter, double **arr, size_t *len) return PROGBUF_ERROR_READ; } - double *l_arr = malloc (sizeof (double) * u_len); + const size_t len_bytes = u_len * sizeof (double); + double *l_arr = malloc (len_bytes); if (!l_arr) { @@ -660,13 +633,8 @@ progbuf_get_double_array (progbuf_it_h iter, double **arr, size_t *len) return PROGBUF_ERROR_MEM_ALLOC; } - double value; - for (size_t i = 0; i < u_len; ++i) - { - memcpy (&value, iter->buf->buffer + iter->read_pos, 8); - l_arr[i] = value; - iter->read_pos += 8; - } + memcpy (l_arr, iter->buf->buffer + iter->read_pos, len_bytes); + iter->read_pos += len_bytes; *arr = l_arr; *len = u_len; @@ -674,6 +642,78 @@ progbuf_get_double_array (progbuf_it_h iter, double **arr, size_t *len) return PROGBUF_SUCCESS; } +int +progbuf_set_string (progbuf_h buf, const char *str) +{ + int val_size, ret; + + if (!buf || !str) + return PROGBUF_ERROR_NULL_PARAM; + + if (!buf->buffer) + return PROGBUF_ERROR_NOT_OWNING; + + size_t len = strlen (str) + 1; + val_size = determine_var_size_t_size (len); + ret = check_buffer_and_expand (buf, 1 + val_size + len); + if (ret != 0) + return ret; + + buf->buffer[buf->size] = PROGBUF_TYPE_STRING; + buf->size++; + + write_var_size_t (buf, len, val_size, 0); + + memcpy (buf->buffer + buf->size, str, len); + buf->size += len; + + return PROGBUF_SUCCESS; +} + +int +progbuf_get_string (progbuf_it_h iter, char **str) +{ + if (!iter || !str) + 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_STRING) != PROGBUF_TYPE_STRING) + return PROGBUF_ERROR_UNEXPECTED_TYPE; + + iter->read_pos++; + + size_t str_len; + size_t prev_read_pos = iter->read_pos; + int negative; + if (read_var_size_t (iter, &str_len, &negative) != 0) + { + iter->read_pos--; + return PROGBUF_ERROR_READ; + } + + char *str_buf = malloc (str_len); + + if (!str_buf) + { + iter->read_pos -= (1 + iter->read_pos - prev_read_pos); + return PROGBUF_ERROR_MEM_ALLOC; + } + + memcpy (str_buf, iter->buf->buffer + iter->read_pos, str_len); + iter->read_pos += str_len; + + *str = str_buf; + + return PROGBUF_SUCCESS; +} + progbuf_h progbuf_alloc (long message_tag) { diff --git a/src/progbuf.h b/src/progbuf.h index 0344c7b..361d7ef 100644 --- a/src/progbuf.h +++ b/src/progbuf.h @@ -48,6 +48,9 @@ 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_string (progbuf_h buf, const char *str); +int progbuf_get_string (progbuf_it_h iter, char **str); + 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); int progbuf_set_uint_array (progbuf_h buf, const unsigned int *arr, size_t len); -- 2.20.1