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