4 * Copyright(c) 2010-2012 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * version: DPDK.L.1.2.3-3
37 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
38 * All rights reserved.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions are met:
42 * * Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * * Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 * * Neither the name of the University of California, Berkeley nor the
48 * names of its contributors may be used to endorse or promote products
49 * derived from this software without specific prior written permission.
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
55 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
66 #include "cmdline_cirbuf.h"
70 cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen)
72 cbuf->maxlen = maxlen;
82 cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n)
86 if (!n || n > CIRBUF_GET_FREELEN(cbuf))
89 e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
91 if (n < cbuf->start + e) {
92 dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->start - n + e, n);
93 memcpy(cbuf->buf + cbuf->start - n + e, c, n);
96 dprintf("s[%d] -> d[%d] (%d)\n", + n - (cbuf->start + e), 0,
98 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - n +
99 (cbuf->start + e), 0, n - (cbuf->start + e));
100 memcpy(cbuf->buf, c + n - (cbuf->start + e) , cbuf->start + e);
101 memcpy(cbuf->buf + cbuf->maxlen - n + (cbuf->start + e), c,
102 n - (cbuf->start + e));
105 cbuf->start += (cbuf->maxlen - n + e);
106 cbuf->start %= cbuf->maxlen;
113 cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n)
117 if (!n || n > CIRBUF_GET_FREELEN(cbuf))
120 e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
122 if (n < cbuf->maxlen - cbuf->end - 1 + e) {
123 dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end + !e, n);
124 memcpy(cbuf->buf + cbuf->end + !e, c, n);
127 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end + !e, 0,
128 cbuf->maxlen - cbuf->end - 1 + e);
129 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - cbuf->end - 1 +
130 e, 0, n - cbuf->maxlen + cbuf->end + 1 - e);
131 memcpy(cbuf->buf + cbuf->end + !e, c, cbuf->maxlen -
133 memcpy(cbuf->buf, c + cbuf->maxlen - cbuf->end - 1 + e,
134 n - cbuf->maxlen + cbuf->end + 1 - e);
138 cbuf->end %= cbuf->maxlen;
145 __cirbuf_add_head(struct cirbuf * cbuf, char c)
147 if (!CIRBUF_IS_EMPTY(cbuf)) {
148 cbuf->start += (cbuf->maxlen - 1);
149 cbuf->start %= cbuf->maxlen;
151 cbuf->buf[cbuf->start] = c;
156 cirbuf_add_head_safe(struct cirbuf * cbuf, char c)
158 if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
159 __cirbuf_add_head(cbuf, c);
166 cirbuf_add_head(struct cirbuf * cbuf, char c)
168 __cirbuf_add_head(cbuf, c);
174 __cirbuf_add_tail(struct cirbuf * cbuf, char c)
176 if (!CIRBUF_IS_EMPTY(cbuf)) {
178 cbuf->end %= cbuf->maxlen;
180 cbuf->buf[cbuf->end] = c;
185 cirbuf_add_tail_safe(struct cirbuf * cbuf, char c)
187 if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
188 __cirbuf_add_tail(cbuf, c);
195 cirbuf_add_tail(struct cirbuf * cbuf, char c)
197 __cirbuf_add_tail(cbuf, c);
202 __cirbuf_shift_left(struct cirbuf *cbuf)
205 char tmp = cbuf->buf[cbuf->start];
207 for (i=0 ; i<cbuf->len ; i++) {
208 cbuf->buf[(cbuf->start+i)%cbuf->maxlen] =
209 cbuf->buf[(cbuf->start+i+1)%cbuf->maxlen];
211 cbuf->buf[(cbuf->start-1+cbuf->maxlen)%cbuf->maxlen] = tmp;
212 cbuf->start += (cbuf->maxlen - 1);
213 cbuf->start %= cbuf->maxlen;
214 cbuf->end += (cbuf->maxlen - 1);
215 cbuf->end %= cbuf->maxlen;
219 __cirbuf_shift_right(struct cirbuf *cbuf)
222 char tmp = cbuf->buf[cbuf->end];
224 for (i=0 ; i<cbuf->len ; i++) {
225 cbuf->buf[(cbuf->end+cbuf->maxlen-i)%cbuf->maxlen] =
226 cbuf->buf[(cbuf->end+cbuf->maxlen-i-1)%cbuf->maxlen];
228 cbuf->buf[(cbuf->end+1)%cbuf->maxlen] = tmp;
230 cbuf->start %= cbuf->maxlen;
232 cbuf->end %= cbuf->maxlen;
235 /* XXX we could do a better algorithm here... */
236 void cirbuf_align_left(struct cirbuf * cbuf)
238 if (cbuf->start < cbuf->maxlen/2) {
239 while (cbuf->start != 0) {
240 __cirbuf_shift_left(cbuf);
244 while (cbuf->start != 0) {
245 __cirbuf_shift_right(cbuf);
250 /* XXX we could do a better algorithm here... */
251 void cirbuf_align_right(struct cirbuf * cbuf)
253 if (cbuf->start >= cbuf->maxlen/2) {
254 while (cbuf->end != cbuf->maxlen-1) {
255 __cirbuf_shift_left(cbuf);
259 while (cbuf->start != cbuf->maxlen-1) {
260 __cirbuf_shift_right(cbuf);
268 cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size)
270 if (!size || size > CIRBUF_GET_LEN(cbuf))
274 if (CIRBUF_IS_EMPTY(cbuf)) {
275 cbuf->start += size - 1;
276 cbuf->start %= cbuf->maxlen;
280 cbuf->start %= cbuf->maxlen;
288 cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size)
290 if (!size || size > CIRBUF_GET_LEN(cbuf))
294 if (CIRBUF_IS_EMPTY(cbuf)) {
295 cbuf->end += (cbuf->maxlen - size + 1);
296 cbuf->end %= cbuf->maxlen;
299 cbuf->end += (cbuf->maxlen - size);
300 cbuf->end %= cbuf->maxlen;
308 __cirbuf_del_head(struct cirbuf * cbuf)
311 if (!CIRBUF_IS_EMPTY(cbuf)) {
313 cbuf->start %= cbuf->maxlen;
318 cirbuf_del_head_safe(struct cirbuf * cbuf)
320 if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
321 __cirbuf_del_head(cbuf);
328 cirbuf_del_head(struct cirbuf * cbuf)
330 __cirbuf_del_head(cbuf);
336 __cirbuf_del_tail(struct cirbuf * cbuf)
339 if (!CIRBUF_IS_EMPTY(cbuf)) {
340 cbuf->end += (cbuf->maxlen - 1);
341 cbuf->end %= cbuf->maxlen;
346 cirbuf_del_tail_safe(struct cirbuf * cbuf)
348 if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
349 __cirbuf_del_tail(cbuf);
356 cirbuf_del_tail(struct cirbuf * cbuf)
358 __cirbuf_del_tail(cbuf);
361 /* convert to buffer */
364 cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size)
368 n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
373 if (cbuf->start <= cbuf->end) {
374 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0, n);
375 memcpy(c, cbuf->buf + cbuf->start , n);
378 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0,
379 cbuf->maxlen - cbuf->start);
380 dprintf("s[%d] -> d[%d] (%d)\n", 0,cbuf->maxlen - cbuf->start,
381 n - cbuf->maxlen + cbuf->start);
382 memcpy(c, cbuf->buf + cbuf->start , cbuf->maxlen - cbuf->start);
383 memcpy(c + cbuf->maxlen - cbuf->start, cbuf->buf,
384 n - cbuf->maxlen + cbuf->start);
389 /* convert to buffer */
392 cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size)
396 n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
401 if (cbuf->start <= cbuf->end) {
402 dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end - n + 1, 0, n);
403 memcpy(c, cbuf->buf + cbuf->end - n + 1, n);
406 dprintf("s[%d] -> d[%d] (%d)\n", 0,
407 cbuf->maxlen - cbuf->start, cbuf->end + 1);
408 dprintf("s[%d] -> d[%d] (%d)\n",
409 cbuf->maxlen - n + cbuf->end + 1, 0, n - cbuf->end - 1);
411 memcpy(c + cbuf->maxlen - cbuf->start,
412 cbuf->buf, cbuf->end + 1);
413 memcpy(c, cbuf->buf + cbuf->maxlen - n + cbuf->end +1,
419 /* get head or get tail */
422 cirbuf_get_head(struct cirbuf * cbuf)
424 return cbuf->buf[cbuf->start];
427 /* get head or get tail */
430 cirbuf_get_tail(struct cirbuf * cbuf)
432 return cbuf->buf[cbuf->end];