1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| #include <stdio.h> #include <stdlib.h> #include <string.h>
* https://gist.github.com/harshkn/909546 * C Implementation of simple circular buffer, Functionality provided are add to queue, read latest * * Implementation: head, tail, and count. The major different between AndersKaloer/Harshkn is the way to detect full/empty. * The former trade with an empty slot, the latter use additional int->count. I review this because this is easier and Scott uses it too. */
typedef struct circular_buffer { void *buffer; void *buffer_end; size_t capacity; size_t count; size_t sz; void *head; void *tail; } circular_buffer;
void cb_init(circular_buffer *cb, size_t capacity, size_t sz) { cb->buffer = malloc(capacity * sz); if (cb->buffer == NULL) { } cb->buffer_end = (char *) cb->buffer + capacity * sz; cb->capacity = capacity; cb->count = 0; cb->sz = sz; cb->head = cb->buffer; cb->tail = cb->buffer; }
void cb_free(circular_buffer *cb) { free(cb->buffer); }
void cb_push_back(circular_buffer *cb, const void *item) { if (cb->count == cb->capacity) { printf("%s, %d: cb push back error. \n", __FILE__, __LINE__);
} memcpy(cb->head, item, cb->sz); printf("push data = %d\n", *(char *) cb->head); cb->head = (char*) cb->head + cb->sz; if (cb->head == cb->buffer_end) cb->head = cb->buffer; cb->count = cb->count == cb->capacity ? cb->count : cb->count + 1; }
void cb_pop_front(circular_buffer *cb, void *item) { if (cb->count == 0) { printf("%s, %d: cb_pop_front: empty cb.\n", __FILE__, __LINE__); return; } memcpy(item, cb->tail, cb->sz); printf("pop data = %d\n", *(char *) cb->tail); cb->tail = (char*) cb->tail + cb->sz; if (cb->tail == cb->buffer_end) cb->tail = cb->buffer; cb->count--; }
int cb_empty(circular_buffer *cb) { if (cb->count == 0) return 1; return 0; }
int cb_full(circular_buffer *cb) { return cb->count == cb->capacity; }
void printbuf(circular_buffer *cb) { int i = 0; for (; i < cb->capacity; ++i) printf("%d ", *(char *) (cb->buffer + i)); }
* https://github.com/kqchen/workspace/blob/21ab1c18dbf6c674437b0c89bb313ddbfc2de85c/hello/circular.c */ void cb_print(circular_buffer *cb) { int cnt = cb->count; do { if (cb->count == 0) { printf("%s, %d: cb is empty now.\n", __FILE__, __LINE__); return; } printf("cb->tail=0x%x, cb->head=0x%x, cnt = %d\n", cb->tail, cb->head, cnt); cnt--; } while (cnt > 0); }
* testing the ring buffer */ int main() { circular_buffer tony; cb_init(&tony, 4, 1); int i = 10; for (; i < 20; ++i) { cb_push_back(&tony, &i);
}
printf("\nafter filling ---\n"); cb_print(&tony);
char result; int j = 0; for (; j < 6; ++j) { cb_pop_front(&tony, &result);
} printf("\nafter pop ---\n"); cb_print(&tony); return 0; }
|