modified: myjupyterlab.sh
[GalaxyCodeBases.git] / c_cpp / lib / uthash / libut / src / ringbuf.c
blob72eb0d4da7d71448264ff0fd0007ed0a4366f13d
1 #include "ringbuf.h"
3 ringbuf *ringbuf_new(size_t sz) {
4 ringbuf *r = malloc(sizeof(*r) + sz);
5 if (r == NULL) {
6 fprintf(stderr,"out of memory\n");
7 goto done;
10 r->u = r->i = r->o = 0;
11 r->n = sz;
13 done:
14 return r;
17 void ringbuf_free(ringbuf* r) {
18 free(r);
21 /* copy data in. fails if ringbuf has insuff space. */
22 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
23 int ringbuf_put(ringbuf *r, const void *_data, size_t len) {
24 char *data = (char*)_data;
25 size_t a,b,c;
26 if (r->i < r->o) { // available space is a contiguous buffer
27 a = r->o - r->i;
28 assert(a == r->n - r->u);
29 if (len > a) return -1;
30 memcpy(&r->d[r->i], data, len);
31 } else { // available space wraps; it's two buffers
32 b = r->n - r->i; // in-head to eob (receives leading input)
33 c = r->o; // out-head to in-head (receives trailing input)
34 a = b + c; // available space
35 // the only ambiguous case is i==o, that's why u is needed
36 if (r->i == r->o) a = r->n - r->u;
37 assert(a == r->n - r->u);
38 if (len > a) return -1;
39 memcpy(&r->d[r->i], data, MIN(b, len));
40 if (len > b) memcpy(r->d, &data[b], len-b);
42 r->i = (r->i + len) % r->n;
43 r->u += len;
44 return 0;
47 size_t ringbuf_get_pending_size(ringbuf *r) {
48 return r->u;
51 size_t ringbuf_get_next_chunk(ringbuf *r, char **data) {
52 // in this case the next chunk is the whole pending buffer
53 if (r->o < r->i) {
54 assert(r->u == r->i - r->o);
55 *data = &r->d[r->o];
56 return r->u;
58 // in this case (i==o) either the buffer is empty of full.
59 // r->u tells distinguishes these cases.
60 if ((r->o == r->i) && (r->u == 0)) { *data=NULL; return 0; }
61 // if we're here, that means r->o > r->i. the pending
62 // output is wrapped around the buffer. this function
63 // returns the chunk prior to eob. the next call gets
64 // the next chunk that's wrapped around the buffer.
65 size_t b,c;
66 b = r->n - r->o; // length of the part we're returning
67 c = r->i; // wrapped part length- a sanity check
68 assert(r->u == b + c);
69 *data = &r->d[r->o];
70 return b;
73 void ringbuf_mark_consumed(ringbuf *r, size_t len) {
74 assert(len <= r->u);
75 r->o = (r->o + len ) % r->n;
76 r->u -= len;
79 void ringbuf_clear(ringbuf *r) {
80 r->u = r->i = r->o = 0;