feat: capability list to enable greater flexibility of devices
[lunaix-os.git] / lunaix-os / kernel / ds / rbuffer.c
1 #include <lunaix/ds/rbuffer.h>
2 #include <lunaix/mm/valloc.h>
3 #include <lunaix/spike.h>
4
5 #include <klibc/string.h>
6
7 struct rbuffer*
8 rbuffer_create(char* buf, size_t maxsz)
9 {
10     struct rbuffer* rb = valloc(sizeof(struct rbuffer));
11     rbuffer_init(rb, buf, maxsz);
12
13     return rb;
14 }
15
16 int
17 rbuffer_erase(struct rbuffer* rb)
18 {
19     if (rb->len == 0) {
20         return 0;
21     }
22     rb->ptr = (rb->ptr - 1) % rb->maxsz;
23     rb->len--;
24
25     return 1;
26 }
27
28 int
29 rbuffer_put(struct rbuffer* rb, char c)
30 {
31     rb->buffer[rb->ptr] = c;
32     rb->ptr = (rb->ptr + 1) % rb->maxsz;
33     rb->len = MIN(rb->len + 1, rb->maxsz);
34
35     return 1;
36 }
37
38 int
39 rbuffer_puts(struct rbuffer* rb, char* buf, size_t len)
40 {
41     if (!len)
42         return 0;
43
44     size_t ptr = (rb->ptr + len) % rb->maxsz;
45     size_t nlen = MIN(len, rb->maxsz);
46     size_t ptr_start = (ptr - nlen) % rb->maxsz;
47
48     buf = &buf[nlen];
49     if (ptr_start >= ptr) {
50         size_t llen = rb->maxsz - ptr_start;
51         memcpy(&rb->buffer[ptr_start], &buf[-nlen], llen);
52         memcpy(&rb->buffer[0], &buf[-nlen + llen], ptr + 1);
53     } else {
54         memcpy(&rb->buffer[ptr_start], &buf[-nlen], nlen);
55     }
56
57     rb->ptr = ptr;
58     rb->len = nlen;
59
60     return nlen;
61 }
62
63 int
64 rbuffer_gets(struct rbuffer* rb, char* buf, size_t len)
65 {
66     if (!len || !rb->len)
67         return 0;
68
69     size_t nlen = MIN(len, rb->len);
70     size_t ptr_start = (rb->ptr - rb->len) % rb->maxsz;
71     size_t ptr_end = (ptr_start + nlen) % rb->maxsz;
72
73     buf = &buf[nlen];
74     if (ptr_start >= ptr_end) {
75         size_t llen = rb->maxsz - ptr_start;
76         memcpy(&buf[-nlen], &rb->buffer[ptr_start], llen);
77         memcpy(&buf[-nlen + llen], &rb->buffer[0], ptr_end + 1);
78     } else {
79         memcpy(&buf[-nlen], &rb->buffer[ptr_start], nlen);
80     }
81
82     rb->len -= nlen;
83
84     return nlen;
85 }
86
87 int
88 rbuffer_get(struct rbuffer* rb, char* c)
89 {
90     if (rb->len == 0) {
91         return 0;
92     }
93
94     size_t ptr_start = (rb->ptr - rb->len) % rb->maxsz;
95     rb->len--;
96
97     *c = rb->buffer[ptr_start];
98
99     return 1;
100 }