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