1 #include "iwrb.h"
2
3 #include <stdlib.h>
4 #include <string.h>
5
iwrb_create(size_t usize,size_t len)6 IWRB* iwrb_create(size_t usize, size_t len) {
7 IWRB *rb = malloc(sizeof(*rb) + usize * len);
8 if (!rb) {
9 return 0;
10 }
11 rb->pos = 0;
12 rb->len = len;
13 rb->usize = usize;
14 rb->buf = (char*) rb + sizeof(*rb);
15 return rb;
16 }
17
iwrb_destroy(IWRB ** rbp)18 void iwrb_destroy(IWRB **rbp) {
19 if (rbp && *rbp) {
20 free(*rbp);
21 *rbp = 0;
22 }
23 }
24
iwrb_wrap(void * buf,size_t len,size_t usize)25 IWRB* iwrb_wrap(void *buf, size_t len, size_t usize) {
26 if (buf == 0 || len < sizeof(IWRB) + usize) {
27 return 0;
28 }
29 IWRB *rb = buf;
30 rb->pos = 0;
31 rb->len = (len - sizeof(IWRB)) / usize;
32 rb->usize = usize;
33 rb->buf = (char*) buf + sizeof(*rb);
34 return rb;
35 }
36
iwrb_put(IWRB * rb,const void * buf)37 void iwrb_put(IWRB *rb, const void *buf) {
38 if (rb->pos != 0) {
39 size_t upos = rb->pos > 0 ? rb->pos : -rb->pos;
40 if (upos == rb->len) {
41 memcpy(rb->buf, buf, rb->usize);
42 rb->pos = 1;
43 } else {
44 memcpy(rb->buf + upos * rb->usize, buf, rb->usize);
45 rb->pos = rb->pos > 0 ? rb->pos + 1 : rb->pos - 1;
46 }
47 } else {
48 memcpy(rb->buf, buf, rb->usize);
49 rb->pos = -1;
50 }
51 }
52
iwrb_back(IWRB * rb)53 void iwrb_back(IWRB *rb) {
54 if (rb->pos > 0) {
55 --rb->pos;
56 } else if (rb->pos < 0) {
57 ++rb->pos;
58 }
59 }
60
iwrb_peek(const IWRB * rb)61 void* iwrb_peek(const IWRB *rb) {
62 if (rb->pos == 0) {
63 return 0;
64 }
65 size_t upos = rb->pos > 0 ? rb->pos : -rb->pos;
66 return rb->buf + (upos - 1) * rb->usize;
67 }
68
iwrb_clear(IWRB * rb)69 void iwrb_clear(IWRB *rb) {
70 rb->pos = 0;
71 }
72
iwrb_num_cached(const IWRB * rb)73 size_t iwrb_num_cached(const IWRB *rb) {
74 if (rb->pos <= 0) {
75 return -rb->pos;
76 } else {
77 return rb->len;
78 }
79 }
80
iwrb_iter_init(const IWRB * rb,IWRB_ITER * iter)81 void iwrb_iter_init(const IWRB *rb, IWRB_ITER *iter) {
82 iter->rb = rb;
83 iter->pos = rb->pos > 0 ? rb->pos : -rb->pos;
84 iter->ipos = rb->pos > 0 ? -rb->pos : rb->pos;
85 }
86
iwrb_iter_prev(IWRB_ITER * iter)87 void* iwrb_iter_prev(IWRB_ITER *iter) {
88 const IWRB *rb = iter->rb;
89 if (iter->ipos == 0) {
90 return 0;
91 }
92 if (rb->pos < 0) {
93 if (iter->pos == 0) {
94 return 0;
95 }
96 if (iter->ipos < 0) {
97 iter->ipos = -iter->ipos;
98 }
99 return rb->buf + --iter->pos * rb->usize;
100 } else {
101 if (iter->pos == 0) {
102 iter->pos = rb->len;
103 }
104 if (iter->ipos < 0) {
105 iter->ipos = -iter->ipos;
106 } else if (iter->ipos == iter->pos) {
107 iter->ipos = 0;
108 return 0;
109 }
110 return rb->buf + --iter->pos * rb->usize;
111 }
112 }
113