jamie@216
|
1 #ifndef INCLUDED_RINGBUF_H
|
jamie@216
|
2 #define INCLUDED_RINGBUF_H
|
jamie@216
|
3
|
jamie@216
|
4 /*
|
jamie@216
|
5 * ringbuf.h - C ring buffer (FIFO) interface.
|
jamie@216
|
6 *
|
jamie@216
|
7 * Written in 2011 by Drew Hess <dhess-src@bothan.net>.
|
jamie@216
|
8 *
|
jamie@216
|
9 * To the extent possible under law, the author(s) have dedicated all
|
jamie@216
|
10 * copyright and related and neighboring rights to this software to
|
jamie@216
|
11 * the public domain worldwide. This software is distributed without
|
jamie@216
|
12 * any warranty.
|
jamie@216
|
13 *
|
jamie@216
|
14 * You should have received a copy of the CC0 Public Domain Dedication
|
jamie@216
|
15 * along with this software. If not, see
|
jamie@216
|
16 * <http://creativecommons.org/publicdomain/zero/1.0/>.
|
jamie@216
|
17 */
|
jamie@216
|
18
|
jamie@216
|
19 /*
|
jamie@216
|
20 * A byte-addressable ring buffer FIFO implementation.
|
jamie@216
|
21 *
|
jamie@216
|
22 * The ring buffer's head pointer points to the starting location
|
jamie@216
|
23 * where data should be written when copying data *into* the buffer
|
jamie@216
|
24 * (e.g., with ringbuf_read). The ring buffer's tail pointer points to
|
jamie@216
|
25 * the starting location where data should be read when copying data
|
jamie@216
|
26 * *from* the buffer (e.g., with ringbuf_write).
|
jamie@216
|
27 */
|
jamie@216
|
28
|
jamie@216
|
29 #include <stddef.h>
|
jamie@216
|
30 #include <sys/types.h>
|
jamie@216
|
31 #include <stdbool.h>
|
jamie@216
|
32
|
jamie@285
|
33 #ifdef _MSC_VER
|
jamie@285
|
34 typedef ptrdiff_t ssize_t;
|
jamie@285
|
35 #endif
|
jamie@285
|
36
|
jamie@216
|
37 typedef struct ringbuf_t *ringbuf_t;
|
jamie@216
|
38
|
jamie@216
|
39 /*
|
jamie@216
|
40 * Create a new ring buffer with the given capacity (usable
|
jamie@216
|
41 * bytes). Note that the actual internal buffer size may be one or
|
jamie@216
|
42 * more bytes larger than the usable capacity, for bookkeeping.
|
jamie@216
|
43 *
|
jamie@216
|
44 * Returns the new ring buffer object, or 0 if there's not enough
|
jamie@216
|
45 * memory to fulfill the request for the given capacity.
|
jamie@216
|
46 */
|
jamie@216
|
47 ringbuf_t
|
jamie@216
|
48 ringbuf_new(size_t capacity);
|
jamie@216
|
49
|
jamie@216
|
50 /*
|
jamie@216
|
51 * The size of the internal buffer, in bytes. One or more bytes may be
|
jamie@216
|
52 * unusable in order to distinguish the "buffer full" state from the
|
jamie@216
|
53 * "buffer empty" state.
|
jamie@216
|
54 *
|
jamie@216
|
55 * For the usable capacity of the ring buffer, use the
|
jamie@216
|
56 * ringbuf_capacity function.
|
jamie@216
|
57 */
|
jamie@216
|
58 size_t
|
jamie@216
|
59 ringbuf_buffer_size(const struct ringbuf_t *rb);
|
jamie@216
|
60
|
jamie@216
|
61 /*
|
jamie@216
|
62 * Deallocate a ring buffer, and, as a side effect, set the pointer to
|
jamie@216
|
63 * 0.
|
jamie@216
|
64 */
|
jamie@216
|
65 void
|
jamie@216
|
66 ringbuf_free(ringbuf_t *rb);
|
jamie@216
|
67
|
jamie@216
|
68 /*
|
jamie@216
|
69 * Reset a ring buffer to its initial state (empty).
|
jamie@216
|
70 */
|
jamie@216
|
71 void
|
jamie@216
|
72 ringbuf_reset(ringbuf_t rb);
|
jamie@216
|
73
|
jamie@216
|
74 /*
|
jamie@216
|
75 * The usable capacity of the ring buffer, in bytes. Note that this
|
jamie@216
|
76 * value may be less than the ring buffer's internal buffer size, as
|
jamie@216
|
77 * returned by ringbuf_buffer_size.
|
jamie@216
|
78 */
|
jamie@216
|
79 size_t
|
jamie@216
|
80 ringbuf_capacity(const struct ringbuf_t *rb);
|
jamie@216
|
81
|
jamie@216
|
82 /*
|
jamie@216
|
83 * The number of free/available bytes in the ring buffer. This value
|
jamie@216
|
84 * is never larger than the ring buffer's usable capacity.
|
jamie@216
|
85 */
|
jamie@216
|
86 size_t
|
jamie@216
|
87 ringbuf_bytes_free(const struct ringbuf_t *rb);
|
jamie@216
|
88
|
jamie@216
|
89 /*
|
jamie@216
|
90 * The number of bytes currently being used in the ring buffer. This
|
jamie@216
|
91 * value is never larger than the ring buffer's usable capacity.
|
jamie@216
|
92 */
|
jamie@216
|
93 size_t
|
jamie@216
|
94 ringbuf_bytes_used(const struct ringbuf_t *rb);
|
jamie@216
|
95
|
jamie@216
|
96 int
|
jamie@216
|
97 ringbuf_is_full(const struct ringbuf_t *rb);
|
jamie@216
|
98
|
jamie@216
|
99 int
|
jamie@216
|
100 ringbuf_is_empty(const struct ringbuf_t *rb);
|
jamie@216
|
101
|
jamie@216
|
102 /*
|
jamie@216
|
103 * Const access to the head and tail pointers of the ring buffer.
|
jamie@216
|
104 */
|
jamie@216
|
105 const void *
|
jamie@216
|
106 ringbuf_tail(const struct ringbuf_t *rb);
|
jamie@216
|
107
|
jamie@216
|
108 const void *
|
jamie@216
|
109 ringbuf_head(const struct ringbuf_t *rb);
|
jamie@216
|
110
|
jamie@216
|
111 /*
|
jamie@216
|
112 * Locate the first occurrence of character c (converted to an
|
jamie@216
|
113 * unsigned char) in ring buffer rb, beginning the search at offset
|
jamie@216
|
114 * bytes from the ring buffer's tail pointer. The function returns the
|
jamie@216
|
115 * offset of the character from the ring buffer's tail pointer, if
|
jamie@216
|
116 * found. If c does not occur in the ring buffer, the function returns
|
jamie@216
|
117 * the number of bytes used in the ring buffer.
|
jamie@216
|
118 *
|
jamie@216
|
119 * Note that the offset parameter and the returned offset are logical
|
jamie@216
|
120 * offsets from the tail pointer, not necessarily linear offsets.
|
jamie@216
|
121 */
|
jamie@216
|
122 size_t
|
jamie@216
|
123 ringbuf_findchr(const struct ringbuf_t *rb, int c, size_t offset);
|
jamie@216
|
124
|
jamie@216
|
125 /*
|
jamie@216
|
126 * Beginning at ring buffer dst's head pointer, fill the ring buffer
|
jamie@216
|
127 * with a repeating sequence of len bytes, each of value c (converted
|
jamie@216
|
128 * to an unsigned char). len can be as large as you like, but the
|
jamie@216
|
129 * function will never write more than ringbuf_buffer_size(dst) bytes
|
jamie@216
|
130 * in a single invocation, since that size will cause all bytes in the
|
jamie@216
|
131 * ring buffer to be written exactly once each.
|
jamie@216
|
132 *
|
jamie@216
|
133 * Note that if len is greater than the number of free bytes in dst,
|
jamie@216
|
134 * the ring buffer will overflow. When an overflow occurs, the state
|
jamie@216
|
135 * of the ring buffer is guaranteed to be consistent, including the
|
jamie@216
|
136 * head and tail pointers; old data will simply be overwritten in FIFO
|
jamie@216
|
137 * fashion, as needed. However, note that, if calling the function
|
jamie@216
|
138 * results in an overflow, the value of the ring buffer's tail pointer
|
jamie@216
|
139 * may be different than it was before the function was called.
|
jamie@216
|
140 *
|
jamie@216
|
141 * Returns the actual number of bytes written to dst: len, if
|
jamie@216
|
142 * len < ringbuf_buffer_size(dst), else ringbuf_buffer_size(dst).
|
jamie@216
|
143 */
|
jamie@216
|
144 size_t
|
jamie@216
|
145 ringbuf_memset(ringbuf_t dst, int c, size_t len);
|
jamie@216
|
146
|
jamie@216
|
147 /*
|
jamie@216
|
148 * Copy n bytes from a contiguous memory area src into the ring buffer
|
jamie@216
|
149 * dst. Returns the ring buffer's new head pointer.
|
jamie@216
|
150 *
|
jamie@216
|
151 * It is possible to copy more data from src than is available in the
|
jamie@216
|
152 * buffer; i.e., it's possible to overflow the ring buffer using this
|
jamie@216
|
153 * function. When an overflow occurs, the state of the ring buffer is
|
jamie@216
|
154 * guaranteed to be consistent, including the head and tail pointers;
|
jamie@216
|
155 * old data will simply be overwritten in FIFO fashion, as
|
jamie@216
|
156 * needed. However, note that, if calling the function results in an
|
jamie@216
|
157 * overflow, the value of the ring buffer's tail pointer may be
|
jamie@216
|
158 * different than it was before the function was called.
|
jamie@216
|
159 */
|
jamie@216
|
160 void *
|
jamie@216
|
161 ringbuf_memcpy_into(ringbuf_t dst, const void *src, size_t count);
|
jamie@216
|
162
|
jamie@216
|
163 /*
|
jamie@216
|
164 * This convenience function calls read(2) on the file descriptor fd,
|
jamie@216
|
165 * using the ring buffer rb as the destination buffer for the read,
|
jamie@216
|
166 * and returns the value returned by read(2). It will only call
|
jamie@216
|
167 * read(2) once, and may return a short count.
|
jamie@216
|
168 *
|
jamie@216
|
169 * It is possible to read more data from the file descriptor than is
|
jamie@216
|
170 * available in the buffer; i.e., it's possible to overflow the ring
|
jamie@216
|
171 * buffer using this function. When an overflow occurs, the state of
|
jamie@216
|
172 * the ring buffer is guaranteed to be consistent, including the head
|
jamie@216
|
173 * and tail pointers: old data will simply be overwritten in FIFO
|
jamie@216
|
174 * fashion, as needed. However, note that, if calling the function
|
jamie@216
|
175 * results in an overflow, the value of the ring buffer's tail pointer
|
jamie@216
|
176 * may be different than it was before the function was called.
|
jamie@216
|
177 */
|
jamie@216
|
178 ssize_t
|
jamie@216
|
179 ringbuf_read(int fd, ringbuf_t rb, size_t count);
|
jamie@216
|
180
|
jamie@216
|
181 /*
|
jamie@216
|
182 * Copy n bytes from the ring buffer src, starting from its tail
|
jamie@216
|
183 * pointer, into a contiguous memory area dst. Returns the value of
|
jamie@216
|
184 * src's tail pointer after the copy is finished.
|
jamie@216
|
185 *
|
jamie@216
|
186 * Note if the destroy flag is set to true this copy is destructive with
|
jamie@216
|
187 * respect to the ring buffer:
|
jamie@216
|
188 * the n bytes copied from the ring buffer are no longer available in
|
jamie@216
|
189 * the ring buffer after the copy is complete, and the ring buffer
|
jamie@216
|
190 * will have n more free bytes than it did before the function was
|
jamie@216
|
191 * called.
|
jamie@216
|
192 *
|
jamie@216
|
193 * This function will *not* allow the ring buffer to underflow. If
|
jamie@216
|
194 * count is greater than the number of bytes used in the ring buffer,
|
jamie@216
|
195 * no bytes are copied, and the function will return 0.
|
jamie@216
|
196 */
|
jamie@216
|
197 void *
|
jamie@216
|
198 ringbuf_memcpy_from(void *dst, ringbuf_t src, size_t count, bool destroy);
|
jamie@216
|
199
|
jamie@216
|
200 /*
|
jamie@216
|
201 * This convenience function calls write(2) on the file descriptor fd,
|
jamie@216
|
202 * using the ring buffer rb as the source buffer for writing (starting
|
jamie@216
|
203 * at the ring buffer's tail pointer), and returns the value returned
|
jamie@216
|
204 * by write(2). It will only call write(2) once, and may return a
|
jamie@216
|
205 * short count.
|
jamie@216
|
206 *
|
jamie@216
|
207 * Note that this copy is destructive with respect to the ring buffer:
|
jamie@216
|
208 * any bytes written from the ring buffer to the file descriptor are
|
jamie@216
|
209 * no longer available in the ring buffer after the copy is complete,
|
jamie@216
|
210 * and the ring buffer will have N more free bytes than it did before
|
jamie@216
|
211 * the function was called, where N is the value returned by the
|
jamie@216
|
212 * function (unless N is < 0, in which case an error occurred and no
|
jamie@216
|
213 * bytes were written).
|
jamie@216
|
214 *
|
jamie@216
|
215 * This function will *not* allow the ring buffer to underflow. If
|
jamie@216
|
216 * count is greater than the number of bytes used in the ring buffer,
|
jamie@216
|
217 * no bytes are written to the file descriptor, and the function will
|
jamie@216
|
218 * return 0.
|
jamie@216
|
219 */
|
jamie@216
|
220 ssize_t
|
jamie@216
|
221 ringbuf_write(int fd, ringbuf_t rb, size_t count);
|
jamie@216
|
222
|
jamie@216
|
223 /*
|
jamie@216
|
224 * Copy count bytes from ring buffer src, starting from its tail
|
jamie@216
|
225 * pointer, into ring buffer dst. Returns dst's new head pointer after
|
jamie@216
|
226 * the copy is finished.
|
jamie@216
|
227 *
|
jamie@216
|
228 * Note that this copy is destructive with respect to the ring buffer
|
jamie@216
|
229 * src: any bytes copied from src into dst are no longer available in
|
jamie@216
|
230 * src after the copy is complete, and src will have 'count' more free
|
jamie@216
|
231 * bytes than it did before the function was called.
|
jamie@216
|
232 *
|
jamie@216
|
233 * It is possible to copy more data from src than is available in dst;
|
jamie@216
|
234 * i.e., it's possible to overflow dst using this function. When an
|
jamie@216
|
235 * overflow occurs, the state of dst is guaranteed to be consistent,
|
jamie@216
|
236 * including the head and tail pointers; old data will simply be
|
jamie@216
|
237 * overwritten in FIFO fashion, as needed. However, note that, if
|
jamie@216
|
238 * calling the function results in an overflow, the value dst's tail
|
jamie@216
|
239 * pointer may be different than it was before the function was
|
jamie@216
|
240 * called.
|
jamie@216
|
241 *
|
jamie@216
|
242 * It is *not* possible to underflow src; if count is greater than the
|
jamie@216
|
243 * number of bytes used in src, no bytes are copied, and the function
|
jamie@216
|
244 * returns 0.
|
jamie@216
|
245 */
|
jamie@216
|
246 void *
|
jamie@216
|
247 ringbuf_copy(ringbuf_t dst, ringbuf_t src, size_t count);
|
jamie@216
|
248
|
jamie@216
|
249 #endif /* INCLUDED_RINGBUF_H */
|