Add string getter and setter; improve float and double functions
authorAhmet Artu Yildirim <ahmet@artulab.com>
Fri, 23 Dec 2022 21:41:50 +0000 (13:41 -0800)
committerAhmet Artu Yildirim <ahmet@artulab.com>
Fri, 23 Dec 2022 21:41:50 +0000 (13:41 -0800)
src/check_progbuf.c
src/common.h
src/progbuf.c
src/progbuf.h

index ac77653..663e12d 100644 (file)
@@ -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);
index a1f6b66..9e84a27 100644 (file)
 #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
 {
index a696628..81a7f95 100644 (file)
@@ -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)
 {
index 0344c7b..361d7ef 100644 (file)
@@ -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);