Add setter and getter functions for int array
authorAhmet Artu Yildirim <ahmet@artulab.com>
Thu, 22 Dec 2022 19:14:17 +0000 (11:14 -0800)
committerAhmet Artu Yildirim <ahmet@artulab.com>
Thu, 22 Dec 2022 20:04:22 +0000 (12:04 -0800)
src/check_progbuf.c
src/common.h
src/progbuf.c
src/progbuf.h

index b02dcfa..cabfd60 100644 (file)
@@ -1,5 +1,6 @@
 #include <check.h>
 #include <float.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 #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;
 }
index 5d63f7e..83cd8e9 100644 (file)
@@ -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
 {
index 56f17ec..2037e60 100644 (file)
@@ -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)
index 0cff17c..43bb3de 100644 (file)
@@ -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);