• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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