-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathringbuffer.c
161 lines (134 loc) · 3.42 KB
/
ringbuffer.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "helpers.h"
#include "ringbuffer.h"
#include "logging.h"
#include <string.h>
#include <unistd.h>
int
rb_write(struct ringbuffer *b, const char *data, size_t len) {
if (RB_AVAILABLE(b) < len) {
return RB_ERR_INSUFFICIENT;
}
size_t toend = RB_FREE_TOEND(b);
size_t chunklen = MIN(toend, len);
memcpy(b->blob + b->writer, data, chunklen);
b->writer = RB_WRITER_CALC(b, chunklen);
b->writecounter += chunklen;
if (len > chunklen) {
len -= chunklen;
memcpy(b->blob, data + chunklen, len);
b->writer += len;
b->writecounter += len;
}
return RB_OK;
}
size_t
rb_read(struct ringbuffer *b, char *data, size_t len) {
size_t bytes;
bytes = MIN(RB_USED_TOEND(b), len);
if (bytes) {
memcpy(data, b->blob + b->reader, bytes);
b->reader = RB_READER_CALC(b, bytes);
len -= bytes;
}
if (len) {
len = MIN(RB_USED_TOEND(b), len);
if (len) {
memcpy(data + bytes, b->blob, len);
b->reader += len;
bytes += len;
}
}
return bytes;
}
size_t
rb_dryread(struct ringbuffer *b, char *data, size_t len) {
size_t toend = RB_USED_TOEND(b);
size_t total = MIN(toend, len);
memcpy(data, b->blob + b->reader, total);
len -= total;
if (len) {
len = MIN(RB_USED(b) - total, len);
memcpy(data + total, b->blob, len);
total += len;
}
return total;
}
ssize_t
rb_readf(struct ringbuffer *b, int fd, size_t len) {
size_t bytes;
bytes = MIN(RB_USED_TOEND(b), len);
if (bytes) {
if (write(fd, b->blob + b->reader, bytes) < 0) {
return ERR;
}
len -= bytes;
}
if (len) {
len = MIN(RB_USED(b) - bytes, len);
if (len) {
if (write(fd, b->blob, len) < 0) {
return ERR;
}
bytes += len;
}
}
if (bytes) {
RB_READER_SKIP(b, bytes);
}
return bytes;
}
int
rb_read_until(struct ringbuffer *b, char *data, size_t len,
char *delimiter, size_t dlen, size_t *readlen) {
size_t rl = rb_dryread(b, data, len);
*readlen = rl;
if (rl <= 0) {
return RB_ERR_NOTFOUND;
}
char *f = memmem(data, rl, delimiter, dlen);
if (f == NULL) {
return RB_ERR_NOTFOUND;
}
*readlen = (f - data) + dlen;
b->reader = RB_READER_CALC(b, *readlen);
return RB_OK;
}
int
rb_dryread_until(struct ringbuffer *b, char *data, size_t len,
char *delimiter, size_t dlen, size_t *readlen) {
size_t rl = rb_dryread(b, data, len);
*readlen = rl;
if (rl <= 0) {
return RB_ERR_NOTFOUND;
}
char *f = memmem(data, rl, delimiter, dlen);
if (f == NULL) {
return RB_ERR_NOTFOUND;
}
*readlen = (f - data) + dlen;
return RB_OK;
}
int
rb_read_until_chr(struct ringbuffer *b, char *data, size_t len,
char delimiter, size_t *readlen) {
size_t rl = rb_dryread(b, data, len);
*readlen = rl;
if (rl <= 0) {
return RB_ERR_NOTFOUND;
}
char *f = memchr(data, delimiter, rl);
if (f == NULL) {
return RB_ERR_NOTFOUND;
}
*readlen = (f - data) + 1;
b->reader = RB_READER_CALC(b, *readlen);
return RB_OK;
}
void
rb_init(struct ringbuffer *b, char *buff, size_t size) {
b->size = size;
b->reader = 0;
b->writer = 0;
b->writecounter = 0;
b->blob = buff;
}