#include <check.h>
#include <float.h>
+#include <stdio.h>
#include <stdlib.h>
#include "common.h"
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");
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;
}
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) \
{ \
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) \
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)
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);