2 Memory-mapped ringbuffer
3 Derived from jack/ringbuffer.h
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 Copyright (C) 2000 Paul Davis
21 Copyright (C) 2003 Rohan Drape
24 Copyright (C) 2004 by Frank Brickle, AB2KT and Bob McGwier, N4HY
32 ringb_create(char *usemem, size_t sz2) {
33 ringb_t *rb = (ringb_t *) usemem;
34 rb->buf = usemem + sizeof(ringb_t);
35 rb->size = sz2; // power-of-2-sized
36 rb->mask = rb->size - 1;
37 rb->wptr = rb->rptr = 0;
42 ringb_reset(ringb_t *rb) {
49 ringb_read_space(const ringb_t *rb) {
50 size_t w = rb->wptr, r = rb->rptr;
51 if (w > r) return w - r;
52 else return (w - r + rb->size) & rb->mask;
56 ringb_write_space(const ringb_t *rb) {
57 size_t w = rb->wptr, r = rb->rptr;
58 if (w > r) return ((r - w + rb->size) & rb->mask) - 1;
59 else if (w < r) return r - w - 1;
60 else return rb->size - 1;
64 ringb_read(ringb_t *rb, char *dest, size_t cnt) {
65 size_t free_cnt, cnt2, to_read, n1, n2;
66 if ((free_cnt = ringb_read_space(rb)) == 0) return 0;
67 to_read = cnt > free_cnt ? free_cnt : cnt;
68 if ((cnt2 = rb->rptr + to_read) > rb->size)
69 n1 = rb->size - rb->rptr, n2 = cnt2 & rb->mask;
72 memcpy(dest, &(rb->buf[rb->rptr]), n1);
73 rb->rptr = (rb->rptr + n1) & rb->mask;
75 memcpy(dest + n1, &(rb->buf[rb->rptr]), n2);
76 rb->rptr = (rb->rptr + n2) & rb->mask;
82 ringb_peek(ringb_t *rb, char *dest, size_t cnt) {
83 size_t free_cnt, cnt2, to_read, n1, n2, tmp_rptr;
85 if ((free_cnt = ringb_read_space(rb)) == 0) return 0;
86 to_read = cnt > free_cnt ? free_cnt : cnt;
87 if ((cnt2 = tmp_rptr + to_read) > rb->size)
88 n1 = rb->size - tmp_rptr, n2 = cnt2 & rb->mask;
91 memcpy(dest, &(rb->buf[tmp_rptr]), n1);
92 tmp_rptr = (tmp_rptr + n1) & rb->mask;
94 memcpy(dest + n1, &(rb->buf[tmp_rptr]), n2);
99 ringb_write(ringb_t *rb, const char *src, size_t cnt) {
100 size_t free_cnt, cnt2, to_write, n1, n2;
101 if ((free_cnt = ringb_write_space(rb)) == 0) return 0;
102 to_write = cnt > free_cnt ? free_cnt : cnt;
103 if ((cnt2 = rb->wptr + to_write) > rb->size)
104 n1 = rb->size - rb->wptr, n2 = cnt2 & rb->mask;
106 n1 = to_write, n2 = 0;
107 memcpy(&(rb->buf[rb->wptr]), src, n1);
108 rb->wptr = (rb->wptr + n1) & rb->mask;
110 memcpy(&(rb->buf[rb->wptr]), src + n1, n2);
111 rb->wptr = (rb->wptr + n2) & rb->mask;
117 ringb_read_advance(ringb_t *rb, size_t cnt) {
118 rb->rptr = (rb->rptr + cnt) & rb->mask;
122 ringb_write_advance(ringb_t *rb, size_t cnt) {
123 rb->wptr = (rb->wptr + cnt) & rb->mask;
127 ringb_get_read_vector(const ringb_t *rb, ringb_data_t *vec) {
128 size_t free_cnt, cnt2,
129 w = rb->wptr, r = rb->rptr;
130 if (w > r) free_cnt = w - r;
131 else free_cnt = (w - r + rb->size) & rb->mask;
132 if ((cnt2 = r + free_cnt) > rb->size) {
133 vec[0].buf = &(rb->buf[r]), vec[0].len = rb->size - r;
134 vec[1].buf = rb->buf, vec[1].len = cnt2 & rb->mask;
136 vec[0].buf = &(rb->buf[r]), vec[0].len = free_cnt;
142 ringb_get_write_vector(const ringb_t *rb, ringb_data_t *vec) {
143 size_t free_cnt, cnt2,
144 w = rb->wptr, r = rb->rptr;
145 if (w > r) free_cnt = ((r - w + rb->size) & rb->mask) - 1;
146 else if (w < r) free_cnt = r - w - 1;
147 else free_cnt = rb->size - 1;
148 if ((cnt2 = w + free_cnt) > rb->size) {
149 vec[0].buf = &(rb->buf[w]), vec[0].len = rb->size - w;
150 vec[1].buf = rb->buf, vec[1].len = cnt2 & rb->mask;
152 vec[0].buf = &(rb->buf[w]), vec[0].len = free_cnt;