summaryrefslogtreecommitdiff
path: root/toxav/ring_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/ring_buffer.c')
-rw-r--r--toxav/ring_buffer.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/toxav/ring_buffer.c b/toxav/ring_buffer.c
new file mode 100644
index 00000000..cef3e943
--- /dev/null
+++ b/toxav/ring_buffer.c
@@ -0,0 +1,92 @@
1#include "ring_buffer.h"
2
3#include <stdlib.h>
4
5struct RingBuffer {
6 uint16_t size; /* Max size */
7 uint16_t start;
8 uint16_t end;
9 void **data;
10};
11
12bool rb_full(const RingBuffer *b)
13{
14 return (b->end + 1) % b->size == b->start;
15}
16bool rb_empty(const RingBuffer *b)
17{
18 return b->end == b->start;
19}
20void *rb_write(RingBuffer *b, void *p)
21{
22 void *rc = NULL;
23
24 if ((b->end + 1) % b->size == b->start) { /* full */
25 rc = b->data[b->start];
26 }
27
28 b->data[b->end] = p;
29 b->end = (b->end + 1) % b->size;
30
31 if (b->end == b->start) {
32 b->start = (b->start + 1) % b->size;
33 }
34
35 return rc;
36}
37bool rb_read(RingBuffer *b, void **p)
38{
39 if (b->end == b->start) { /* Empty */
40 *p = NULL;
41 return false;
42 }
43
44 *p = b->data[b->start];
45 b->start = (b->start + 1) % b->size;
46 return true;
47}
48RingBuffer *rb_new(int size)
49{
50 RingBuffer *buf = calloc(sizeof(RingBuffer), 1);
51
52 if (!buf) {
53 return NULL;
54 }
55
56 buf->size = size + 1; /* include empty elem */
57
58 if (!(buf->data = calloc(buf->size, sizeof(void *)))) {
59 free(buf);
60 return NULL;
61 }
62
63 return buf;
64}
65void rb_kill(RingBuffer *b)
66{
67 if (b) {
68 free(b->data);
69 free(b);
70 }
71}
72uint16_t rb_size(const RingBuffer *b)
73{
74 if (rb_empty(b)) {
75 return 0;
76 }
77
78 return
79 b->end > b->start ?
80 b->end - b->start :
81 (b->size - b->start) + b->end;
82}
83uint16_t rb_data(const RingBuffer *b, void **dest)
84{
85 uint16_t i = 0;
86
87 for (; i < rb_size(b); i++) {
88 dest[i] = b->data[(b->start + i) % b->size];
89 }
90
91 return i;
92}