19#define isPowerOfTwo(x) ((x != 0) && ((x & (~x + 1)) == x))
38 if (buf->
iStop == 0) {
46 const size_t capacity, uint8_t *buffer) {
47 if (!isPowerOfTwo(capacity)) {
48 Throw(ASC_ERROR_CB_BAD_CAPACITY);
55 for (
size_t i = 0; i < capacity; i++) {
61 return circ_buf->
size;
74 FILE *outfile, uint8_t verbosity) {
75 fprintf(outfile,
"circular_buffer_uint8, capacity: %zu size: %zu",
78 fprintf(outfile,
" iStart: %zu iStop %zu buffer: %p\n", circ_buf->
iStart,
82 fprintf(outfile,
" Content: [ ");
83 for (
size_t i = 0; i < circ_buf->
size; i++) {
84 fprintf(outfile,
"%" PRIu8
" ",
87 fprintf(outfile,
"]\n");
90 fprintf(outfile,
" Raw Memory: [ ");
91 for (
size_t i = 0; i < circ_buf->
capacity; i++) {
92 fprintf(outfile,
"%" PRIu8
" ", *(circ_buf->
buffer + i));
94 fprintf(outfile,
"]\n");
96 fprintf(outfile,
" Content as string: ");
97 for (
size_t i = 0; i < circ_buf->
size; i++) {
99 if (thisChar == 0x0A) {
100 fprintf(outfile,
"\\n");
101 }
else if (thisChar < 0x20 || thisChar >= 0x7F) {
102 fprintf(outfile,
"\\x%02" PRIX8, thisChar);
104 fprintf(outfile,
"%c", thisChar);
107 fprintf(outfile,
"\n");
108 if (verbosity >= 1) {
109 fprintf(outfile,
" Raw memory as string: ");
110 for (
size_t i = 0; i < circ_buf->
capacity; i++) {
111 uint8_t thisChar = *(circ_buf->
buffer + i);
112 if (thisChar == 0x0A) {
113 fprintf(outfile,
"\\n");
114 }
else if (thisChar < 0x20 || thisChar >= 0x7F) {
115 fprintf(outfile,
"\\x%02" PRIX8, thisChar);
117 fprintf(outfile,
"%c", thisChar);
120 fprintf(outfile,
"\n");
127 const size_t iElement) {
130 Throw(ASC_ERROR_CB_OOB);
132 size_t iResult = (circ_buf->
iStart + iElement) & (circ_buf->
capacity - 1);
133 uint8_t result = *(circ_buf->
buffer + iResult);
138 const uint8_t element) {
139 dec_iStart_uint8(circ_buf);
142 dec_iStop_uint8(circ_buf);
149 const uint8_t element) {
151 inc_iStop_uint8(circ_buf);
153 inc_iStart_uint8(circ_buf);
160 if (circ_buf->
size == 0) {
161 Throw(ASC_ERROR_CB_POP_EMPTY);
163 const uint8_t result = *(circ_buf->
buffer + circ_buf->
iStart);
164 inc_iStart_uint8(circ_buf);
170 if (circ_buf->
size == 0) {
171 Throw(ASC_ERROR_CB_POP_EMPTY);
173 dec_iStop_uint8(circ_buf);
175 const uint8_t result = *(circ_buf->
buffer + circ_buf->
iStop);
181 const bool inclusive) {
182 while (circ_buf->
size > 0) {
184 if (iValue == value) {
197 const bool inclusive) {
198 while (circ_buf->
size > 0) {
201 if (iValue == value) {
213 const uint8_t value) {
215 for (iElement = 0; iElement < circ_buf->
size; iElement++) {
217 if (iValue == value) {
221 return circ_buf->
size;
225 const uint8_t value) {
226 size_t iElement = circ_buf->
size;
227 while (iElement > 0) {
230 if (iValue == value) {
234 return circ_buf->
size;
238 const uint8_t value) {
240 for (
size_t iElement = 0; iElement < circ_buf->
size; iElement++) {
242 if (iValue == value) {
251 const uint8_t **outBlock) {
256 return circ_buf->
size;
264 for (
size_t i = 0; i < toPop; i++) {
269 const size_t origSize = circ_buf->
size;
278 const uint8_t *source,
279 size_t source_size) {
280 for (
size_t iElement = 0; iElement < source_size; iElement++) {
286 uint8_t *destination,
288 uint8_t *outBlock = circ_buf->
buffer + circ_buf->
iStart;
293 nBlock = circ_buf->
size;
295 const size_t nWritten = dest_size < nBlock ? dest_size : nBlock;
296 for (
size_t iByte = 0; iByte < nWritten; iByte++) {
297 destination[iByte] = outBlock[iByte];
299 circ_buf->
size -= nWritten;
300 if (circ_buf->
size == 0) {
312 size_t block_size_available;
313 uint8_t *block_start = circ_buf->
buffer + circ_buf->
iStop;
317 block_size_available = circ_buf->
iStart - circ_buf->
iStop;
319 ssize_t nRead = read(fd, block_start, block_size_available);
321 perror(
"circular_buffer_push_back_from_fd_uint8 error while reading from "
323 Throw(ASC_ERROR_FILE_READ);
326 circ_buf->
size += nRead;
340 uint8_t *outBlock = circ_buf->
buffer + circ_buf->
iStart;
345 nBlock = circ_buf->
size;
347 ssize_t nWritten = write(fd, outBlock, nBlock);
349 perror(
"circular_buffer_pop_front_to_fd_uint8 error while writing to "
351 Throw(ASC_ERROR_FILE_WRITE);
353 circ_buf->
size -= nWritten;
354 if (circ_buf->
size == 0) {
371 const char *
string) {
375 const char *pChar =
string + iChar;
376 if ((*pChar) ==
'\0') {
388 if (iEnd >= circ_buf->
size) {
389 const size_t iLastStart =
391 if (iLastStart >= circ_buf->
size) {
392 const size_t bufSize = circ_buf->
size;
396 for (
size_t i = 0; i < iLastStart; i++) {
404 circ_buf, startChar, endChar);
406 size_t iElement = iEnd - 1;
412 for (
size_t i = 0; i <= iEnd; i++) {
417 circ_buf, startChar, endChar);
422 for (
size_t i = 0; i < iElement; i++) {
429 size_t iStart,
size_t nElem,
431 size_t *blocks_sizes) {
433 Throw(ASC_ERROR_CB_OOB);
435 bool wraps = circ_buf->
iStart + iStart + nElem > circ_buf->
capacity;
436 blocks[0] = circ_buf->
buffer + circ_buf->
iStart + iStart;
438 blocks[1] = circ_buf->
buffer;
440 blocks_sizes[1] = nElem - blocks_sizes[0];
444 blocks_sizes[0] = nElem;
size_t circular_buffer_pop_front_to_fd_uint8(circular_buffer_uint8 *circ_buf, const int fd)
circular buffer pop front writing to file descriptor
uint8_t circular_buffer_pop_back_uint8(circular_buffer_uint8 *circ_buf)
circular buffer pop back
void circular_buffer_remove_front_to_uint8(circular_buffer_uint8 *circ_buf, const uint8_t value, const bool inclusive)
circular buffer remove elements from front until you find the given value
size_t circular_buffer_count_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t value)
circular buffer count the number of a given value
size_t circular_buffer_get_size_uint8(const circular_buffer_uint8 *circ_buf)
circular buffer get number of elements
size_t circular_buffer_pop_front_block_uint8(circular_buffer_uint8 *circ_buf, uint8_t *destination, size_t dest_size)
circular buffer pop from front into a block of memory
void circular_buffer_init_uint8(circular_buffer_uint8 *circ_buf, const size_t capacity, uint8_t *buffer)
circular buffer init method
size_t circular_buffer_remove_front_unfinished_frames_uint8(circular_buffer_uint8 *circ_buf, const char startChar, const char endChar)
circular buffer remove unfinished frames from front of buffer
size_t circular_buffer_get_blocks_uint8(circular_buffer_uint8 *circ_buf, size_t iStart, size_t nElem, uint8_t **blocks, size_t *blocks_sizes)
circular buffer access raw blocks of data for a given range of elements
size_t circular_buffer_push_back_from_fd_uint8(circular_buffer_uint8 *circ_buf, int fd)
circular buffer push back reading from file descriptor
uint8_t circular_buffer_get_element_uint8(const circular_buffer_uint8 *circ_buf, const size_t iElement)
circular buffer get element
size_t circular_buffer_find_first_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t value)
circular buffer find index of first occurance of value
uint8_t circular_buffer_pop_front_uint8(circular_buffer_uint8 *circ_buf)
circular buffer pop front
bool circular_buffer_is_full_uint8(const circular_buffer_uint8 *circ_buf)
circular buffer get if full
size_t circular_buffer_get_first_block_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t **outBlock)
circular buffer get first block
void circular_buffer_remove_back_to_uint8(circular_buffer_uint8 *circ_buf, const uint8_t value, const bool inclusive)
circular buffer remove elements from back until you find the given value
size_t circular_buffer_delete_first_block_uint8(circular_buffer_uint8 *circ_buf)
circular buffer delete first block
size_t circular_buffer_push_back_string_uint8(circular_buffer_uint8 *circ_buf, const char *string)
circular buffer push back string (null terminated)
void circular_buffer_clear_uint8(circular_buffer_uint8 *circ_buf)
circular buffer clear
size_t circular_buffer_find_last_uint8(const circular_buffer_uint8 *circ_buf, const uint8_t value)
circular buffer find index of last occurance of value
bool circular_buffer_is_empty_uint8(const circular_buffer_uint8 *circ_buf)
circular buffer get if empty
void circular_buffer_push_front_uint8(circular_buffer_uint8 *circ_buf, const uint8_t element)
circular buffer push front
void circular_buffer_push_back_block_uint8(circular_buffer_uint8 *circ_buf, const uint8_t *source, size_t source_size)
circular buffer push a block of memory on back
void circular_buffer_push_back_uint8(circular_buffer_uint8 *circ_buf, const uint8_t element)
circular buffer push back
void circular_buffer_print_uint8(const circular_buffer_uint8 *circ_buf, FILE *outfile, uint8_t verbosity)
circular buffer print contents