annotate src/c-ringbuf/ringbuf.h @ 285:89fe52066db1 tip master

MSCV missing ssize_t fix
author Jamie Bullock <jamie@jamiebullock.com>
date Tue, 16 Jul 2019 18:29:20 +0100
parents 1f18f47e29eb
children
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@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 */