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_clear(ringb_t *rb, size_t nbytes) {
52 for (i = 0; i < nbytes; i++)
53 ringb_write(rb, &zero, 1);
57 ringb_restart(ringb_t *rb, size_t nbytes) {
59 ringb_clear(rb, nbytes);
63 ringb_read_space(const ringb_t *rb) {
64 size_t w = rb->wptr, r = rb->rptr;
65 if (w > r) return w - r;
66 else return (w - r + rb->size) & rb->mask;
70 ringb_write_space(const ringb_t *rb) {
71 size_t w = rb->wptr, r = rb->rptr;
72 if (w > r) return ((r - w + rb->size) & rb->mask) - 1;
73 else if (w < r) return r - w - 1;
74 else return rb->size - 1;
78 ringb_read(ringb_t *rb, char *dest, size_t cnt) {
79 size_t free_cnt, cnt2, to_read, n1, n2;
80 if ((free_cnt = ringb_read_space(rb)) == 0) return 0;
81 to_read = cnt > free_cnt ? free_cnt : cnt;
82 if ((cnt2 = rb->rptr + to_read) > rb->size)
83 n1 = rb->size - rb->rptr, n2 = cnt2 & rb->mask;
86 memcpy(dest, &(rb->buf[rb->rptr]), n1);
87 rb->rptr = (rb->rptr + n1) & rb->mask;
89 memcpy(dest + n1, &(rb->buf[rb->rptr]), n2);
90 rb->rptr = (rb->rptr + n2) & rb->mask;
96 ringb_peek(ringb_t *rb, char *dest, size_t cnt) {
97 size_t free_cnt, cnt2, to_read, n1, n2, tmp_rptr;
99 if ((free_cnt = ringb_read_space(rb)) == 0) return 0;
100 to_read = cnt > free_cnt ? free_cnt : cnt;
101 if ((cnt2 = tmp_rptr + to_read) > rb->size)
102 n1 = rb->size - tmp_rptr, n2 = cnt2 & rb->mask;
104 n1 = to_read, n2 = 0;
105 memcpy(dest, &(rb->buf[tmp_rptr]), n1);
106 tmp_rptr = (tmp_rptr + n1) & rb->mask;
108 memcpy(dest + n1, &(rb->buf[tmp_rptr]), n2);
113 ringb_write(ringb_t *rb, const char *src, size_t cnt) {
114 size_t free_cnt, cnt2, to_write, n1, n2;
115 if ((free_cnt = ringb_write_space(rb)) == 0) return 0;
116 to_write = cnt > free_cnt ? free_cnt : cnt;
117 if ((cnt2 = rb->wptr + to_write) > rb->size)
118 n1 = rb->size - rb->wptr, n2 = cnt2 & rb->mask;
120 n1 = to_write, n2 = 0;
121 memcpy(&(rb->buf[rb->wptr]), src, n1);
122 rb->wptr = (rb->wptr + n1) & rb->mask;
124 memcpy(&(rb->buf[rb->wptr]), src + n1, n2);
125 rb->wptr = (rb->wptr + n2) & rb->mask;
131 ringb_read_advance(ringb_t *rb, size_t cnt) {
132 rb->rptr = (rb->rptr + cnt) & rb->mask;
136 ringb_write_advance(ringb_t *rb, size_t cnt) {
137 rb->wptr = (rb->wptr + cnt) & rb->mask;
141 ringb_get_read_vector(const ringb_t *rb, ringb_data_t *vec) {
142 size_t free_cnt, cnt2,
143 w = rb->wptr, r = rb->rptr;
144 if (w > r) free_cnt = w - r;
145 else free_cnt = (w - r + rb->size) & rb->mask;
146 if ((cnt2 = r + free_cnt) > rb->size) {
147 vec[0].buf = &(rb->buf[r]), vec[0].len = rb->size - r;
148 vec[1].buf = rb->buf, vec[1].len = cnt2 & rb->mask;
150 vec[0].buf = &(rb->buf[r]), vec[0].len = free_cnt;
156 ringb_get_write_vector(const ringb_t *rb, ringb_data_t *vec) {
157 size_t free_cnt, cnt2,
158 w = rb->wptr, r = rb->rptr;
159 if (w > r) free_cnt = ((r - w + rb->size) & rb->mask) - 1;
160 else if (w < r) free_cnt = r - w - 1;
161 else free_cnt = rb->size - 1;
162 if ((cnt2 = w + free_cnt) > rb->size) {
163 vec[0].buf = &(rb->buf[w]), vec[0].len = rb->size - w;
164 vec[1].buf = rb->buf, vec[1].len = cnt2 & rb->mask;
166 vec[0].buf = &(rb->buf[w]), vec[0].len = free_cnt;