1 /* robtk LV2 GUI
2 *
3 * Copyright 2013 Robin Gareus <robin@gareus.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20 #include <string.h>
21 #include <stdlib.h>
22
23 /* simple lockless ringbuffer */
24
25 typedef struct {
26 uint8_t *d;
27 size_t rp;
28 size_t wp;
29 size_t len;
30 } posringbuf;
31
posrb_alloc(size_t siz)32 static posringbuf * posrb_alloc(size_t siz) {
33 posringbuf *rb = (posringbuf*) malloc(sizeof(posringbuf));
34 rb->d = (uint8_t*) malloc(siz * sizeof(uint8_t));
35 rb->len = siz;
36 rb->rp = 0;
37 rb->wp = 0;
38 return rb;
39 }
40
posrb_free(posringbuf * rb)41 static void posrb_free(posringbuf *rb) {
42 free(rb->d);
43 free(rb);
44 }
45
posrb_write_space(posringbuf * rb)46 static size_t posrb_write_space(posringbuf *rb) {
47 if (rb->rp == rb->wp) return (rb->len -1);
48 return ((rb->len + rb->rp - rb->wp) % rb->len) -1;
49 }
50
posrb_read_space(posringbuf * rb)51 static size_t posrb_read_space(posringbuf *rb) {
52 return ((rb->len + rb->wp - rb->rp) % rb->len);
53 }
54
posrb_read(posringbuf * rb,uint8_t * d,size_t len)55 static int posrb_read(posringbuf *rb, uint8_t *d, size_t len) {
56 if (posrb_read_space(rb) < len) return -1;
57 if (rb->rp + len <= rb->len) {
58 memcpy((void*) d, (void*) &rb->d[rb->rp], len * sizeof (uint8_t));
59 } else {
60 int part = rb->len - rb->rp;
61 int remn = len - part;
62 memcpy((void*) d, (void*) &(rb->d[rb->rp]), part * sizeof (uint8_t));
63 memcpy((void*) &(d[part]), (void*) rb->d, remn * sizeof (uint8_t));
64 }
65 rb->rp = (rb->rp + len) % rb->len;
66 return 0;
67 }
68
69
posrb_write(posringbuf * rb,uint8_t * d,size_t len)70 static int posrb_write(posringbuf *rb, uint8_t *d, size_t len) {
71 if (posrb_write_space(rb) < len) return -1;
72 if (rb->wp + len <= rb->len) {
73 memcpy((void*) &rb->d[rb->wp], (void*) d, len * sizeof(uint8_t));
74 } else {
75 int part = rb->len - rb->wp;
76 int remn = len - part;
77 memcpy((void*) &rb->d[rb->wp], (void*) d, part * sizeof(uint8_t));
78 memcpy((void*) rb->d, (void*) &d[part], remn * sizeof(uint8_t));
79 }
80 rb->wp = (rb->wp + len) % rb->len;
81 return 0;
82 }
83
posrb_read_clear(posringbuf * rb)84 static void posrb_read_clear(posringbuf *rb) {
85 rb->rp = rb->wp;
86 }
87