annotate src/c-ringbuf/ringbuf.h @ 269:446f6d3dc809

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