From 39d10530c59ad2ba888c40e3740078463ad5875f Mon Sep 17 00:00:00 2001 From: Ahmet Artu Yildirim Date: Wed, 21 Dec 2022 17:33:12 -0800 Subject: [PATCH] Have a function to load progbuf from a user buffer --- src/check_progbuf.c | 115 +++++++++++++++++++++++++++++++++++++++++++- src/progbuf.c | 41 ++++++++++++++++ src/progbuf.h | 1 + 3 files changed, 156 insertions(+), 1 deletion(-) diff --git a/src/check_progbuf.c b/src/check_progbuf.c index 961e797..822df87 100644 --- a/src/check_progbuf.c +++ b/src/check_progbuf.c @@ -306,11 +306,119 @@ START_TEST (test_progbuf_write_read_ulonglong) } END_TEST +START_TEST (test_progbuf_load_from_buffer) +{ + int ret; + const long tag = -11; + + progbuf_h buf = progbuf_alloc (tag); + + long p_tag; + + ck_assert (buf); + + ret = progbuf_message_tag (buf, &p_tag); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (tag == p_tag); + + long val = -0xFF; + long p_val = val; + + ret = progbuf_set_long (buf, p_val); + + ck_assert (ret == PROGBUF_SUCCESS); + + size_t size; + + ret = progbuf_buffer_size (buf, &size); + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (size == 4); + + progbuf_it_h iter = progbuf_iter_alloc (buf); + + ck_assert (iter); + + ret = progbuf_get_long (iter, &p_val); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (val == p_val); + + struct progbuf_it_s *iter_internal = iter; + + ck_assert (iter_internal->read_pos == 4); + + char *buffer; + progbuf_own_buffer (buf, &buffer, &size); + + ck_assert (buffer); + ck_assert (size == 4); + + progbuf_h buf_2 = progbuf_from_buffer (buffer, size); + + ck_assert (buf_2); + + ret = progbuf_buffer_size (buf_2, &size); + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (size == 4); + + ret = progbuf_message_tag (buf_2, &p_tag); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (tag == p_tag); + + progbuf_it_h iter2 = progbuf_iter_alloc (buf_2); + + ck_assert (iter2); + + ret = progbuf_get_long (iter2, &p_val); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (val == p_val); + + iter_internal = iter2; + + ck_assert (iter_internal->read_pos == 4); + + val = 0xFF; + p_val = val; + + ret = progbuf_set_long (buf_2, p_val); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_get_long (iter2, &p_val); + + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (val == p_val); + + ck_assert (iter_internal->read_pos == 7); + + ret = progbuf_get_long (iter2, &p_val); + ck_assert (ret == PROGBUF_ERROR_END_OF_ITER); + + ret = progbuf_buffer_size (buf_2, &size); + ck_assert (ret == PROGBUF_SUCCESS); + ck_assert (size == 7); + + ret = progbuf_iter_free (iter); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_iter_free (iter2); + ck_assert (ret == PROGBUF_SUCCESS); + + ret = progbuf_free (buf_2); + ck_assert (ret == PROGBUF_SUCCESS); +} +END_TEST + static Suite * progbuf_suite (void) { Suite *s; - TCase *tc_basic, *tc_long, *tc_longlong; + TCase *tc_basic, *tc_long, *tc_longlong, *tc_load; s = suite_create ("progbuf test suite"); @@ -330,9 +438,14 @@ progbuf_suite (void) tcase_add_test (tc_longlong, test_progbuf_write_read_negative_longlong); tcase_add_test (tc_longlong, test_progbuf_write_read_ulonglong); + tc_load = tcase_create ("load_from_buffer"); + + tcase_add_test (tc_load, test_progbuf_load_from_buffer); + suite_add_tcase (s, tc_basic); suite_add_tcase (s, tc_long); suite_add_tcase (s, tc_longlong); + suite_add_tcase (s, tc_load); return s; } diff --git a/src/progbuf.c b/src/progbuf.c index 1abbfb0..1128820 100644 --- a/src/progbuf.c +++ b/src/progbuf.c @@ -234,6 +234,47 @@ progbuf_alloc (long message_tag) return buf; } +progbuf_h +progbuf_from_buffer (char *buffer, size_t size) +{ + if (!buffer || size == 0) + return 0; + + ulong u_value; + int negative; + + struct progbuf_s *buf = malloc (sizeof (struct progbuf_s)); + buf->buffer = buffer; + + struct progbuf_it_s iter; + iter.buf = buf; + iter.read_pos = 0; + + if (read_var_ulong (&iter, &u_value, &negative) != 0) + { + free (buf); + return 0; + } + + buf->message_tag = (negative ? -u_value : u_value); + buf->header_size = determine_var_ulong_size (ABS (buf->message_tag)); + + buf->size = size; + buf->capacity = size; + + /* update buffer with the new address */ + buf->buffer = malloc (size); + if (!buf->buffer) + { + free (buf); + return 0; + } + + memcpy (buf->buffer, buffer, size); + + return buf; +} + progbuf_it_h progbuf_iter_alloc (progbuf_h buf) { diff --git a/src/progbuf.h b/src/progbuf.h index ce6ebd6..1e54c71 100644 --- a/src/progbuf.h +++ b/src/progbuf.h @@ -16,6 +16,7 @@ typedef struct progbuf_s *progbuf_h; typedef struct progbuf_it_s *progbuf_it_h; progbuf_h progbuf_alloc (long message_tag); +progbuf_h progbuf_from_buffer (char *buffer, size_t size); int progbuf_message_tag (progbuf_h buf, long *message_tag); int progbuf_own_buffer (progbuf_h buf, char **buffer, size_t *size); -- 2.20.1