c68e2485b9c076553c8fc37c50bd95119289bb66
[libcmdline.git] / src / lib / cmdline_cirbuf.h
1 /*
2  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
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 #ifndef _CIRBUF_H_
29 #define _CIRBUF_H_
30
31 #include <stdio.h>
32
33 /**
34  * This structure is the header of a cirbuf type.
35  */
36 struct cirbuf {
37         unsigned int maxlen;    /**< total len of the fifo (number of elements) */
38         unsigned int start;     /**< indice of the first elt */
39         unsigned int end;       /**< indice of the last elt */
40         unsigned int len;       /**< current len of fifo */
41         char *buf;
42 };
43
44 /* #define CIRBUF_DEBUG */
45
46 #ifdef CIRBUF_DEBUG
47 #define dprintf(fmt, ...) printf("line %3.3d - " fmt, __LINE__, ##__VA_ARGS__)
48 #else
49 #define dprintf(args...) do {} while(0)
50 #endif
51
52
53 /**
54  * Init the circular buffer
55  */
56 void cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen);
57
58
59 /**
60  * Return 1 if the circular buffer is full
61  */
62 #define CIRBUF_IS_FULL(cirbuf) ((cirbuf)->maxlen == (cirbuf)->len)
63
64 /**
65  * Return 1 if the circular buffer is empty
66  */
67 #define CIRBUF_IS_EMPTY(cirbuf) ((cirbuf)->len == 0)
68
69 /**
70  * return current size of the circular buffer (number of used elements)
71  */
72 #define CIRBUF_GET_LEN(cirbuf) ((cirbuf)->len)
73
74 /**
75  * return size of the circular buffer (used + free elements)
76  */
77 #define CIRBUF_GET_MAXLEN(cirbuf) ((cirbuf)->maxlen)
78
79 /**
80  * return the number of free elts 
81  */
82 #define CIRBUF_GET_FREELEN(cirbuf) ((cirbuf)->maxlen - (cirbuf)->len)
83
84 /**
85  * Iterator for a circular buffer
86  *   c: struct cirbuf pointer
87  *   i: an integer type internally used in the macro
88  *   e: char that takes the value for each iteration
89  */
90 #define CIRBUF_FOREACH(c, i, e)                                 \
91         for ( i=0, e=(c)->buf[(c)->start] ;                     \
92               i<((c)->len) ;                                    \
93               i ++,  e=(c)->buf[((c)->start+i)%((c)->maxlen)])
94
95
96 /** 
97  * Add a character at head of the circular buffer. Return 0 on success, or
98  * a negative value on error.
99  */
100 int cirbuf_add_head_safe(struct cirbuf *cbuf, char c);
101
102 /** 
103  * Add a character at head of the circular buffer. You _must_ check that you
104  * have enough free space in the buffer before calling this func.
105  */
106 void cirbuf_add_head(struct cirbuf *cbuf, char c);
107
108 /** 
109  * Add a character at tail of the circular buffer. Return 0 on success, or
110  * a negative value on error.
111  */
112 int cirbuf_add_tail_safe(struct cirbuf *cbuf, char c);
113
114 /** 
115  * Add a character at tail of the circular buffer. You _must_ check that you
116  * have enough free space in the buffer before calling this func.
117  */
118 void cirbuf_add_tail(struct cirbuf *cbuf, char c);
119
120 /** 
121  * Remove a char at the head of the circular buffer. Return 0 on
122  * success, or a negative value on error.
123  */
124 int cirbuf_del_head_safe(struct cirbuf *cbuf);
125
126 /** 
127  * Remove a char at the head of the circular buffer. You _must_ check
128  * that buffer is not empty before calling the function.
129  */
130 void cirbuf_del_head(struct cirbuf *cbuf);
131
132 /** 
133  * Remove a char at the tail of the circular buffer. Return 0 on
134  * success, or a negative value on error.
135  */
136 int cirbuf_del_tail_safe(struct cirbuf *cbuf);
137
138 /** 
139  * Remove a char at the tail of the circular buffer. You _must_ check
140  * that buffer is not empty before calling the function.
141  */
142 void cirbuf_del_tail(struct cirbuf *cbuf);
143
144 /**
145  * Return the head of the circular buffer. You _must_ check that
146  * buffer is not empty before calling the function.
147  */
148 char cirbuf_get_head(struct cirbuf *cbuf);
149
150 /**
151  * Return the tail of the circular buffer. You _must_ check that
152  * buffer is not empty before calling the function.
153  */
154 char cirbuf_get_tail(struct cirbuf *cbuf);
155
156 /** 
157  * Add a buffer at head of the circular buffer. 'c' is a pointer to a
158  * buffer, and n is the number of char to add. Return the number of
159  * copied bytes on success, or a negative value on error.
160  */
161 int cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n);
162
163 /** 
164  * Add a buffer at tail of the circular buffer. 'c' is a pointer to a
165  * buffer, and n is the number of char to add. Return the number of
166  * copied bytes on success, or a negative value on error.
167  */
168 int cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n);
169
170 /** 
171  * Remove chars at the head of the circular buffer. Return 0 on
172  * success, or a negative value on error.
173  */
174 int cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size);
175
176 /** 
177  * Remove chars at the tail of the circular buffer. Return 0 on
178  * success, or a negative value on error.
179  */
180 int cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size);
181
182 /** 
183  * Copy a maximum of 'size' characters from the head of the circular
184  * buffer to a flat one pointed by 'c'. Return the number of copied
185  * chars.
186  */
187 int cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size);
188
189 /** 
190  * Copy a maximum of 'size' characters from the tail of the circular
191  * buffer to a flat one pointed by 'c'. Return the number of copied
192  * chars.
193  */
194 int cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size);
195
196
197 /** 
198  * Set the start of the data to the index 0 of the internal buffer.
199  */
200 void cirbuf_align_left(struct cirbuf *cbuf);
201
202 /** 
203  * Set the end of the data to the last index of the internal buffer.
204  */
205 void cirbuf_align_right(struct cirbuf *cbuf);
206
207 #endif /* _CIRBUF_H_ */