summaryrefslogtreecommitdiffstats
path: root/src/aclk/mqtt_websockets/c-rbuf
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-25 17:33:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-11-25 17:34:10 +0000
commit83ba6762cc43d9db581b979bb5e3445669e46cc2 (patch)
tree2e69833b43f791ed253a7a20318b767ebe56cdb8 /src/aclk/mqtt_websockets/c-rbuf
parentReleasing debian version 1.47.5-1. (diff)
downloadnetdata-83ba6762cc43d9db581b979bb5e3445669e46cc2.tar.xz
netdata-83ba6762cc43d9db581b979bb5e3445669e46cc2.zip
Merging upstream version 2.0.3+dfsg (Closes: #923993, #1042533, #1045145).
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/aclk/mqtt_websockets/c-rbuf')
-rw-r--r--src/aclk/mqtt_websockets/c-rbuf/cringbuffer.c203
-rw-r--r--src/aclk/mqtt_websockets/c-rbuf/cringbuffer.h47
-rw-r--r--src/aclk/mqtt_websockets/c-rbuf/cringbuffer_internal.h37
-rw-r--r--src/aclk/mqtt_websockets/c-rbuf/ringbuffer_test.c485
4 files changed, 0 insertions, 772 deletions
diff --git a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.c b/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.c
deleted file mode 100644
index 8950c6906..000000000
--- a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.c
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright: SPDX-License-Identifier: GPL-3.0-only
-
-#include "cringbuffer.h"
-#include "cringbuffer_internal.h"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#define MAX(a,b) (((a)>(b))?(a):(b))
-
-// this allows user to use their own
-// custom memory allocation functions
-#ifdef RBUF_CUSTOM_MALLOC
-#include "../../helpers/ringbuffer_pal.h"
-#else
-#define crbuf_malloc(...) malloc(__VA_ARGS__)
-#define crbuf_free(...) free(__VA_ARGS__)
-#endif
-
-rbuf_t rbuf_create(size_t size)
-{
- rbuf_t buffer = crbuf_malloc(sizeof(struct rbuf_t) + size);
- if (!buffer)
- return NULL;
-
- memset(buffer, 0, sizeof(struct rbuf_t));
-
- buffer->data = ((char*)buffer) + sizeof(struct rbuf_t);
-
- buffer->head = buffer->data;
- buffer->tail = buffer->data;
- buffer->size = size;
- buffer->end = buffer->data + size;
-
- return buffer;
-}
-
-void rbuf_free(rbuf_t buffer)
-{
- crbuf_free(buffer);
-}
-
-void rbuf_flush(rbuf_t buffer)
-{
- buffer->head = buffer->data;
- buffer->tail = buffer->data;
- buffer->size_data = 0;
-}
-
-char *rbuf_get_linear_insert_range(rbuf_t buffer, size_t *bytes)
-{
- *bytes = 0;
- if (buffer->head == buffer->tail && buffer->size_data)
- return NULL;
-
- *bytes = ((buffer->head >= buffer->tail) ? buffer->end : buffer->tail) - buffer->head;
- return buffer->head;
-}
-
-char *rbuf_get_linear_read_range(rbuf_t buffer, size_t *bytes)
-{
- *bytes = 0;
- if(buffer->head == buffer->tail && !buffer->size_data)
- return NULL;
-
- *bytes = ((buffer->tail >= buffer->head) ? buffer->end : buffer->head) - buffer->tail;
-
- return buffer->tail;
-}
-
-int rbuf_bump_head(rbuf_t buffer, size_t bytes)
-{
- size_t free_bytes = rbuf_bytes_free(buffer);
- if (bytes > free_bytes)
- return 0;
- int i = buffer->head - buffer->data;
- buffer->head = &buffer->data[(i + bytes) % buffer->size];
- buffer->size_data += bytes;
- return 1;
-}
-
-int rbuf_bump_tail(rbuf_t buffer, size_t bytes)
-{
- if(!rbuf_bump_tail_noopt(buffer, bytes))
- return 0;
-
- // if tail catched up with head
- // start writing buffer from beggining
- // this is not necessary (rbuf must work well without it)
- // but helps to optimize big writes as rbuf_get_linear_insert_range
- // will return bigger continuous region
- if(buffer->tail == buffer->head) {
- assert(buffer->size_data == 0);
- rbuf_flush(buffer);
- }
-
- return 1;
-}
-
-size_t rbuf_get_capacity(rbuf_t buffer)
-{
- return buffer->size;
-}
-
-size_t rbuf_bytes_available(rbuf_t buffer)
-{
- return buffer->size_data;
-}
-
-size_t rbuf_bytes_free(rbuf_t buffer)
-{
- return buffer->size - buffer->size_data;
-}
-
-size_t rbuf_push(rbuf_t buffer, const char *data, size_t len)
-{
- size_t to_cpy;
- char *w_ptr = rbuf_get_linear_insert_range(buffer, &to_cpy);
- if(!to_cpy)
- return to_cpy;
-
- to_cpy = MIN(to_cpy, len);
- memcpy(w_ptr, data, to_cpy);
- rbuf_bump_head(buffer, to_cpy);
- if(to_cpy < len)
- to_cpy += rbuf_push(buffer, &data[to_cpy], len - to_cpy);
- return to_cpy;
-}
-
-size_t rbuf_pop(rbuf_t buffer, char *data, size_t len)
-{
- size_t to_cpy;
- const char *r_ptr = rbuf_get_linear_read_range(buffer, &to_cpy);
- if(!to_cpy)
- return to_cpy;
-
- to_cpy = MIN(to_cpy, len);
- memcpy(data, r_ptr, to_cpy);
- rbuf_bump_tail(buffer, to_cpy);
- if(to_cpy < len)
- to_cpy += rbuf_pop(buffer, &data[to_cpy], len - to_cpy);
- return to_cpy;
-}
-
-static inline void rbuf_ptr_inc(rbuf_t buffer, const char **ptr)
-{
- (*ptr)++;
- if(*ptr >= buffer->end)
- *ptr = buffer->data;
-}
-
-int rbuf_memcmp(rbuf_t buffer, const char *haystack, const char *needle, size_t needle_bytes)
-{
- const char *end = needle + needle_bytes;
-
- // as head==tail can mean 2 things here
- if (haystack == buffer->head && buffer->size_data) {
- if (*haystack != *needle)
- return (*haystack - *needle);
- rbuf_ptr_inc(buffer, &haystack);
- needle++;
- }
-
- while (haystack != buffer->head && needle != end) {
- if (*haystack != *needle)
- return (*haystack - *needle);
- rbuf_ptr_inc(buffer, &haystack);
- needle++;
- }
- return 0;
-}
-
-int rbuf_memcmp_n(rbuf_t buffer, const char *to_cmp, size_t to_cmp_bytes)
-{
- return rbuf_memcmp(buffer, buffer->tail, to_cmp, to_cmp_bytes);
-}
-
-char *rbuf_find_bytes(rbuf_t buffer, const char *needle, size_t needle_bytes, int *found_idx)
-{
- const char *ptr = buffer->tail;
- *found_idx = 0;
-
- if (!rbuf_bytes_available(buffer))
- return NULL;
-
- if (buffer->head == buffer->tail && buffer->size_data) {
- if(!rbuf_memcmp(buffer, ptr, needle, needle_bytes))
- return (char *)ptr;
- rbuf_ptr_inc(buffer, &ptr);
- (*found_idx)++;
- }
-
- while (ptr != buffer->head)
- {
- if(!rbuf_memcmp(buffer, ptr, needle, needle_bytes))
- return (char *)ptr;
- rbuf_ptr_inc(buffer, &ptr);
- (*found_idx)++;
- }
- return NULL;
-}
diff --git a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.h b/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.h
deleted file mode 100644
index eb98035a9..000000000
--- a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer.h
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright: SPDX-License-Identifier: GPL-3.0-only
-
-#ifndef CRINGBUFFER_H
-#define CRINGBUFFER_H
-
-#include <stddef.h>
-
-typedef struct rbuf_t *rbuf_t;
-
-rbuf_t rbuf_create(size_t size);
-void rbuf_free(rbuf_t buffer);
-void rbuf_flush(rbuf_t buffer);
-
-/* /param bytes how much bytes can be copied into pointer returned
- * /return pointer where data can be copied to or NULL if buffer full
- */
-char *rbuf_get_linear_insert_range(rbuf_t buffer, size_t *bytes);
-char *rbuf_get_linear_read_range(rbuf_t buffer, size_t *bytes);
-
-int rbuf_bump_head(rbuf_t buffer, size_t bytes);
-int rbuf_bump_tail(rbuf_t buffer, size_t bytes);
-
-/* @param buffer related buffer instance
- * @returns total capacity of buffer in bytes (not free/used)
- */
-size_t rbuf_get_capacity(rbuf_t buffer);
-
-/* @param buffer related buffer instance
- * @returns count of bytes stored in the buffer
- */
-size_t rbuf_bytes_available(rbuf_t buffer);
-
-/* @param buffer related buffer instance
- * @returns count of bytes available/free in the buffer (how many more bytes you can store in this buffer)
- */
-size_t rbuf_bytes_free(rbuf_t buffer);
-
-/* writes as many bytes from `data` into the `buffer` as possible
- * but maximum `len` bytes
- */
-size_t rbuf_push(rbuf_t buffer, const char *data, size_t len);
-size_t rbuf_pop(rbuf_t buffer, char *data, size_t len);
-
-char *rbuf_find_bytes(rbuf_t buffer, const char *needle, size_t needle_bytes, int *found_idx);
-int rbuf_memcmp_n(rbuf_t buffer, const char *to_cmp, size_t to_cmp_bytes);
-
-#endif
diff --git a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer_internal.h b/src/aclk/mqtt_websockets/c-rbuf/cringbuffer_internal.h
deleted file mode 100644
index d32de187c..000000000
--- a/src/aclk/mqtt_websockets/c-rbuf/cringbuffer_internal.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright: SPDX-License-Identifier: GPL-3.0-only
-
-#ifndef CRINGBUFFER_INTERNAL_H
-#define CRINGBUFFER_INTERNAL_H
-
-struct rbuf_t {
- char *data;
-
- // points to next byte where we can write
- char *head;
- // points to oldest (next to be poped) readable byte
- char *tail;
-
- // to avoid calculating data + size
- // all the time
- char *end;
-
- size_t size;
- size_t size_data;
-};
-
-/* this exists so that it can be tested by unit tests
- * without optimization that resets head and tail to
- * beginning if buffer empty
- */
-inline static int rbuf_bump_tail_noopt(rbuf_t buffer, size_t bytes)
-{
- if (bytes > buffer->size_data)
- return 0;
- int i = buffer->tail - buffer->data;
- buffer->tail = &buffer->data[(i + bytes) % buffer->size];
- buffer->size_data -= bytes;
-
- return 1;
-}
-
-#endif
diff --git a/src/aclk/mqtt_websockets/c-rbuf/ringbuffer_test.c b/src/aclk/mqtt_websockets/c-rbuf/ringbuffer_test.c
deleted file mode 100644
index 6a17c9956..000000000
--- a/src/aclk/mqtt_websockets/c-rbuf/ringbuffer_test.c
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright: SPDX-License-Identifier: GPL-3.0-only
-
-#include "ringbuffer.h"
-
-// to be able to access internals
-// never do this from app
-#include "../src/ringbuffer_internal.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#define KNRM "\x1B[0m"
-#define KRED "\x1B[31m"
-#define KGRN "\x1B[32m"
-#define KYEL "\x1B[33m"
-#define KBLU "\x1B[34m"
-#define KMAG "\x1B[35m"
-#define KCYN "\x1B[36m"
-#define KWHT "\x1B[37m"
-
-#define UNUSED(x) (void)(x)
-
-int total_fails = 0;
-int total_tests = 0;
-int total_checks = 0;
-
-#define CHECK_EQ_RESULT(x, y) \
- while (s_len--) \
- putchar('.'); \
- printf("%s%s " KNRM "\n", (((x) == (y)) ? KGRN : KRED), (((x) == (y)) ? " PASS " : " FAIL ")); \
- if ((x) != (y)) \
- total_fails++; \
- total_checks++;
-
-#define CHECK_EQ_PREFIX(x, y, prefix, subtest_name, ...) \
- { \
- int s_len = \
- 100 - \
- printf(("Checking: " KWHT "%s %s%2d " subtest_name " " KNRM), __func__, prefix, subtest_no, ##__VA_ARGS__); \
- CHECK_EQ_RESULT(x, y) \
- }
-
-#define CHECK_EQ(x, y, subtest_name, ...) \
- { \
- int s_len = \
- 100 - printf(("Checking: " KWHT "%s %2d " subtest_name " " KNRM), __func__, subtest_no, ##__VA_ARGS__); \
- CHECK_EQ_RESULT(x, y) \
- }
-
-#define TEST_DECL() \
- int subtest_no = 0; \
- printf(KYEL "TEST SUITE: %s\n" KNRM, __func__); \
- total_tests++;
-
-static void test_rbuf_get_linear_insert_range()
-{
- TEST_DECL();
-
- // check empty buffer behaviour
- rbuf_t buff = rbuf_create(5);
- char *to_write;
- size_t ret;
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(ret, 5, "empty size");
- CHECK_EQ(to_write, buff->head, "empty write ptr");
- rbuf_free(buff);
-
- // check full buffer behaviour
- subtest_no++;
- buff = rbuf_create(5);
- ret = rbuf_bump_head(buff, 5);
- CHECK_EQ(ret, 1, "ret");
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(to_write, NULL, "writable NULL");
- CHECK_EQ(ret, 0, "writable count = 0");
-
- // check buffer flush
- subtest_no++;
- rbuf_flush(buff);
- CHECK_EQ(rbuf_bytes_free(buff), 5, "size_free");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check behaviour head > tail
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 3);
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(to_write, buff->head, "write location");
- CHECK_EQ(ret, 2, "availible to linear write");
-
- // check behaviour tail > head
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 5);
- rbuf_bump_tail(buff, 3);
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 3, "tail_ptr");
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(to_write, buff->head, "write location");
- CHECK_EQ(ret, 3, "availible to linear write");
-
-/* // check behaviour tail and head at last element
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 4);
- rbuf_bump_tail(buff, 4);
- CHECK_EQ(buff->head, buff->end - 1, "head_ptr");
- CHECK_EQ(buff->tail, buff->end - 1, "tail_ptr");
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(to_write, buff->head, "write location");
- CHECK_EQ(ret, 1, "availible to linear write");*/
-
- // check behaviour tail and head at last element
- // after rbuf_bump_tail optimisation that restarts buffer
- // in case tail catches up with head
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 4);
- rbuf_bump_tail(buff, 4);
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
- to_write = rbuf_get_linear_insert_range(buff, &ret);
- CHECK_EQ(to_write, buff->head, "write location");
- CHECK_EQ(ret, 5, "availible to linear write");
-}
-
-#define _CHECK_EQ(x, y, subtest_name, ...) CHECK_EQ_PREFIX(x, y, prefix, subtest_name, ##__VA_ARGS__)
-#define _PREFX "(size = %5zu) "
-static void test_rbuf_bump_head_bsize(size_t size)
-{
- char prefix[16];
- snprintf(prefix, 16, _PREFX, size);
- int subtest_no = 0;
- rbuf_t buff = rbuf_create(size);
- _CHECK_EQ(rbuf_bytes_free(buff), size, "size_free");
-
- subtest_no++;
- int ret = rbuf_bump_head(buff, size);
- _CHECK_EQ(buff->data, buff->head, "loc");
- _CHECK_EQ(ret, 1, "ret");
- _CHECK_EQ(buff->size_data, buff->size, "size");
- _CHECK_EQ(rbuf_bytes_free(buff), 0, "size_free");
-
- subtest_no++;
- ret = rbuf_bump_head(buff, 1);
- _CHECK_EQ(buff->data, buff->head, "loc no move");
- _CHECK_EQ(ret, 0, "ret error");
- _CHECK_EQ(buff->size_data, buff->size, "size");
- _CHECK_EQ(rbuf_bytes_free(buff), 0, "size_free");
- rbuf_free(buff);
-
- subtest_no++;
- buff = rbuf_create(size);
- ret = rbuf_bump_head(buff, size - 1);
- _CHECK_EQ(buff->head, buff->end-1, "loc end");
- rbuf_free(buff);
-}
-#undef _CHECK_EQ
-
-static void test_rbuf_bump_head()
-{
- TEST_DECL();
- UNUSED(subtest_no);
-
- size_t test_sizes[] = { 1, 2, 3, 5, 6, 7, 8, 100, 99999, 0 };
- for (int i = 0; test_sizes[i]; i++)
- test_rbuf_bump_head_bsize(test_sizes[i]);
-}
-
-static void test_rbuf_bump_tail_noopt(int subtest_no)
-{
- rbuf_t buff = rbuf_create(10);
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
-
- subtest_no++;
- int ret = rbuf_bump_head(buff, 5);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_free(buff), 5, "size_free");
- CHECK_EQ(rbuf_bytes_available(buff), 5, "size_avail");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 2);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 3, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 7, "size_free");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 2, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 3);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 5, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 1);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 5, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_head(buff, 7);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 7, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 3, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 5, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 5);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check tail can't overrun head
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 3);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check head can't overrun tail
- subtest_no++;
- ret = rbuf_bump_head(buff, 9);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check head can fill the buffer
- subtest_no++;
- ret = rbuf_bump_head(buff, 8);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 10, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 0, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check can empty the buffer
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 10);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-}
-
-static void test_rbuf_bump_tail_opt(int subtest_no)
-{
- subtest_no++;
- rbuf_t buff = rbuf_create(10);
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
-
- subtest_no++;
- int ret = rbuf_bump_head(buff, 5);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_free(buff), 5, "size_free");
- CHECK_EQ(rbuf_bytes_available(buff), 5, "size_avail");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail(buff, 2);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 3, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 7, "size_free");
- CHECK_EQ(buff->head, buff->data + 5, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 2, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail(buff, 3);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail_noopt(buff, 1);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_head(buff, 6);
- ret = rbuf_bump_tail(buff, 5);
- ret = rbuf_bump_head(buff, 6);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 7, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 3, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data + 5, "tail_ptr");
-
- subtest_no++;
- ret = rbuf_bump_tail(buff, 5);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check tail can't overrun head
- subtest_no++;
- ret = rbuf_bump_tail(buff, 3);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check head can't overrun tail
- subtest_no++;
- ret = rbuf_bump_head(buff, 9);
- CHECK_EQ(ret, 0, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 2, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 8, "size_free");
- CHECK_EQ(buff->head, buff->data + 2, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check head can fill the buffer
- subtest_no++;
- ret = rbuf_bump_head(buff, 8);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 10, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 0, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-
- // check can empty the buffer
- subtest_no++;
- ret = rbuf_bump_tail(buff, 10);
- CHECK_EQ(ret, 1, "ret");
- CHECK_EQ(rbuf_bytes_available(buff), 0, "size_avail");
- CHECK_EQ(rbuf_bytes_free(buff), 10, "size_free");
- CHECK_EQ(buff->head, buff->data, "head_ptr");
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
-}
-
-static void test_rbuf_bump_tail()
-{
- TEST_DECL();
- test_rbuf_bump_tail_noopt(subtest_no);
- test_rbuf_bump_tail_opt(subtest_no);
-}
-
-#define ASCII_A 0x61
-#define ASCII_Z 0x7A
-#define TEST_DATA_SIZE ASCII_Z-ASCII_A+1
-static void test_rbuf_push()
-{
- TEST_DECL();
- rbuf_t buff = rbuf_create(10);
- int i;
- char test_data[TEST_DATA_SIZE];
-
- for (int i = 0; i <= TEST_DATA_SIZE; i++)
- test_data[i] = i + ASCII_A;
-
- int ret = rbuf_push(buff, test_data, 10);
- CHECK_EQ(ret, 10, "written 10 bytes");
- CHECK_EQ(rbuf_bytes_free(buff), 0, "empty size == 0");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], i + ASCII_A, "Check data");
-
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 5);
- rbuf_bump_tail_noopt(buff, 5); //to not reset both pointers to beginning
- ret = rbuf_push(buff, test_data, 10);
- CHECK_EQ(ret, 10, "written 10 bytes");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], ((i+5)%10) + ASCII_A, "Check Data");
-
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 9);
- rbuf_bump_tail_noopt(buff, 9);
- ret = rbuf_push(buff, test_data, 10);
- CHECK_EQ(ret, 10, "written 10 bytes");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], ((i + 1) % 10) + ASCII_A, "Check data");
-
- // let tail > head
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 9);
- rbuf_bump_tail_noopt(buff, 9);
- rbuf_bump_head(buff, 1);
- ret = rbuf_push(buff, test_data, 9);
- CHECK_EQ(ret, 9, "written 9 bytes");
- CHECK_EQ(buff->head, buff->end - 1, "head_ptr");
- CHECK_EQ(buff->tail, buff->head, "tail_ptr");
- rbuf_bump_tail(buff, 1);
- //TODO push byte can be usefull optimisation
- ret = rbuf_push(buff, &test_data[9], 1);
- CHECK_EQ(ret, 1, "written 1 byte");
- CHECK_EQ(rbuf_bytes_free(buff), 0, "empty size == 0");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], i + ASCII_A, "Check data");
-
- subtest_no++;
- rbuf_flush(buff);
- rbuf_bump_head(buff, 9);
- rbuf_bump_tail_noopt(buff, 7);
- rbuf_bump_head(buff, 1);
- ret = rbuf_push(buff, test_data, 7);
- CHECK_EQ(ret, 7, "written 7 bytes");
- CHECK_EQ(buff->head, buff->data + 7, "head_ptr");
- CHECK_EQ(buff->tail, buff->head, "tail_ptr");
- rbuf_bump_tail(buff, 3);
- CHECK_EQ(buff->tail, buff->data, "tail_ptr");
- //TODO push byte can be usefull optimisation
- ret = rbuf_push(buff, &test_data[7], 3);
- CHECK_EQ(ret, 3, "written 3 bytes");
- CHECK_EQ(rbuf_bytes_free(buff), 0, "empty size == 0");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], i + ASCII_A, "Check data");
-
- // test can't overfill the buffer
- subtest_no++;
- rbuf_flush(buff);
- rbuf_push(buff, test_data, TEST_DATA_SIZE);
- CHECK_EQ(ret, 3, "written 10 bytes");
- for (i = 0; i < 10; i++)
- CHECK_EQ(buff->data[i], i + ASCII_A, "Check data");
-}
-
-#define TEST_RBUF_FIND_BYTES_SIZE 10
-void test_rbuf_find_bytes()
-{
- TEST_DECL();
- rbuf_t buff = rbuf_create(TEST_RBUF_FIND_BYTES_SIZE);
- char *filler_3 = " ";
- char *needle = "needle";
- int idx;
- char *ptr;
-
- // make sure needle is wrapped aroung in the buffer
- // to test we still can find it
- // target "edle ne"
- rbuf_bump_head(buff, TEST_RBUF_FIND_BYTES_SIZE / 2);
- rbuf_push(buff, filler_3, strlen(filler_3));
- rbuf_bump_tail(buff, TEST_RBUF_FIND_BYTES_SIZE / 2);
- rbuf_push(buff, needle, strlen(needle));
- ptr = rbuf_find_bytes(buff, needle, strlen(needle), &idx);
- CHECK_EQ(ptr, buff->data + (TEST_RBUF_FIND_BYTES_SIZE / 2) + strlen(filler_3), "Pointer to needle correct");
- CHECK_EQ(idx, ptr - buff->tail, "Check needle index");
-}
-
-int main()
-{
- test_rbuf_bump_head();
- test_rbuf_bump_tail();
- test_rbuf_get_linear_insert_range();
- test_rbuf_push();
- test_rbuf_find_bytes();
-
- printf(
- KNRM "Total Tests %d, Total Checks %d, Successful Checks %d, Failed Checks %d\n",
- total_tests, total_checks, total_checks - total_fails, total_fails);
- if (total_fails)
- printf(KRED "!!!Some test(s) Failed!!!\n");
- else
- printf(KGRN "ALL TESTS PASSED\n");
-
- return total_fails;
-}