rate: add some sanity checking
[sox.git] / src / fifo.h
blob2e65afa2d78c1774e290ed817fb86e4116bfb12f
1 /* Addressable FIFO buffer Copyright (c) 2007 robs@users.sourceforge.net
3 * This library is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation; either version 2.1 of the License, or (at
6 * your option) any later version.
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11 * General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this library; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 #ifndef fifo_included
19 #define fifo_included
21 #include <string.h>
23 #ifndef FIFO_SIZE_T
24 #define FIFO_SIZE_T size_t
25 #endif
27 typedef struct {
28 char * data;
29 size_t allocation; /* Number of bytes allocated for data. */
30 size_t item_size; /* Size of each item in data */
31 size_t begin; /* Offset of the first byte to read. */
32 size_t end; /* 1 + Offset of the last byte byte to read. */
33 } fifo_t;
35 #define FIFO_MIN 0x4000
37 UNUSED static void fifo_clear(fifo_t * f)
39 f->end = f->begin = 0;
42 UNUSED static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n)
44 n *= f->item_size;
46 if (f->begin == f->end)
47 fifo_clear(f);
49 while (1) {
50 if (f->end + n <= f->allocation) {
51 void *p = f->data + f->end;
53 f->end += n;
54 return p;
56 if (f->begin > FIFO_MIN) {
57 memmove(f->data, f->data + f->begin, f->end - f->begin);
58 f->end -= f->begin;
59 f->begin = 0;
60 continue;
62 f->allocation += n;
63 f->data = lsx_realloc(f->data, f->allocation);
67 UNUSED static void * fifo_write(fifo_t * f, FIFO_SIZE_T n, void const * data)
69 void * s = fifo_reserve(f, n);
70 if (data)
71 memcpy(s, data, n * f->item_size);
72 return s;
75 UNUSED static void fifo_trim_to(fifo_t * f, FIFO_SIZE_T n)
77 n *= f->item_size;
78 f->end = f->begin + n;
81 UNUSED static void fifo_trim_by(fifo_t * f, FIFO_SIZE_T n)
83 n *= f->item_size;
84 f->end -= n;
87 UNUSED static FIFO_SIZE_T fifo_occupancy(fifo_t * f)
89 return (f->end - f->begin) / f->item_size;
92 UNUSED static void * fifo_read(fifo_t * f, FIFO_SIZE_T n, void * data)
94 char * ret = f->data + f->begin;
95 n *= f->item_size;
96 if (n > (FIFO_SIZE_T)(f->end - f->begin))
97 return NULL;
98 if (data)
99 memcpy(data, ret, (size_t)n);
100 f->begin += n;
101 return ret;
104 #define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
106 UNUSED static void fifo_delete(fifo_t * f)
108 free(f->data);
111 UNUSED static void fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
113 f->item_size = item_size;
114 f->allocation = FIFO_MIN;
115 f->data = lsx_malloc(f->allocation);
116 fifo_clear(f);
119 #endif