forked from ish-app/ish
-
Notifications
You must be signed in to change notification settings - Fork 12
/
fifo.c
67 lines (57 loc) · 1.85 KB
/
fifo.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <stdlib.h>
#include <string.h>
#include "util/fifo.h"
void fifo_init(struct fifo *fifo, size_t capacity) {
fifo->buf = malloc(capacity);
fifo->capacity = capacity;
fifo->size = fifo->start = 0;
}
void fifo_destroy(struct fifo *fifo) {
free(fifo->buf);
}
size_t fifo_capacity(struct fifo *fifo) {
return fifo->capacity;
}
size_t fifo_size(struct fifo *fifo) {
return fifo->size;
}
size_t fifo_remaining(struct fifo *fifo) {
return fifo->capacity - fifo->size;
}
int fifo_write(struct fifo *fifo, const void *data, size_t size, int flags) {
if (size > fifo_remaining(fifo)) {
if (!(flags & FIFO_OVERWRITE))
return 1;
size_t excess = size - fifo_remaining(fifo);
fifo->start = (fifo->start + excess) % fifo->capacity;
fifo->size -= excess;
}
size_t tail = (fifo->start + fifo->size) % fifo->capacity;;
size_t first_copy_size = fifo->capacity - tail;
if (first_copy_size > size)
first_copy_size = size;
memcpy(&fifo->buf[tail], data, first_copy_size);
memcpy(&fifo->buf[0], (char *) data + first_copy_size, size - first_copy_size);
fifo->size += size;
return 0;
}
int fifo_read(struct fifo *fifo, void *buf, size_t size, int flags) {
if (size > fifo_size(fifo))
return 1;
size_t start = fifo->start;
if (flags & FIFO_LAST)
start = (start + (fifo->size - size)) % fifo->capacity;
size_t first_copy_size = fifo->capacity - fifo->start;
if (first_copy_size > size)
first_copy_size = size;
memcpy(buf, &fifo->buf[start], first_copy_size);
memcpy((char *) buf + first_copy_size, &fifo->buf[0], size - first_copy_size);
if (!(flags & FIFO_PEEK)) {
fifo->start = (start + size) % fifo->capacity;
fifo->size -= size;
}
return 0;
}
void fifo_flush(struct fifo *fifo) {
fifo->size = 0;
}