diff options
Diffstat (limited to 'toxcore/util.c')
-rw-r--r-- | toxcore/util.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/toxcore/util.c b/toxcore/util.c index c320cdc4..28d8721c 100644 --- a/toxcore/util.c +++ b/toxcore/util.c | |||
@@ -192,3 +192,87 @@ int create_recursive_mutex(pthread_mutex_t *mutex) | |||
192 | 192 | ||
193 | return 0; | 193 | return 0; |
194 | } | 194 | } |
195 | |||
196 | |||
197 | struct RingBuffer { | ||
198 | uint16_t size; /* Max size */ | ||
199 | uint16_t start; | ||
200 | uint16_t end; | ||
201 | void **data; | ||
202 | }; | ||
203 | |||
204 | bool rb_full(const RingBuffer *b) | ||
205 | { | ||
206 | return (b->end + 1) % b->size == b->start; | ||
207 | } | ||
208 | bool rb_empty(const RingBuffer *b) | ||
209 | { | ||
210 | return b->end == b->start; | ||
211 | } | ||
212 | void *rb_write(RingBuffer *b, void *p) | ||
213 | { | ||
214 | void *rc = NULL; | ||
215 | |||
216 | if ((b->end + 1) % b->size == b->start) /* full */ | ||
217 | rc = b->data[b->start]; | ||
218 | |||
219 | b->data[b->end] = p; | ||
220 | b->end = (b->end + 1) % b->size; | ||
221 | |||
222 | if (b->end == b->start) | ||
223 | b->start = (b->start + 1) % b->size; | ||
224 | |||
225 | return rc; | ||
226 | } | ||
227 | bool rb_read(RingBuffer *b, void **p) | ||
228 | { | ||
229 | if (b->end == b->start) { /* Empty */ | ||
230 | *p = NULL; | ||
231 | return false; | ||
232 | } | ||
233 | |||
234 | *p = b->data[b->start]; | ||
235 | b->start = (b->start + 1) % b->size; | ||
236 | return true; | ||
237 | } | ||
238 | RingBuffer *rb_new(int size) | ||
239 | { | ||
240 | RingBuffer *buf = calloc(sizeof(RingBuffer), 1); | ||
241 | |||
242 | if (!buf) return NULL; | ||
243 | |||
244 | buf->size = size + 1; /* include empty elem */ | ||
245 | |||
246 | if (!(buf->data = calloc(buf->size, sizeof(void *)))) { | ||
247 | free(buf); | ||
248 | return NULL; | ||
249 | } | ||
250 | |||
251 | return buf; | ||
252 | } | ||
253 | void rb_kill(RingBuffer *b) | ||
254 | { | ||
255 | if (b) { | ||
256 | free(b->data); | ||
257 | free(b); | ||
258 | } | ||
259 | } | ||
260 | uint16_t rb_size(const RingBuffer *b) | ||
261 | { | ||
262 | if (rb_empty(b)) | ||
263 | return 0; | ||
264 | |||
265 | return | ||
266 | b->end > b->start ? | ||
267 | b->end - b->start : | ||
268 | (b->size - b->start) + b->end; | ||
269 | } | ||
270 | uint16_t rb_data(const RingBuffer *b, void **dest) | ||
271 | { | ||
272 | uint16_t i = 0; | ||
273 | |||
274 | for (; i < rb_size(b); i++) | ||
275 | dest[i] = b->data[(b->start + i) % b->size]; | ||
276 | |||
277 | return i; | ||
278 | } | ||