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