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
|
#include <stdlib.h>
#include <string.h>
#include "rb.h"
#define MAX(_x1, _x2) (((_x1) > (_x2)) ? (_x1) : (_x2))
#define MIN(_x1, _x2) (((_x1) < (_x2)) ? (_x1) : (_x2))
int rb_init(t_rb *rb)
{
rb->off_r = 0;
rb->off_w = 0;
rb->size_filled = 0;
return 0;
}
t_rb *rb_new(void)
{
t_rb *rb;
if ((rb = malloc(sizeof(t_rb))) == NULL) {
return NULL;
}
rb_init(rb);
return rb;
}
void rb_delete(t_rb **rb)
{
free(*rb);
*rb = NULL;
}
t_rb *rb_put(t_rb *rb, const void *src, size_t n)
{
size_t size;
/* loop until n bytes of src have been written */
while (n != 0) {
size = MIN(n, rb_get_size(rb) - rb->off_w);
memcpy(&rb->buffer[rb->off_w], src, size);
/* if we overrided the data to read, we need to move off_r */
if (rb->off_w < rb->off_r && rb->off_w + size > rb->off_r) {
rb->off_r = (rb->off_w + size) % rb_get_size(rb);
} else if (rb->off_r == rb->off_w
&& rb->size_filled == rb_get_size(rb))
{
rb->off_r = (rb->off_w + size) % rb_get_size(rb);
}
/* this will put the offset back to 0 if we reached the end */
rb->off_w = (rb->off_w + size) % rb_get_size(rb);
n -= size;
src += size;
rb->size_filled += size;
rb->size_filled = MIN(rb->size_filled, rb_get_size(rb));
}
return rb;
}
size_t rb_get(t_rb *rb, void *dest, size_t n)
{
size_t size = rb_peek(rb, dest, n);
rb->size_filled -= size;
rb->off_r = (rb->off_r + size) % rb_get_size(rb);
if (rb->size_filled == 0) {
/* optimize space */
rb->off_w = rb->off_r = 0;
}
return size;
}
size_t rb_peek(const t_rb *rb, void *dest, size_t n)
{
uint16_t offset;
size_t size;
size_t size2;
if (rb->size_filled == 0 || n == 0) {
return 0;
}
size = 0;
if (rb->off_r >= rb->off_w) {
/* do not try to retrieve too much data */
size = MIN(n, rb_get_size(rb) - rb->off_r);
if (dest != NULL) {
memcpy(dest, &rb->buffer[rb->off_r], size);
}
dest += size;
n -= size;
}
offset = (rb->off_r + size) % rb_get_size(rb);
size2 = MIN(n, (size_t)(rb->off_w - offset));
if (dest != NULL) {
memcpy(dest, &rb->buffer[offset], size2);
}
return size + size2;
}
|