initial revision
[ucgine.git] / lib / cirbuf / include / ucg_cirbuf.h
1 /*
2  * Copyright 2009-2015, Olivier MATZ <zer0@droids-corp.org>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 /*-
29  * Copyright (c) <2010>, Intel Corporation
30  * All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * - Redistributions of source code must retain the above copyright
37  *   notice, this list of conditions and the following disclaimer.
38  *
39  * - Redistributions in binary form must reproduce the above copyright
40  *   notice, this list of conditions and the following disclaimer in
41  *   the documentation and/or other materials provided with the
42  *   distribution.
43  *
44  * - Neither the name of Intel Corporation nor the names of its
45  *   contributors may be used to endorse or promote products derived
46  *   from this software without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
51  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
52  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
53  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
54  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
55  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
57  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
59  * OF THE POSSIBILITY OF SUCH DAMAGE.
60  */
61
62 #ifndef UCG_CIRBUF_H_
63 #define UCG_CIRBUF_H_
64
65 #include <stdio.h>
66
67 /**
68  * A circular buffer.
69  */
70 struct ucg_cirbuf {
71         unsigned maxlen; /**< Total length of the fifo (number of elements). */
72         unsigned start;  /**< Index of the first element. */
73         unsigned len;    /**< Current len of fifo. */
74         char *buf;       /**< Pointer to the data buffer. */
75 };
76
77 /**
78  * Initialize a circular buffer.
79  *
80  * @param cbuf
81  *   A pointer to an uninitialized circular buffer structure.
82  * @param buf
83  *   The buffer used to store the data.
84  * @param start
85  *   The index of head at initialization.
86  * @param maxlen
87  *   The size of the buffer.
88  */
89 void ucg_cirbuf_init(struct ucg_cirbuf *cbuf, char *buf, unsigned start,
90         unsigned maxlen);
91
92 /**
93  * Check if the circular buffer is full.
94  *
95  * @param cbuf
96  *   The circular buffer pointer.
97  * @return
98  *   1 if the circular buffer is full, else 0.
99  */
100 static inline int ucg_cirbuf_is_full(const struct ucg_cirbuf *cbuf)
101 {
102         return cbuf->len == cbuf->maxlen;
103 }
104
105 /**
106  * Check if the circular buffer is empty.
107  *
108  * @param cbuf
109  *   The circular buffer pointer.
110  * @return
111  *   1 if the circular buffer is empty, else 0.
112  */
113 static inline int ucg_cirbuf_is_empty(const struct ucg_cirbuf *cbuf)
114 {
115         return cbuf->len == 0;
116 }
117
118 /**
119  * Get the length of data in the circular buffer.
120  *
121  * @param cbuf
122  *   The circular buffer pointer.
123  * @return
124  *   The current length of data in the circular buffer.
125  */
126 static inline unsigned ucg_cirbuf_get_len(const struct ucg_cirbuf *cbuf)
127 {
128         return cbuf->len;
129 }
130
131 /**
132  * Get the size of the circular buffer.
133  *
134  * @param cbuf
135  *   The circular buffer pointer.
136  * @return
137  *   Return the maximum size of the circular buffer (used + free elements)
138  */
139 static inline unsigned ucg_cirbuf_get_maxlen(const struct ucg_cirbuf *cbuf)
140 {
141         return cbuf->maxlen;
142 }
143
144 /**
145  * Get the lenght of free space in the circular buffer.
146  *
147  * @param cbuf
148  *   The circular buffer pointer.
149  * @return
150  *   Return the length of free space.
151  */
152 static inline unsigned ucg_cirbuf_get_freelen(const struct ucg_cirbuf *cbuf)
153 {
154         return cbuf->maxlen - cbuf->len;
155 }
156
157 /**
158  * Iterator for a circular buffer
159  *
160  *   cirbuf: struct cirbuf pointer
161  *   i: an integer internally used in the macro
162  *   elt: char that takes the value for each iteration
163  */
164 #define UCG_CIRBUF_FOREACH(cirbuf, i, elt)                              \
165         for (i = 0, elt = (cirbuf)->buf[(cirbuf)->start];               \
166              i < ((cirbuf)->len);                                       \
167              i ++,  elt = (cirbuf)->buf[((cirbuf)->start + i) %         \
168                      ((cirbuf)->maxlen)])
169
170 /**
171  * Add a character at the head of the circular buffer.
172  *
173  * @param cbuf
174  *   The circular buffer pointer.
175  * @param c
176  *   The character to add.
177  * @return
178  *   Return 0 on success, or a negative value on error.
179  */
180 int ucg_cirbuf_add_head_safe(struct ucg_cirbuf *cbuf, char c);
181
182 /**
183  * Add a character at the head of the circular buffer.
184  *
185  * The function does not check that there is enough free space
186  * in the buffer, so it has to be done by the caller. If it's
187  * not the case, undefined behavior will occur.
188  *
189  * @param cbuf
190  *   The circular buffer pointer.
191  * @param c
192  *   The character to add.
193  */
194 void ucg_cirbuf_add_head(struct ucg_cirbuf *cbuf, char c);
195
196 /**
197  * Add a character at the tail of the circular buffer.
198  *
199  * @param cbuf
200  *   The circular buffer pointer.
201  * @param c
202  *   The character to add.
203  * @return
204  *   Return 0 on success, or a negative value on error.
205  */
206 int ucg_cirbuf_add_tail_safe(struct ucg_cirbuf *cbuf, char c);
207
208 /**
209  * Add a character at the tail of the circular buffer.
210  *
211  * The function does not check that there is enough free space
212  * in the buffer, so it has to be done by the caller. If it's
213  * not the case, undefined behavior will occur.
214  *
215  * @param cbuf
216  *   The circular buffer pointer.
217  * @param c
218  *   The character to add.
219  */
220 void ucg_cirbuf_add_tail(struct ucg_cirbuf *cbuf, char c);
221
222 /**
223  * Remove a char at the head of the circular buffer.
224  *
225  * @param cbuf
226  *   The circular buffer pointer.
227  * @return
228  *   Return 0 on success, or a negative value on error.
229  */
230 int ucg_cirbuf_del_head_safe(struct ucg_cirbuf *cbuf);
231
232 /**
233  * Remove a char at the head of the circular buffer.
234  *
235  * The function does not check that there is enough elements
236  * in the buffer, so it has to be done by the caller. If it's
237  * not the case, undefined behavior will occur.
238  *
239  * @param cbuf
240  *   The circular buffer pointer.
241  */
242 void ucg_cirbuf_del_head(struct ucg_cirbuf *cbuf);
243
244 /**
245  * Remove a char at the tail of the circular buffer.
246  *
247  * @param cbuf
248  *   The circular buffer pointer.
249  * @return
250  *   Return 0 on success, or a negative value on error.
251  */
252 int ucg_cirbuf_del_tail_safe(struct ucg_cirbuf *cbuf);
253
254 /**
255  * Remove a char at the tail of the circular buffer.
256  *
257  * The function does not check that there is enough elements
258  * in the buffer, so it has to be done by the caller. If it's
259  * not the case, undefined behavior will occur.
260  *
261  * @param cbuf
262  *   The circular buffer pointer.
263  */
264 void ucg_cirbuf_del_tail(struct ucg_cirbuf *cbuf);
265
266 /**
267  * Return the element at the tail of the circular buffer.
268  *
269  * The circular buffer must not be empty or an undefined character
270  * will be returned.
271  *
272  * @param cbuf
273  *   The circular buffer pointer.
274  * @return
275  *   The character at the tail of the circular buffer.
276  */
277 char ucg_cirbuf_get_head(const struct ucg_cirbuf *cbuf);
278
279 /**
280  * Return the element at the tail of the circular buffer.
281  *
282  * The circular buffer must not be empty or an undefined character
283  * will be returned.
284  *
285  * @param cbuf
286  *   The circular buffer pointer.
287  * @return
288  *   The character at the tail of the circular buffer.
289  */
290 char ucg_cirbuf_get_tail(const struct ucg_cirbuf *cbuf);
291
292 /**
293  * Add a buffer at the head of the circular buffer.
294  *
295  * Add 'n' bytes of buffer pointed by 'buf' ad the head of th
296  * circular buffer.
297  *
298  * @param cbuf
299  *   The circular buffer pointer.
300  * @param buf
301  *   The pointer to the buffer.
302  * @param n
303  *   Number of bytes to add.
304  * @return
305  *   Return 0 on success, or a negative value on error.
306  */
307 int ucg_cirbuf_add_buf_head(struct ucg_cirbuf *cbuf, const char *buf,
308         unsigned n);
309
310 /**
311  * Add a buffer at the tail of the circular buffer.
312  *
313  * Add 'n' bytes of buffer pointed by 'buf' ad the tail of th
314  * circular buffer.
315  *
316  * @param cbuf
317  *   The circular buffer pointer.
318  * @param buf
319  *   The pointer to the buffer.
320  * @param n
321  *   Number of bytes to add.
322  * @return
323  *   Return 0 on success, or a negative value on error.
324  */
325 int ucg_cirbuf_add_buf_tail(struct ucg_cirbuf *cbuf, const char *buf,
326         unsigned n);
327
328 /**
329  * Remove chars at the head of the circular buffer.
330  *
331  * @param cbuf
332  *   The circular buffer pointer.
333  * @param n
334  *   Number of bytes to remove.
335  * @return
336  *   Return 0 on success, or a negative value on error.
337  */
338 int ucg_cirbuf_del_buf_head(struct ucg_cirbuf *cbuf, unsigned n);
339
340 /**
341  * Remove chars at the tail of the circular buffer.
342  *
343  * @param cbuf
344  *   The circular buffer pointer.
345  * @param n
346  *   Number of bytes to remove.
347  * @return
348  *   Return 0 on success, or a negative value on error.
349  */
350 int ucg_cirbuf_del_buf_tail(struct ucg_cirbuf *cbuf, unsigned n);
351
352 /**
353  * Copy multiple bytes from the head of the circular buffer.
354  *
355  * Copy a maximum of 'n' characters from the head of the circular buffer
356  * into a flat buffer pointed by 'buf'. If the circular buffer is
357  * smaller than n, less bytes are copied.
358  *
359  * @param cbuf
360  *   The circular buffer pointer.
361  * @param buf
362  *   The pointer to the buffer.
363  * @param n
364  *   Maximum number of bytes to copy.
365  * @return
366  *   Return the number of copied chars.
367  */
368 int ucg_cirbuf_get_buf_head(const struct ucg_cirbuf *cbuf, char *buf,
369         unsigned n);
370
371 /**
372  * Copy multiple bytes from the tail of the circular buffer.
373  *
374  * Copy a maximum of 'n' characters from the tail of the circular buffer
375  * into a flat buffer pointed by 'buf'. If the circular buffer is
376  * smaller than n, less bytes are copied.
377  *
378  * @param cbuf
379  *   The circular buffer pointer.
380  * @param buf
381  *   The pointer to the buffer.
382  * @param n
383  *   Maximum number of bytes to copy.
384  * @return
385  *   Return the number of copied chars.
386  */
387 int ucg_cirbuf_get_buf_tail(const struct ucg_cirbuf *cbuf, char *buf,
388         unsigned n);
389
390 /**
391  * Set the start of the data to the index 0 of the internal buffer.
392  *
393  * After a call to this function, it is possible for the caller to
394  * use cbuf->buf as a linear (read-only) buffer.
395  *
396  * @param cbuf
397  *   The circular buffer pointer.
398  */
399 void ucg_cirbuf_align_left(struct ucg_cirbuf *cbuf);
400
401 /**
402  * Set the end of the data to the last index of the internal buffer.
403  *
404  * After a call to this function, it is possible for the caller to
405  * use cbuf->buf as a linear (read-only) buffer.
406  *
407  * @param cbuf
408  *   The circular buffer pointer.
409  */
410 void ucg_cirbuf_align_right(struct ucg_cirbuf *cbuf);
411
412 #endif /* CIRBUF_H_ */