FreeRDP
Loading...
Searching...
No Matches
TestRingBuffer.c
1
20#include <stdio.h>
21#include <string.h>
22
23#include <freerdp/utils/ringbuffer.h>
24
25static BOOL test_overlaps(void)
26{
27 RingBuffer rb;
28 DataChunk chunks[2];
29 BYTE bytes[200];
30 int nchunks = 0;
31 int counter = 0;
32
33 for (size_t i = 0; i < sizeof(bytes); i++)
34 bytes[i] = (BYTE)i;
35
36 if (!ringbuffer_init(&rb, 5))
37 goto error;
38 if (!ringbuffer_write(&rb, bytes, 4)) /* [0123.] */
39 goto error;
40 counter += 4;
41 ringbuffer_commit_read_bytes(&rb, 2); /* [..23.] */
42
43 if (!ringbuffer_write(&rb, &bytes[counter], 2)) /* [5.234] */
44 goto error;
45 counter += 2;
46
47 nchunks = ringbuffer_peek(&rb, chunks, 4);
48 if (nchunks != 2 || chunks[0].size != 3 || chunks[1].size != 1)
49 goto error;
50
51 for (int x = 0, j = 2; x < nchunks; x++)
52 {
53 for (size_t k = 0; k < chunks[x].size; k++, j++)
54 {
55 if (chunks[x].data[k] != (BYTE)j)
56 goto error;
57 }
58 }
59
60 ringbuffer_commit_read_bytes(&rb, 3); /* [5....] */
61 if (ringbuffer_used(&rb) != 1)
62 goto error;
63
64 if (!ringbuffer_write(&rb, &bytes[counter], 6)) /* [56789ab....] */
65 goto error;
66
67 ringbuffer_commit_read_bytes(&rb, 6); /* [......b....] */
68 nchunks = ringbuffer_peek(&rb, chunks, 10);
69 if (nchunks != 1 || chunks[0].size != 1 || (*chunks[0].data != 0xb))
70 goto error;
71
72 if (ringbuffer_capacity(&rb) != 5)
73 goto error;
74
75 ringbuffer_destroy(&rb);
76 return TRUE;
77error:
78 ringbuffer_destroy(&rb);
79 return FALSE;
80}
81
82int TestRingBuffer(int argc, char* argv[])
83{
84 RingBuffer ringBuffer;
85 int testNo = 0;
86 BYTE* tmpBuf = nullptr;
87 BYTE* rb_ptr = nullptr;
88 DataChunk chunks[2];
89
90 WINPR_UNUSED(argc);
91 WINPR_UNUSED(argv);
92
93 if (!ringbuffer_init(&ringBuffer, 10))
94 {
95 (void)fprintf(stderr, "unable to initialize ringbuffer\n");
96 return -1;
97 }
98
99 tmpBuf = (BYTE*)malloc(50);
100 if (!tmpBuf)
101 return -1;
102
103 for (int i = 0; i < 50; i++)
104 tmpBuf[i] = (char)i;
105
106 (void)fprintf(stderr, "%d: basic tests...", ++testNo);
107 if (!ringbuffer_write(&ringBuffer, tmpBuf, 5) || !ringbuffer_write(&ringBuffer, tmpBuf, 5) ||
108 !ringbuffer_write(&ringBuffer, tmpBuf, 5))
109 {
110 (void)fprintf(stderr, "error when writing bytes\n");
111 return -1;
112 }
113
114 if (ringbuffer_used(&ringBuffer) != 15)
115 {
116 (void)fprintf(stderr, "invalid used size got %" PRIuz " when I would expect 15\n",
117 ringbuffer_used(&ringBuffer));
118 return -1;
119 }
120
121 if (ringbuffer_peek(&ringBuffer, chunks, 10) != 1 || chunks[0].size != 10)
122 {
123 (void)fprintf(stderr, "error when reading bytes\n");
124 return -1;
125 }
126 ringbuffer_commit_read_bytes(&ringBuffer, chunks[0].size);
127
128 /* check retrieved bytes */
129 for (size_t i = 0; i < chunks[0].size; i++)
130 {
131 if (chunks[0].data[i] != i % 5)
132 {
133 (void)fprintf(stderr,
134 "invalid byte at %" PRIuz ", got %" PRIu8 " instead of %" PRIuz "\n", i,
135 chunks[0].data[i], i % 5U);
136 return -1;
137 }
138 }
139
140 if (ringbuffer_used(&ringBuffer) != 5)
141 {
142 (void)fprintf(stderr, "invalid used size after read got %" PRIuz " when I would expect 5\n",
143 ringbuffer_used(&ringBuffer));
144 return -1;
145 }
146
147 /* write some more bytes to have writePtr < readPtr and data split in 2 chunks */
148 if (!ringbuffer_write(&ringBuffer, tmpBuf, 6) ||
149 ringbuffer_peek(&ringBuffer, chunks, 11) != 2 || chunks[0].size != 10 ||
150 chunks[1].size != 1)
151 {
152 (void)fprintf(stderr, "invalid read of split data\n");
153 return -1;
154 }
155
156 ringbuffer_commit_read_bytes(&ringBuffer, 11);
157 (void)fprintf(stderr, "ok\n");
158
159 (void)fprintf(stderr, "%d: peek with nothing to read...", ++testNo);
160 if (ringbuffer_peek(&ringBuffer, chunks, 10))
161 {
162 (void)fprintf(stderr, "peek returns some chunks\n");
163 return -1;
164 }
165 (void)fprintf(stderr, "ok\n");
166
167 (void)fprintf(stderr, "%d: ensure_linear_write / read() shouldn't grow...", ++testNo);
168 for (int i = 0; i < 1000; i++)
169 {
170 rb_ptr = ringbuffer_ensure_linear_write(&ringBuffer, 50);
171 if (!rb_ptr)
172 {
173 (void)fprintf(stderr, "ringbuffer_ensure_linear_write() error\n");
174 return -1;
175 }
176
177 memcpy(rb_ptr, tmpBuf, 50);
178
179 if (!ringbuffer_commit_written_bytes(&ringBuffer, 50))
180 {
181 (void)fprintf(stderr, "ringbuffer_commit_written_bytes() error, i=%d\n", i);
182 return -1;
183 }
184
185 // ringbuffer_commit_read_bytes(&ringBuffer, 25);
186 }
187
188 for (int i = 0; i < 1000; i++)
189 ringbuffer_commit_read_bytes(&ringBuffer, 25);
190
191 for (int i = 0; i < 1000; i++)
192 ringbuffer_commit_read_bytes(&ringBuffer, 25);
193
194 if (ringbuffer_capacity(&ringBuffer) != 10)
195 {
196 (void)fprintf(stderr, "not the expected capacity, have %" PRIuz " and expects 10\n",
197 ringbuffer_capacity(&ringBuffer));
198 return -1;
199 }
200 (void)fprintf(stderr, "ok\n");
201
202 (void)fprintf(stderr, "%d: free size is correctly computed...", ++testNo);
203 for (int i = 0; i < 1000; i++)
204 {
205 if (!ringbuffer_ensure_linear_write(&ringBuffer, 50))
206 return -1;
207
208 if (!ringbuffer_commit_written_bytes(&ringBuffer, 50))
209 {
210 (void)fprintf(stderr, "ringbuffer_commit_written_bytes() error, i=%d\n", i);
211 return -1;
212 }
213 }
214 ringbuffer_commit_read_bytes(&ringBuffer, 50ULL * 1000ULL);
215 (void)fprintf(stderr, "ok\n");
216
217 ringbuffer_destroy(&ringBuffer);
218
219 (void)fprintf(stderr, "%d: specific overlaps test...", ++testNo);
220 if (!test_overlaps())
221 {
222 (void)fprintf(stderr, "ko\n");
223 return -1;
224 }
225 (void)fprintf(stderr, "ok\n");
226
227 ringbuffer_destroy(&ringBuffer);
228 free(tmpBuf);
229 return 0;
230}
a piece of data in the ring buffer, exactly like a glibc iovec
Definition ringbuffer.h:44
ring buffer meta data
Definition ringbuffer.h:33