}
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);
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);
#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
{
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;
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;
}
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)
{
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;
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;
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;
}
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)
{
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;
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)
{
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);