1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include "k_api.h"
6
7 #define RING_BUF_LEN sizeof(size_t)
8
ringbuf_init(k_ringbuf_t * p_ringbuf,void * buf,size_t len,size_t type,size_t block_size)9 kstat_t ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len, size_t type,
10 size_t block_size)
11 {
12 p_ringbuf->type = type;
13 p_ringbuf->buf = buf;
14 p_ringbuf->end = (uint8_t *)buf + len;
15 p_ringbuf->blk_size = block_size;
16
17 ringbuf_reset(p_ringbuf);
18
19 return RHINO_SUCCESS;
20
21 }
22
ringbuf_push(k_ringbuf_t * p_ringbuf,void * data,size_t len)23 kstat_t ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len)
24 {
25 size_t len_bytes = 0;
26 size_t split_len = 0;
27 uint8_t c_len[RING_BUF_LEN] = {0};
28
29 if (p_ringbuf->type == RINGBUF_TYPE_FIX) {
30
31 if (p_ringbuf->freesize < p_ringbuf->blk_size) {
32 return RHINO_RINGBUF_FULL;
33 }
34
35 if (p_ringbuf->tail == p_ringbuf->end) {
36 p_ringbuf->tail = p_ringbuf->buf;
37 }
38
39 memcpy(p_ringbuf->tail, data, p_ringbuf->blk_size);
40 p_ringbuf->tail += p_ringbuf->blk_size;
41 p_ringbuf->freesize -= p_ringbuf->blk_size;
42 } else {
43 if ((len == 0u) || (len >= (uint32_t) -1)) {
44 return RHINO_INV_PARAM;
45 }
46
47 len_bytes = RING_BUF_LEN;
48
49 /* for dynamic length ringbuf */
50 if (p_ringbuf->freesize < (len_bytes + len)) {
51 return RHINO_RINGBUF_FULL;
52 }
53
54 memcpy(c_len, &len, RING_BUF_LEN);
55
56 if (p_ringbuf->tail == p_ringbuf->end) {
57 p_ringbuf->tail = p_ringbuf->buf;
58 }
59
60 /* copy length data to buffer */
61 split_len = p_ringbuf->end - p_ringbuf->tail;
62 if (p_ringbuf->tail >= p_ringbuf->head &&
63 split_len < len_bytes && split_len > 0) {
64 memcpy(p_ringbuf->tail, &c_len[0], split_len);
65 len_bytes -= split_len;
66 p_ringbuf->tail = p_ringbuf->buf;
67 p_ringbuf->freesize -= split_len;
68 } else {
69 split_len = 0;
70 }
71
72 if (len_bytes > 0) {
73 memcpy(p_ringbuf->tail, &c_len[split_len], len_bytes);
74 p_ringbuf->freesize -= len_bytes;
75 p_ringbuf->tail += len_bytes;
76 }
77
78 /* copy data to ringbuf, if break by buffer end, split data and copy to buffer head*/
79 split_len = 0;
80
81 if (p_ringbuf->tail == p_ringbuf->end) {
82 p_ringbuf->tail = p_ringbuf->buf;
83 }
84
85 split_len = p_ringbuf->end - p_ringbuf->tail;
86 if (p_ringbuf->tail >= p_ringbuf->head &&
87 split_len < len && split_len > 0) {
88 memcpy(p_ringbuf->tail, data, split_len);
89 data = (uint8_t *)data + split_len;
90 len -= split_len;
91 p_ringbuf->tail = p_ringbuf->buf;
92 p_ringbuf->freesize -= split_len;
93 }
94
95 memcpy(p_ringbuf->tail, data, len);
96 p_ringbuf->tail += len;
97 p_ringbuf->freesize -= len;
98 }
99
100 return RHINO_SUCCESS;
101 }
102
ringbuf_pop(k_ringbuf_t * p_ringbuf,void * pdata,size_t * plen)103 kstat_t ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen)
104 {
105 size_t split_len = 0;
106 uint8_t *data = pdata;
107 size_t len = 0;
108 uint8_t c_len[RING_BUF_LEN] = {0};
109 size_t len_bytes = 0;
110
111 if (p_ringbuf->type == RINGBUF_TYPE_FIX) {
112 if (p_ringbuf->head == p_ringbuf->end) {
113 p_ringbuf->head = p_ringbuf->buf;
114 }
115
116 memcpy(pdata, p_ringbuf->head, p_ringbuf->blk_size);
117 p_ringbuf->head += p_ringbuf->blk_size;
118 p_ringbuf->freesize += p_ringbuf->blk_size;
119
120 if (plen != NULL) {
121 *plen = p_ringbuf->blk_size;
122 }
123
124 return RHINO_SUCCESS;
125 } else {
126
127 len_bytes = RING_BUF_LEN;
128
129 if (p_ringbuf->head == p_ringbuf->end) {
130 p_ringbuf->head = p_ringbuf->buf;
131 }
132 split_len = p_ringbuf->end - p_ringbuf->head;
133 if (split_len < len_bytes && split_len > 0) {
134 memcpy(&c_len[0], p_ringbuf->head, split_len);
135 p_ringbuf->head = p_ringbuf->buf;
136 p_ringbuf->freesize += split_len;
137 } else {
138 split_len = 0;
139 }
140
141 if (len_bytes - split_len > 0) {
142 memcpy(&c_len[split_len], p_ringbuf->head, (len_bytes - split_len));
143 p_ringbuf->head += (len_bytes - split_len);
144 p_ringbuf->freesize += (len_bytes - split_len);
145 }
146
147 memcpy(&len, c_len, RING_BUF_LEN);
148 *plen = len;
149
150 if (p_ringbuf->head == p_ringbuf->end) {
151 p_ringbuf->head = p_ringbuf->buf;
152 }
153
154 split_len = p_ringbuf->end - p_ringbuf->head;
155 if (p_ringbuf->head > p_ringbuf->tail && split_len < len) {
156 memcpy(pdata, p_ringbuf->head, split_len);
157 data = (uint8_t *)pdata + split_len;
158 len -= split_len;
159 p_ringbuf->head = p_ringbuf->buf;
160 p_ringbuf->freesize += split_len;
161 }
162
163 memcpy(data, p_ringbuf->head, len);
164 p_ringbuf->head += len;
165 p_ringbuf->freesize += len;
166
167 return RHINO_SUCCESS;
168 }
169 }
170
ringbuf_is_full(k_ringbuf_t * p_ringbuf)171 uint8_t ringbuf_is_full(k_ringbuf_t *p_ringbuf)
172 {
173 if (p_ringbuf->type == RINGBUF_TYPE_DYN && p_ringbuf->freesize < (RING_BUF_LEN + 1)) {
174 return 1;
175 }
176
177 if ((p_ringbuf->type == RINGBUF_TYPE_FIX) &&
178 (p_ringbuf->freesize < p_ringbuf->blk_size)) {
179 return 1;
180 }
181
182 return 0;
183 }
184
ringbuf_is_empty(k_ringbuf_t * p_ringbuf)185 uint8_t ringbuf_is_empty(k_ringbuf_t *p_ringbuf)
186 {
187 if (p_ringbuf->freesize == (size_t)(p_ringbuf->end - p_ringbuf->buf)) {
188 return 1;
189 }
190
191 return 0;
192 }
193
ringbuf_reset(k_ringbuf_t * p_ringbuf)194 kstat_t ringbuf_reset(k_ringbuf_t *p_ringbuf)
195 {
196 p_ringbuf->head = p_ringbuf->buf;
197 p_ringbuf->tail = p_ringbuf->buf;
198 p_ringbuf->freesize = p_ringbuf->end - p_ringbuf->buf;
199
200 return RHINO_SUCCESS;
201 }
202
203