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 #include "cx/test.h"
30 #include "util_allocator.h"
31 #include <errno.h>
32
33 #include "cx/buffer.h"
34
35 CX_TEST(test_buffer_init_wrap_space) {
36 CxTestingAllocator talloc;
37 cx_testing_allocator_init(&talloc);
38 CxAllocator *alloc = &talloc.base;
39 CX_TEST_DO {
40 CxBuffer buf;
41 void *space = cxMalloc(alloc,
16);
42 cxBufferInit(&buf, space,
16, alloc,
CX_BUFFER_DEFAULT);
43 CX_TEST_ASSERT(buf.flush ==
NULL);
44 CX_TEST_ASSERT(buf.space == space);
45 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_AUTO_EXTEND) ==
0);
46 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_FREE_CONTENTS) ==
0);
47 CX_TEST_ASSERT(buf.pos ==
0);
48 CX_TEST_ASSERT(buf.size ==
0);
49 CX_TEST_ASSERT(buf.capacity ==
16);
50 CX_TEST_ASSERT(buf.allocator == alloc);
51 cxBufferDestroy(&buf);
52 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
53 cxFree(alloc, space);
54 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
55 }
56 cx_testing_allocator_destroy(&talloc);
57 }
58
59 CX_TEST(test_buffer_init_wrap_space_auto_extend) {
60 CxTestingAllocator talloc;
61 cx_testing_allocator_init(&talloc);
62 CxAllocator *alloc = &talloc.base;
63 CX_TEST_DO {
64 CxBuffer buf;
65 void *space = cxMalloc(alloc,
16);
66 cxBufferInit(&buf, space,
16, alloc,
CX_BUFFER_AUTO_EXTEND);
67 CX_TEST_ASSERT(buf.flush ==
NULL);
68 CX_TEST_ASSERT(buf.space == space);
69 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_AUTO_EXTEND) ==
CX_BUFFER_AUTO_EXTEND);
70 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_FREE_CONTENTS) ==
0);
71 CX_TEST_ASSERT(buf.pos ==
0);
72 CX_TEST_ASSERT(buf.size ==
0);
73 CX_TEST_ASSERT(buf.capacity ==
16);
74 CX_TEST_ASSERT(buf.allocator == alloc);
75 cxBufferDestroy(&buf);
76 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
77 cxFree(alloc, space);
78 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
79 }
80 cx_testing_allocator_destroy(&talloc);
81 }
82
83 CX_TEST(test_buffer_init_wrap_space_auto_free) {
84 CxTestingAllocator talloc;
85 cx_testing_allocator_init(&talloc);
86 CxAllocator *alloc = &talloc.base;
87 CX_TEST_DO {
88 CxBuffer buf;
89 void *space = cxMalloc(alloc,
16);
90 cxBufferInit(&buf, space,
16, alloc,
CX_BUFFER_FREE_CONTENTS);
91 CX_TEST_ASSERT(buf.flush ==
NULL);
92 CX_TEST_ASSERT(buf.space == space);
93 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_AUTO_EXTEND) ==
0);
94 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_FREE_CONTENTS) ==
CX_BUFFER_FREE_CONTENTS);
95 CX_TEST_ASSERT(buf.pos ==
0);
96 CX_TEST_ASSERT(buf.size ==
0);
97 CX_TEST_ASSERT(buf.capacity ==
16);
98 CX_TEST_ASSERT(buf.allocator == alloc);
99 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
100 cxBufferDestroy(&buf);
101 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
102 }
103 cx_testing_allocator_destroy(&talloc);
104 }
105
106 CX_TEST(test_buffer_init_fresh_space) {
107 CxTestingAllocator talloc;
108 cx_testing_allocator_init(&talloc);
109 CxAllocator *alloc = &talloc.base;
110 CX_TEST_DO {
111 CxBuffer buf;
112 cxBufferInit(&buf,
NULL,
8, alloc,
CX_BUFFER_DEFAULT);
113 CX_TEST_ASSERT(buf.flush ==
NULL);
114 CX_TEST_ASSERT(buf.space !=
NULL);
115 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_AUTO_EXTEND) ==
0);
116 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_FREE_CONTENTS) ==
CX_BUFFER_FREE_CONTENTS);
117 CX_TEST_ASSERT(buf.pos ==
0);
118 CX_TEST_ASSERT(buf.size ==
0);
119 CX_TEST_ASSERT(buf.capacity ==
8);
120 CX_TEST_ASSERT(buf.allocator == alloc);
121 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
122 cxBufferDestroy(&buf);
123 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
124 }
125 cx_testing_allocator_destroy(&talloc);
126 }
127
128 CX_TEST(test_buffer_init_on_heap) {
129 CxTestingAllocator talloc;
130 cx_testing_allocator_init(&talloc);
131 CxAllocator *alloc = &talloc.base;
132 CX_TEST_DO {
133 CxBuffer *buf;
134 void *space = cxMalloc(alloc,
16);
135 buf = cxBufferCreate(space,
16, alloc,
CX_BUFFER_FREE_CONTENTS);
136 CX_TEST_ASSERT(buf !=
NULL);
137 CX_TEST_ASSERT(buf->flush ==
NULL);
138 CX_TEST_ASSERT(buf->space == space);
139 CX_TEST_ASSERT((buf->flags &
CX_BUFFER_AUTO_EXTEND) ==
0);
140 CX_TEST_ASSERT((buf->flags &
CX_BUFFER_FREE_CONTENTS) ==
CX_BUFFER_FREE_CONTENTS);
141 CX_TEST_ASSERT(buf->pos ==
0);
142 CX_TEST_ASSERT(buf->size ==
0);
143 CX_TEST_ASSERT(buf->capacity ==
16);
144 CX_TEST_ASSERT(buf->allocator == alloc);
145 cxBufferFree(buf);
146 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
147 }
148 cx_testing_allocator_destroy(&talloc);
149 }
150
151 CX_TEST(test_buffer_create_defaulted_allocator) {
152 CX_TEST_DO {
153 CxBuffer *buf;
154 buf = cxBufferCreate(
NULL,
16,
NULL,
0);
155 CX_TEST_ASSERT(buf !=
NULL);
156 CX_TEST_ASSERT(buf->flush ==
NULL);
157 CX_TEST_ASSERT(buf->space !=
NULL);
158 CX_TEST_ASSERT((buf->flags &
CX_BUFFER_AUTO_EXTEND) ==
0);
159 CX_TEST_ASSERT((buf->flags &
CX_BUFFER_FREE_CONTENTS) ==
CX_BUFFER_FREE_CONTENTS);
160 CX_TEST_ASSERT(buf->pos ==
0);
161 CX_TEST_ASSERT(buf->size ==
0);
162 CX_TEST_ASSERT(buf->capacity ==
16);
163 CX_TEST_ASSERT(buf->allocator == cxDefaultAllocator);
164 cxBufferFree(buf);
165 }
166 }
167
168 CX_TEST(test_buffer_minimum_capacity_sufficient) {
169 CxTestingAllocator talloc;
170 cx_testing_allocator_init(&talloc);
171 CxAllocator *alloc = &talloc.base;
172 CX_TEST_DO {
173 void *space = cxMalloc(alloc,
8);
174 CxBuffer buf;
175 cxBufferInit(&buf, space,
8, alloc,
CX_BUFFER_FREE_CONTENTS);
176 memcpy(space,
"Testing",
8);
177 buf.size =
8;
178 cxBufferMinimumCapacity(&buf,
6);
179 CX_TEST_ASSERT(buf.capacity ==
8);
180 CX_TEST_ASSERT(buf.size ==
8);
181 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
182 cxBufferDestroy(&buf);
183 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
184 }
185 cx_testing_allocator_destroy(&talloc);
186 }
187
188 CX_TEST(test_buffer_minimum_capacity_extend) {
189 CxTestingAllocator talloc;
190 cx_testing_allocator_init(&talloc);
191 CxAllocator *alloc = &talloc.base;
192 CX_TEST_DO {
193 void *space = cxMalloc(alloc,
8);
194 CxBuffer buf;
195 cxBufferInit(&buf, space,
8, alloc,
CX_BUFFER_FREE_CONTENTS);
196 memcpy(space,
"Testing",
8);
197 buf.size =
8;
198 cxBufferMinimumCapacity(&buf,
16);
199 CX_TEST_ASSERT(buf.capacity ==
16);
200 CX_TEST_ASSERT(buf.size ==
8);
201 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
202
203
204 cxBufferMinimumCapacity(&buf,
200);
205 CX_TEST_ASSERT(buf.capacity ==
256);
206
207
208 cxBufferMinimumCapacity(&buf, cx_system_page_size() +
200);
209 CX_TEST_ASSERT(buf.capacity == cx_system_page_size()*
2);
210
211 cxBufferDestroy(&buf);
212 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
213 }
214 cx_testing_allocator_destroy(&talloc);
215 }
216
217 CX_TEST(test_buffer_shrink) {
218 CxTestingAllocator talloc;
219 cx_testing_allocator_init(&talloc);
220 CxAllocator *alloc = &talloc.base;
221 CX_TEST_DO {
222 CxBuffer buf;
223 cxBufferInit(&buf,
NULL,
16, alloc,
CX_BUFFER_FREE_CONTENTS);
224 cxBufferPutString(&buf,
"Testing");
225 cxBufferTerminate(&buf);
226 CX_TEST_ASSERT(buf.capacity ==
16);
227 CX_TEST_ASSERT(buf.size ==
7);
228 cxBufferShrink(&buf,
4);
229 CX_TEST_ASSERT(buf.capacity ==
11);
230 CX_TEST_ASSERT(buf.size ==
7);
231 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
232 cxBufferDestroy(&buf);
233 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
234 }
235 cx_testing_allocator_destroy(&talloc);
236 }
237
238 CX_TEST(test_buffer_shrink_copy_on_write) {
239 CxTestingAllocator talloc;
240 cx_testing_allocator_init(&talloc);
241 CxAllocator *alloc = &talloc.base;
242 CX_TEST_DO {
243 CxBuffer buf;
244 const char* space =
"Testing";
245 cxBufferInit(&buf, (
void*)space,
16, alloc,
CX_BUFFER_COPY_ON_WRITE);
246 buf.size =
8;
247 CX_TEST_ASSERT(buf.capacity ==
16);
248 cxBufferShrink(&buf,
4);
249 CX_TEST_ASSERT(buf.capacity ==
16);
250 CX_TEST_ASSERT(buf.size ==
8);
251 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
252 CX_TEST_ASSERT(talloc.alloc_total ==
0);
253 cxBufferDestroy(&buf);
254 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
255 }
256 cx_testing_allocator_destroy(&talloc);
257 }
258
259 CX_TEST(test_buffer_shrink_copy_on_extend) {
260 CxTestingAllocator talloc;
261 cx_testing_allocator_init(&talloc);
262 CxAllocator *alloc = &talloc.base;
263 CX_TEST_DO {
264 CxBuffer buf;
265 char space[
16] =
"Testing";
266 cxBufferInit(&buf, space,
16, alloc,
CX_BUFFER_COPY_ON_EXTEND);
267 buf.size =
8;
268 CX_TEST_ASSERT(buf.capacity ==
16);
269 cxBufferShrink(&buf,
4);
270 CX_TEST_ASSERT(buf.capacity ==
16);
271 CX_TEST_ASSERT(buf.size ==
8);
272 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
273 CX_TEST_ASSERT(talloc.alloc_total ==
0);
274 cxBufferDestroy(&buf);
275 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
276 }
277 cx_testing_allocator_destroy(&talloc);
278 }
279
280 CX_TEST(test_buffer_reserve) {
281 CxTestingAllocator talloc;
282 cx_testing_allocator_init(&talloc);
283 CxAllocator *alloc = &talloc.base;
284 CX_TEST_DO {
285 CxBuffer buf;
286 char space[
16] =
"Testing";
287 cxBufferInit(&buf, space,
16, alloc,
CX_BUFFER_COPY_ON_EXTEND);
288 buf.size =
8;
289 CX_TEST_ASSERT(buf.capacity ==
16);
290 CX_TEST_ASSERT(talloc.alloc_total ==
0);
291
292 cxBufferReserve(&buf,
32);
293 CX_TEST_ASSERT(buf.capacity ==
32);
294 CX_TEST_ASSERT(buf.size ==
8);
295 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
296 CX_TEST_ASSERT(talloc.alloc_total >
0);
297 CX_TEST_ASSERT((buf.flags &
CX_BUFFER_COPY_ON_EXTEND) ==
0);
298
299 buf.size =
24;
300 cxBufferReserve(&buf,
16);
301 CX_TEST_ASSERT(buf.capacity ==
16);
302 CX_TEST_ASSERT(buf.size ==
16);
303 CX_TEST_ASSERT(memcmp(buf.space,
"Testing",
8) ==
0);
304
305 cxBufferReserve(&buf,
0);
306 CX_TEST_ASSERT(buf.capacity ==
0);
307 CX_TEST_ASSERT(buf.size ==
0);
308 CX_TEST_ASSERT(buf.space ==
NULL);
309 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
310 cxBufferDestroy(&buf);
311 }
312 cx_testing_allocator_destroy(&talloc);
313 }
314
315 CX_TEST(test_buffer_clear) {
316 char space[
16];
317 strcpy(space,
"clear test");
318 CxBuffer buf;
319 cxBufferInit(&buf, space,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
320 CX_TEST_DO {
321 CX_TEST_ASSERT(buf.size ==
0);
322
323 cxBufferClear(&buf);
324 CX_TEST_ASSERT(
0 == memcmp(space,
"clear test",
10));
325 buf.size =
5;
326 buf.pos =
3;
327 cxBufferClear(&buf);
328 CX_TEST_ASSERT(
0 == memcmp(space,
"\0\0\0\0\0 test",
10));
329 CX_TEST_ASSERT(buf.size ==
0);
330 CX_TEST_ASSERT(buf.pos ==
0);
331 }
332 cxBufferDestroy(&buf);
333 }
334
335 CX_TEST(test_buffer_clear_copy_on_write) {
336 char space[
16];
337 strcpy(space,
"clear test");
338 CxBuffer buf;
339 cxBufferInit(&buf, space,
16, cxDefaultAllocator,
CX_BUFFER_COPY_ON_WRITE);
340 CX_TEST_DO {
341 buf.size =
5;
342 buf.pos =
3;
343 cxBufferClear(&buf);
344 CX_TEST_ASSERT(
0 == memcmp(space,
"clear test",
10));
345 CX_TEST_ASSERT(buf.size ==
0);
346 CX_TEST_ASSERT(buf.pos ==
0);
347 }
348 cxBufferDestroy(&buf);
349 }
350
351 CX_TEST(test_buffer_reset) {
352 char space[
16];
353 strcpy(space,
"reset test");
354 CxBuffer buf;
355 cxBufferInit(&buf, space,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
356 CX_TEST_DO {
357 buf.size =
5;
358 buf.pos =
3;
359 cxBufferReset(&buf);
360 CX_TEST_ASSERT(
0 == memcmp(space,
"reset test",
10));
361 CX_TEST_ASSERT(buf.size ==
0);
362 CX_TEST_ASSERT(buf.pos ==
0);
363 }
364 cxBufferDestroy(&buf);
365 }
366
367 CX_TEST(test_buffer_seek_set_zero) {
368 CxBuffer buf;
369 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
370 buf.size =
6;
371 buf.pos =
3;
372 CX_TEST_DO {
373 int result = cxBufferSeek(&buf,
0,
SEEK_SET);
374 CX_TEST_ASSERT(result ==
0);
375 CX_TEST_ASSERT(buf.pos ==
0);
376 }
377 cxBufferDestroy(&buf);
378 }
379
380 CX_TEST(test_buffer_seek_set_valid) {
381 CxBuffer buf;
382 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
383 buf.size =
6;
384 buf.pos =
3;
385 CX_TEST_DO {
386 int result = cxBufferSeek(&buf,
5,
SEEK_SET);
387 CX_TEST_ASSERT(result ==
0);
388 CX_TEST_ASSERT(buf.pos ==
5);
389 }
390 cxBufferDestroy(&buf);
391 }
392
393 CX_TEST(test_buffer_seek_set_invalid) {
394 CxBuffer buf;
395 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
396 buf.size =
6;
397 buf.pos =
3;
398 CX_TEST_DO {
399 int result = cxBufferSeek(&buf,
7,
SEEK_SET);
400 CX_TEST_ASSERT(result !=
0);
401 CX_TEST_ASSERT(buf.pos ==
3);
402 }
403 cxBufferDestroy(&buf);
404 }
405
406 CX_TEST(test_buffer_seek_cur_zero) {
407 CxBuffer buf;
408 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
409 buf.size =
6;
410 buf.pos =
3;
411 CX_TEST_DO {
412 int result = cxBufferSeek(&buf,
0,
SEEK_CUR);
413 CX_TEST_ASSERT(result ==
0);
414 CX_TEST_ASSERT(buf.pos ==
3);
415 }
416 cxBufferDestroy(&buf);
417 }
418
419 CX_TEST(test_buffer_seek_cur_valid_positive) {
420 CxBuffer buf;
421 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
422 buf.size =
6;
423 buf.pos =
3;
424 CX_TEST_DO {
425 int result = cxBufferSeek(&buf,
2,
SEEK_CUR);
426 CX_TEST_ASSERT(result ==
0);
427 CX_TEST_ASSERT(buf.pos ==
5);
428 }
429 cxBufferDestroy(&buf);
430 }
431
432 CX_TEST(test_buffer_seek_cur_valid_negative) {
433 CxBuffer buf;
434 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
435 buf.size =
6;
436 buf.pos =
3;
437 CX_TEST_DO {
438 int result = cxBufferSeek(&buf,
-3,
SEEK_CUR);
439 CX_TEST_ASSERT(result ==
0);
440 CX_TEST_ASSERT(buf.pos ==
0);
441 }
442 cxBufferDestroy(&buf);
443 }
444
445 CX_TEST(test_buffer_seek_cur_invalid_positive) {
446 CxBuffer buf;
447 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
448 buf.size =
6;
449 buf.pos =
3;
450 CX_TEST_DO {
451 int result = cxBufferSeek(&buf,
4,
SEEK_CUR);
452 CX_TEST_ASSERT(result !=
0);
453 CX_TEST_ASSERT(buf.pos ==
3);
454 }
455 cxBufferDestroy(&buf);
456 }
457
458 CX_TEST(test_buffer_seek_cur_invalid_negative) {
459 CxBuffer buf;
460 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
461 buf.size =
6;
462 buf.pos =
3;
463 CX_TEST_DO {
464 int result = cxBufferSeek(&buf,
-4,
SEEK_CUR);
465 CX_TEST_ASSERT(result !=
0);
466 CX_TEST_ASSERT(buf.pos ==
3);
467 }
468 cxBufferDestroy(&buf);
469 }
470
471 CX_TEST(test_buffer_seek_end_zero) {
472 CxBuffer buf;
473 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
474 buf.size =
6;
475 buf.pos =
3;
476 CX_TEST_DO {
477 int result = cxBufferSeek(&buf,
0,
SEEK_END);
478 CX_TEST_ASSERT(result ==
0);
479 CX_TEST_ASSERT(buf.pos ==
6);
480 }
481 cxBufferDestroy(&buf);
482 }
483
484 CX_TEST(test_buffer_seek_end_valid) {
485 CxBuffer buf;
486 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
487 buf.size =
6;
488 buf.pos =
3;
489 CX_TEST_DO {
490 int result = cxBufferSeek(&buf,
-6,
SEEK_END);
491 CX_TEST_ASSERT(result ==
0);
492 CX_TEST_ASSERT(buf.pos ==
0);
493 }
494 cxBufferDestroy(&buf);
495 }
496
497 CX_TEST(test_buffer_seek_end_invalid) {
498 CxBuffer buf;
499 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
500 buf.size =
6;
501 buf.pos =
3;
502 CX_TEST_DO {
503 int result = cxBufferSeek(&buf,
1,
SEEK_END);
504 CX_TEST_ASSERT(result !=
0);
505 CX_TEST_ASSERT(buf.pos ==
3);
506 }
507 cxBufferDestroy(&buf);
508 }
509
510 CX_TEST(test_buffer_seek_whence_invalid) {
511 CxBuffer buf;
512 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
513 buf.size =
6;
514 buf.pos =
3;
515 CX_TEST_DO {
516 int result = cxBufferSeek(&buf,
2,
9000);
517 CX_TEST_ASSERT(result !=
0);
518 CX_TEST_ASSERT(buf.size ==
6);
519 CX_TEST_ASSERT(buf.pos ==
3);
520 }
521 cxBufferDestroy(&buf);
522 }
523
524 CX_TEST(test_buffer_eof_reached) {
525 CxBuffer buf;
526 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
527 buf.size = buf.pos =
3;
528 CX_TEST_DO {
529 CX_TEST_ASSERT(cxBufferEof(&buf));
530 buf.pos = buf.size -
1;
531 CX_TEST_ASSERT(!cxBufferEof(&buf));
532 cxBufferPut(&buf,
'a');
533 CX_TEST_ASSERT(cxBufferEof(&buf));
534 }
535 cxBufferDestroy(&buf);
536 }
537
538 CX_TEST(test_buffer_eof_not_reached) {
539 CxBuffer buf;
540 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
541 buf.size =
6;
542 CX_TEST_DO {
543 buf.pos = buf.size -
1;
544 CX_TEST_ASSERT(!cxBufferEof(&buf));
545 buf.pos =
0;
546 cxBufferWrite(
"test",
1,
5, &buf);
547 CX_TEST_ASSERT(!cxBufferEof(&buf));
548 }
549 cxBufferDestroy(&buf);
550 }
551
552 #define TEST_BUFFER_SHIFT_SETUP(buf) \
553 CxTestingAllocator talloc; \
554 cx_testing_allocator_init(&talloc); \
555 CxAllocator *alloc = &talloc.base; \
556 CxBuffer buf; \
557 cxBufferInit(&buf,
NULL,
16, alloc,
CX_BUFFER_DEFAULT); \
558 memcpy(buf.space,
"test____XXXXXXXX",
16); \
559 buf.capacity =
8; \
560 buf.pos =
4; \
561 buf.size =
4
562 #define TEST_BUFFER_SHIFT_TEARDOWN(buf) \
563 cxBufferDestroy(&buf); \
564 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); \
565 cx_testing_allocator_destroy(&talloc)
566
567
568 CX_TEST(test_buffer_shift_left_zero) {
569 TEST_BUFFER_SHIFT_SETUP(buf);
570 CX_TEST_DO {
571 int ret = cxBufferShiftLeft(&buf,
0);
572 CX_TEST_ASSERT(ret ==
0);
573 CX_TEST_ASSERT(buf.pos ==
4);
574 CX_TEST_ASSERT(buf.size ==
4);
575 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
576 TEST_BUFFER_SHIFT_TEARDOWN(buf);
577 }
578 }
579
580 CX_TEST(test_buffer_shift_left_zero_offset_interface) {
581 TEST_BUFFER_SHIFT_SETUP(buf);
582 CX_TEST_DO {
583 int ret = cxBufferShift(&buf,
-0);
584 CX_TEST_ASSERT(ret ==
0);
585 CX_TEST_ASSERT(buf.pos ==
4);
586 CX_TEST_ASSERT(buf.size ==
4);
587 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
588 TEST_BUFFER_SHIFT_TEARDOWN(buf);
589 }
590 }
591
592 CX_TEST(test_buffer_shift_left_standard) {
593 TEST_BUFFER_SHIFT_SETUP(buf);
594 CX_TEST_DO {
595 int ret = cxBufferShiftLeft(&buf,
2);
596 CX_TEST_ASSERT(ret ==
0);
597 CX_TEST_ASSERT(buf.pos ==
2);
598 CX_TEST_ASSERT(buf.size ==
2);
599 CX_TEST_ASSERT(memcmp(buf.space,
"stst____XXXXXXXX",
16) ==
0);
600 TEST_BUFFER_SHIFT_TEARDOWN(buf);
601 }
602 }
603
604 CX_TEST(test_buffer_shift_left_overshift) {
605 TEST_BUFFER_SHIFT_SETUP(buf);
606 CX_TEST_DO {
607 int ret = cxBufferShiftLeft(&buf,
6);
608 CX_TEST_ASSERT(ret ==
0);
609 CX_TEST_ASSERT(buf.pos ==
0);
610 CX_TEST_ASSERT(buf.size ==
0);
611 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
612 TEST_BUFFER_SHIFT_TEARDOWN(buf);
613 }
614 }
615
616 CX_TEST(test_buffer_shift_left_overshift_pos_only) {
617 TEST_BUFFER_SHIFT_SETUP(buf);
618 buf.pos =
2;
619 CX_TEST_DO {
620 int ret = cxBufferShiftLeft(&buf,
3);
621 CX_TEST_ASSERT(ret ==
0);
622 CX_TEST_ASSERT(buf.pos ==
0);
623 CX_TEST_ASSERT(buf.size ==
1);
624 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
625 TEST_BUFFER_SHIFT_TEARDOWN(buf);
626 }
627 }
628
629 CX_TEST(test_buffer_shift_left_offset_interface) {
630 TEST_BUFFER_SHIFT_SETUP(buf);
631 buf.pos =
3;
632 CX_TEST_DO {
633 int ret = cxBufferShift(&buf,
-2);
634 CX_TEST_ASSERT(ret ==
0);
635 CX_TEST_ASSERT(buf.pos ==
1);
636 CX_TEST_ASSERT(buf.size ==
2);
637 CX_TEST_ASSERT(memcmp(buf.space,
"stst____XXXXXXXX",
16) ==
0);
638 TEST_BUFFER_SHIFT_TEARDOWN(buf);
639 }
640 }
641
642 CX_TEST(test_buffer_shift_left_copy_on_write) {
643 TEST_BUFFER_SHIFT_SETUP(buf);
644 buf.flags |=
CX_BUFFER_COPY_ON_WRITE;
645 char *original = buf.space;
646 CX_TEST_DO {
647 int ret = cxBufferShiftLeft(&buf,
2);
648 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
649 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_FREE_CONTENTS));
650 CX_TEST_ASSERT(ret ==
0);
651 CX_TEST_ASSERT(buf.pos ==
2);
652 CX_TEST_ASSERT(buf.size ==
2);
653 CX_TEST_ASSERT(memcmp(original,
"test____XXXXXXXX",
16) ==
0);
654 CX_TEST_ASSERT(memcmp(buf.space,
"st",
2) ==
0);
655 cxFree(buf.allocator, original);
656 TEST_BUFFER_SHIFT_TEARDOWN(buf);
657 }
658 }
659
660 CX_TEST(test_buffer_shift_right_zero) {
661 TEST_BUFFER_SHIFT_SETUP(buf);
662 CX_TEST_DO {
663 int ret = cxBufferShiftRight(&buf,
0);
664 CX_TEST_ASSERT(ret ==
0);
665 CX_TEST_ASSERT(buf.pos ==
4);
666 CX_TEST_ASSERT(buf.size ==
4);
667 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
668 TEST_BUFFER_SHIFT_TEARDOWN(buf);
669 }
670 }
671
672 CX_TEST(test_buffer_shift_right_zero_offset_interface) {
673 TEST_BUFFER_SHIFT_SETUP(buf);
674 CX_TEST_DO {
675 int ret = cxBufferShift(&buf,
+0);
676 CX_TEST_ASSERT(ret ==
0);
677 CX_TEST_ASSERT(buf.pos ==
4);
678 CX_TEST_ASSERT(buf.size ==
4);
679 CX_TEST_ASSERT(memcmp(buf.space,
"test____XXXXXXXX",
16) ==
0);
680 TEST_BUFFER_SHIFT_TEARDOWN(buf);
681 }
682 }
683
684 CX_TEST(test_buffer_shift_right_standard) {
685 TEST_BUFFER_SHIFT_SETUP(buf);
686 CX_TEST_DO {
687 int ret = cxBufferShiftRight(&buf,
3);
688 CX_TEST_ASSERT(ret ==
0);
689 CX_TEST_ASSERT(buf.pos ==
7);
690 CX_TEST_ASSERT(buf.size ==
7);
691 CX_TEST_ASSERT(memcmp(buf.space,
"testest_XXXXXXXX",
16) ==
0);
692 TEST_BUFFER_SHIFT_TEARDOWN(buf);
693 }
694 }
695
696 CX_TEST(test_buffer_shift_right_overshift_discard) {
697 TEST_BUFFER_SHIFT_SETUP(buf);
698 CX_TEST_DO {
699 int ret = cxBufferShiftRight(&buf,
6);
700 CX_TEST_ASSERT(ret ==
0);
701 CX_TEST_ASSERT(buf.pos ==
8);
702 CX_TEST_ASSERT(buf.size ==
8);
703 CX_TEST_ASSERT(buf.capacity ==
8);
704 CX_TEST_ASSERT(memcmp(buf.space,
"test__teXXXXXXXX",
16) ==
0);
705 TEST_BUFFER_SHIFT_TEARDOWN(buf);
706 }
707 }
708
709 CX_TEST(test_buffer_shift_right_overshift_extend) {
710 TEST_BUFFER_SHIFT_SETUP(buf);
711 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
712 CX_TEST_DO {
713 int ret = cxBufferShiftRight(&buf,
6);
714 CX_TEST_ASSERT(ret ==
0);
715 CX_TEST_ASSERT(buf.pos ==
10);
716 CX_TEST_ASSERT(buf.size ==
10);
717 CX_TEST_ASSERT(buf.capacity >=
10);
718
719
720 CX_TEST_ASSERT(memcmp(buf.space,
"test__test",
10) ==
0);
721 TEST_BUFFER_SHIFT_TEARDOWN(buf);
722 }
723 }
724
725 CX_TEST(test_buffer_shift_right_offset_interface) {
726 TEST_BUFFER_SHIFT_SETUP(buf);
727 buf.pos =
3;
728 CX_TEST_DO {
729 int ret = cxBufferShift(&buf,
2);
730 CX_TEST_ASSERT(ret ==
0);
731 CX_TEST_ASSERT(buf.pos ==
5);
732 CX_TEST_ASSERT(buf.size ==
6);
733 CX_TEST_ASSERT(memcmp(buf.space,
"tetest__XXXXXXXX",
16) ==
0);
734 TEST_BUFFER_SHIFT_TEARDOWN(buf);
735 }
736 }
737
738 CX_TEST(test_buffer_shift_right_copy_on_write) {
739 TEST_BUFFER_SHIFT_SETUP(buf);
740 buf.flags |=
CX_BUFFER_COPY_ON_WRITE;
741 char *original = buf.space;
742 CX_TEST_DO {
743 int ret = cxBufferShiftRight(&buf,
3);
744 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
745 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_FREE_CONTENTS));
746 CX_TEST_ASSERT(ret ==
0);
747 CX_TEST_ASSERT(buf.pos ==
7);
748 CX_TEST_ASSERT(buf.size ==
7);
749 CX_TEST_ASSERT(memcmp(original,
"test____XXXXXXXX",
16) ==
0);
750 CX_TEST_ASSERT(memcmp(buf.space,
"testest",
7) ==
0);
751 cxFree(buf.allocator, original);
752 TEST_BUFFER_SHIFT_TEARDOWN(buf);
753 }
754 }
755
756 CX_TEST(test_buffer_shift_right_overflow) {
757 TEST_BUFFER_SHIFT_SETUP(buf);
758 CX_TEST_DO {
759 errno =
0;
760 int ret = cxBufferShiftRight(&buf,
SIZE_MAX -
2);
761 CX_TEST_ASSERT(ret !=
0);
762 CX_TEST_ASSERT(errno ==
EOVERFLOW);
763 TEST_BUFFER_SHIFT_TEARDOWN(buf);
764 }
765 }
766
767 static size_t mock_write_limited_rate(
768 const void *ptr,
769 size_t size,
770 cx_attr_unused
size_t nitems,
771 CxBuffer *buffer
772 ) {
773 return cxBufferWrite(ptr, size, nitems >
2 ?
2 : nitems, buffer);
774 }
775
776 CX_TEST(test_buffer_write_size_one_fit) {
777 CxBuffer buf;
778 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
779 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
780 buf.capacity =
8;
781 buf.size = buf.pos =
4;
782 const char *data =
"test";
783 CX_TEST_DO {
784 size_t written = cxBufferWrite(data,
1,
4, &buf);
785 CX_TEST_ASSERT(written ==
4);
786 CX_TEST_ASSERT(buf.size ==
8);
787 CX_TEST_ASSERT(buf.pos ==
8);
788 CX_TEST_ASSERT(buf.capacity ==
8);
789 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest",
8));
790 }
791
792 cxBufferDestroy(&buf);
793 }
794
795 CX_TEST(test_buffer_write_size_one_discard) {
796 CxBuffer buf;
797 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
798 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
799 buf.capacity =
8;
800 buf.size = buf.pos =
4;
801 const char *data =
"testing";
802 CX_TEST_DO {
803 size_t written = cxBufferWrite(data,
1,
7, &buf);
804 CX_TEST_ASSERT(written ==
4);
805 CX_TEST_ASSERT(buf.size ==
8);
806 CX_TEST_ASSERT(buf.pos ==
8);
807 CX_TEST_ASSERT(buf.capacity ==
8);
808 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest\0",
9));
809 }
810 cxBufferDestroy(&buf);
811 }
812
813 CX_TEST(test_buffer_write_size_one_extend) {
814 CxBuffer buf;
815 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
816 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
817 buf.capacity =
8;
818 buf.size = buf.pos =
4;
819 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
820 const char *data =
"testing";
821 CX_TEST_DO {
822 size_t written = cxBufferWrite(data,
1,
7, &buf);
823 CX_TEST_ASSERT(written ==
7);
824 CX_TEST_ASSERT(buf.size ==
11);
825 CX_TEST_ASSERT(buf.pos ==
11);
826 CX_TEST_ASSERT(buf.capacity >=
11);
827 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptesting",
11));
828 }
829 cxBufferDestroy(&buf);
830 }
831
832 CX_TEST(test_buffer_write_copy_on_write) {
833 CxBuffer buf;
834 char original[
16] =
"preparedXXXXXXX";
835 cxBufferInit(&buf, original,
16, cxDefaultAllocator,
CX_BUFFER_COPY_ON_WRITE);
836 buf.capacity =
8;
837 buf.size =
8;
838 buf.pos =
0;
839 const char *data =
"testing";
840 CX_TEST_DO {
841 size_t written = cxBufferWrite(data,
1,
7, &buf);
842 CX_TEST_ASSERT(written ==
7);
843 CX_TEST_ASSERT(buf.size ==
8);
844 CX_TEST_ASSERT(buf.pos ==
7);
845 CX_TEST_ASSERT(buf.capacity ==
8);
846 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"testingd",
8));
847 CX_TEST_ASSERT(
0 == memcmp(original,
"preparedXXXXXXX\0",
16));
848 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
849 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_FREE_CONTENTS));
850 }
851 cxBufferDestroy(&buf);
852 }
853
854 CX_TEST(test_buffer_write_multibyte_fit) {
855 CxBuffer buf;
856 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
857 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
858 buf.capacity =
8;
859 buf.size = buf.pos =
4;
860 const char *data =
"test";
861 CX_TEST_DO {
862 size_t written = cxBufferWrite(data,
2,
2, &buf);
863 CX_TEST_ASSERT(written ==
2);
864 CX_TEST_ASSERT(buf.size ==
8);
865 CX_TEST_ASSERT(buf.pos ==
8);
866 CX_TEST_ASSERT(buf.capacity ==
8);
867 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest",
8));
868 }
869 cxBufferDestroy(&buf);
870 }
871
872 CX_TEST(test_buffer_write_multibyte_discard) {
873 CxBuffer buf;
874 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
875 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
876 buf.capacity =
8;
877 buf.size =
4;
878 buf.pos =
3;
879 const char *data =
"testing";
880 CX_TEST_DO {
881 size_t written = cxBufferWrite(data,
2,
4, &buf);
882
883 CX_TEST_ASSERT(written ==
2);
884 CX_TEST_ASSERT(buf.size ==
7);
885 CX_TEST_ASSERT(buf.pos ==
7);
886 CX_TEST_ASSERT(buf.capacity ==
8);
887 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"pretest\0",
8));
888 }
889 cxBufferDestroy(&buf);
890 }
891
892 CX_TEST(test_buffer_write_multibyte_extend) {
893 CxBuffer buf;
894 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
895 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
896 buf.capacity =
8;
897 buf.size =
4;
898 buf.pos =
3;
899 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
900 const char *data =
"tester";
901 CX_TEST_DO {
902 size_t written = cxBufferWrite(data,
2,
3, &buf);
903
904 CX_TEST_ASSERT(written ==
3);
905 CX_TEST_ASSERT(buf.size ==
9);
906 CX_TEST_ASSERT(buf.pos ==
9);
907 CX_TEST_ASSERT(buf.capacity >=
9);
908 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"pretester",
9));
909 }
910 cxBufferDestroy(&buf);
911 }
912
913 CX_TEST(test_buffer_append) {
914 CxBuffer buf;
915 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
916 memcpy(buf.space,
"prepXXXX\0\0\0\0\0\0\0\0",
16);
917 buf.capacity =
8;
918 buf.size =
6;
919 buf.pos =
4;
920 CX_TEST_DO {
921 size_t written = cxBufferAppend(
"testing",
1,
7, &buf);
922 CX_TEST_ASSERT(written ==
7);
923 CX_TEST_ASSERT(buf.size ==
13);
924 CX_TEST_ASSERT(buf.pos ==
4);
925 CX_TEST_ASSERT(buf.capacity >=
13);
926 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prepXXtesting",
13));
927 }
928 cxBufferDestroy(&buf);
929 }
930
931 CX_TEST(test_buffer_append_flush) {
932 CxBuffer buf, target;
933 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
934 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
935 memcpy(buf.space,
"prepXXXX",
8);
936 buf.capacity =
8;
937 buf.size =
6;
938 buf.pos =
4;
939 CxBufferFlushConfig flush;
940 flush.threshold =
0;
941 flush.blksize =
4;
942 flush.blkmax =
1;
943 flush.target = ⌖
944 flush.wfunc = cxBufferWriteFunc;
945 cxBufferEnableFlushing(&buf, flush);
946 CX_TEST_DO{
947 size_t written = cxBufferAppend(
"testing",
1,
7, &buf);
948 CX_TEST_ASSERT(written ==
7);
949 CX_TEST_ASSERT(buf.size ==
7);
950 CX_TEST_ASSERTM(buf.pos ==
0,
"position not correctly reset");
951 CX_TEST_ASSERT(buf.capacity ==
8);
952 CX_TEST_ASSERT(target.size ==
6);
953 CX_TEST_ASSERT(target.pos ==
6);
954 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"testing",
7));
955 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepXX",
6));
956
957 buf.pos =
6;
958 written = cxBufferAppend(
"foo",
1,
3, &buf);
959 CX_TEST_ASSERT(written ==
3);
960 CX_TEST_ASSERT(buf.size ==
6);
961 CX_TEST_ASSERTM(buf.pos ==
2,
"position not correctly adjusted");
962 CX_TEST_ASSERT(buf.capacity ==
8);
963 CX_TEST_ASSERT(target.size ==
10);
964 CX_TEST_ASSERT(target.pos ==
10);
965 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"ingfoo",
6));
966 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepXXtest",
10));
967 }
968 cxBufferDestroy(&buf);
969 cxBufferDestroy(&target);
970 }
971
972 CX_TEST(test_buffer_put_fit) {
973 CxBuffer buf;
974 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
975 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
976 buf.capacity =
8;
977 buf.size = buf.pos =
4;
978 CX_TEST_DO {
979 int c = cxBufferPut(&buf,
0x200 |
'a');
980 CX_TEST_ASSERT(c ==
'a');
981 CX_TEST_ASSERT(buf.size ==
5);
982 CX_TEST_ASSERT(buf.pos ==
5);
983 CX_TEST_ASSERT(buf.capacity ==
8);
984 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prepa\0",
6));
985 }
986 cxBufferDestroy(&buf);
987 }
988
989 CX_TEST(test_buffer_put_discard) {
990 CxBuffer buf;
991 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
992 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
993 buf.capacity =
8;
994 buf.size =
4;
995 buf.pos =
8;
996 CX_TEST_DO {
997 int c = cxBufferPut(&buf,
0x200 |
'a');
998 CX_TEST_ASSERT(c ==
EOF);
999 CX_TEST_ASSERT(buf.size ==
4);
1000 CX_TEST_ASSERT(buf.pos ==
8);
1001 CX_TEST_ASSERT(buf.capacity ==
8);
1002 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prep\0\0\0\0\0",
9));
1003 }
1004 cxBufferDestroy(&buf);
1005 }
1006
1007 CX_TEST(test_buffer_put_extend) {
1008 CxBuffer buf;
1009 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1010 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1011 buf.capacity =
8;
1012 buf.size =
4;
1013 buf.pos =
8;
1014 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1015 CX_TEST_DO {
1016 int c = cxBufferPut(&buf,
0x200 |
'a');
1017 CX_TEST_ASSERT(c ==
'a');
1018 CX_TEST_ASSERT(buf.size ==
9);
1019 CX_TEST_ASSERT(buf.pos ==
9);
1020 CX_TEST_ASSERT(buf.capacity >=
9);
1021 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prep\0\0\0\0a",
9));
1022 }
1023 cxBufferDestroy(&buf);
1024 }
1025
1026 CX_TEST(test_buffer_put_copy_on_write) {
1027 CxBuffer buf;
1028 char original[
16] =
"preparedXXXXXXX";
1029 cxBufferInit(&buf, original,
16, cxDefaultAllocator,
CX_BUFFER_COPY_ON_WRITE);
1030 buf.capacity =
8;
1031 buf.size =
8;
1032 buf.pos =
8;
1033 CX_TEST_DO {
1034 int c = cxBufferPut(&buf,
0x200 |
'a');
1035 CX_TEST_ASSERT(c ==
EOF);
1036 CX_TEST_ASSERT(buf.size ==
8);
1037 CX_TEST_ASSERT(buf.pos ==
8);
1038 CX_TEST_ASSERT(buf.capacity ==
8);
1039 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prepared",
8));
1040
1041 CX_TEST_ASSERT(original == buf.space);
1042 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
1043 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_FREE_CONTENTS));
1044
1045 buf.pos =
2;
1046 c = cxBufferPut(&buf,
0x200 |
'a');
1047 CX_TEST_ASSERT(c ==
'a');
1048 CX_TEST_ASSERT(buf.size ==
8);
1049 CX_TEST_ASSERT(buf.pos ==
3);
1050 CX_TEST_ASSERT(buf.capacity ==
8);
1051 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prapared",
8));
1052 CX_TEST_ASSERT(original != buf.space);
1053 CX_TEST_ASSERT(
0 == memcmp(original,
"preparedXXXXXXX\0",
16));
1054 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
1055 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_FREE_CONTENTS));
1056 }
1057 cxBufferDestroy(&buf);
1058 }
1059
1060 CX_TEST(test_buffer_put_string_fit) {
1061 CxBuffer buf;
1062 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1063 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1064 buf.capacity =
8;
1065 buf.size = buf.pos =
4;
1066 const char *data =
"test";
1067 CX_TEST_DO {
1068 size_t written = cxBufferPutString(&buf, data);
1069 CX_TEST_ASSERT(written ==
4);
1070 CX_TEST_ASSERT(buf.size ==
8);
1071 CX_TEST_ASSERT(buf.pos ==
8);
1072 CX_TEST_ASSERT(buf.capacity ==
8);
1073 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest",
8));
1074 }
1075 cxBufferDestroy(&buf);
1076 }
1077
1078 CX_TEST(test_buffer_put_string_discard) {
1079 CxBuffer buf;
1080 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1081 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1082 buf.capacity =
8;
1083 buf.size = buf.pos =
4;
1084 const char *data =
"testing";
1085 CX_TEST_DO {
1086 size_t written = cxBufferPutString(&buf, data);
1087 CX_TEST_ASSERT(written ==
4);
1088 CX_TEST_ASSERT(buf.size ==
8);
1089 CX_TEST_ASSERT(buf.pos ==
8);
1090 CX_TEST_ASSERT(buf.capacity ==
8);
1091 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest\0",
9));
1092 }
1093 cxBufferDestroy(&buf);
1094 }
1095
1096 CX_TEST(test_buffer_put_string_extend) {
1097 CxBuffer buf;
1098 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1099 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1100 buf.capacity =
8;
1101 buf.size = buf.pos =
4;
1102 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1103 const char *data =
"testing";
1104 CX_TEST_DO {
1105 size_t written = cxBufferPutString(&buf, data);
1106 CX_TEST_ASSERT(written ==
7);
1107 CX_TEST_ASSERT(buf.size ==
11);
1108 CX_TEST_ASSERT(buf.pos ==
11);
1109 CX_TEST_ASSERT(buf.capacity >=
11);
1110 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptesting",
11));
1111 }
1112 cxBufferDestroy(&buf);
1113 }
1114
1115 CX_TEST(test_buffer_put_string_copy_on_extend) {
1116 CxTestingAllocator talloc;
1117 cx_testing_allocator_init(&talloc);
1118 const CxAllocator *alloc = &talloc.base;
1119 CxBuffer buf;
1120 char original[
16] =
"preparedXXXXXXX";
1121 CX_TEST_DO {
1122 cxBufferInit(&buf, original,
16, alloc,
CX_BUFFER_COPY_ON_EXTEND);
1123 buf.capacity =
8;
1124 buf.size = buf.pos =
4;
1125 size_t written = cxBufferPutString(&buf,
"test");
1126 CX_TEST_ASSERT(written ==
4);
1127 CX_TEST_ASSERT(buf.size ==
8);
1128 CX_TEST_ASSERT(buf.pos ==
8);
1129 CX_TEST_ASSERT(buf.capacity ==
8);
1130 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest",
8));
1131 CX_TEST_ASSERT(original == buf.space);
1132 written = cxBufferPutString(&buf,
"ing");
1133 CX_TEST_ASSERT(written ==
3);
1134 CX_TEST_ASSERT(buf.size ==
11);
1135 CX_TEST_ASSERT(buf.pos ==
11);
1136 CX_TEST_ASSERT(buf.capacity >=
11);
1137 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptesting",
11));
1138 CX_TEST_ASSERT(original != buf.space);
1139 CX_TEST_ASSERT(
0 == memcmp(original,
"preptestXXXXXXX\0",
16));
1140 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc));
1141 cxBufferDestroy(&buf);
1142 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
1143 cx_testing_allocator_destroy(&talloc);
1144 }
1145 }
1146
1147 CX_TEST(test_buffer_put_string_copy_on_write) {
1148 CxBuffer buf;
1149 char original[
16] =
"preparedXXXXXXX";
1150 cxBufferInit(&buf, original,
16, cxDefaultAllocator,
CX_BUFFER_COPY_ON_WRITE);
1151 buf.capacity =
8;
1152 buf.size =
8;
1153 buf.pos =
4;
1154 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1155 const char *data =
"testing";
1156 CX_TEST_DO {
1157 size_t written = cxBufferPutString(&buf, data);
1158 CX_TEST_ASSERT(written ==
7);
1159 CX_TEST_ASSERT(buf.size ==
11);
1160 CX_TEST_ASSERT(buf.pos ==
11);
1161 CX_TEST_ASSERT(buf.capacity >=
11);
1162 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptesting",
11));
1163 CX_TEST_ASSERT(original != buf.space);
1164 CX_TEST_ASSERT(
0 == memcmp(original,
"preparedXXXXXXX\0",
16));
1165 CX_TEST_ASSERT(
0 == (buf.flags &
CX_BUFFER_COPY_ON_WRITE));
1166 CX_TEST_ASSERT(
0 != (buf.flags &
CX_BUFFER_FREE_CONTENTS));
1167 }
1168 cxBufferDestroy(&buf);
1169 }
1170
1171 CX_TEST(test_buffer_terminate) {
1172 CxBuffer buf;
1173 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1174 memcpy(buf.space,
"prepAAAAAA\0\0\0\0\0\0",
16);
1175 buf.capacity =
8;
1176 buf.size = buf.pos =
4;
1177 const char *data =
"test";
1178 CX_TEST_DO {
1179 size_t written = cxBufferPutString(&buf, data);
1180 CX_TEST_ASSERT(
0 != cxBufferTerminate(&buf));
1181 CX_TEST_ASSERT(written ==
4);
1182 CX_TEST_ASSERT(buf.size ==
8);
1183 CX_TEST_ASSERT(buf.pos ==
8);
1184 CX_TEST_ASSERT(buf.capacity ==
8);
1185 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptestAA",
10));
1186 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1187 CX_TEST_ASSERT(
0 == cxBufferTerminate(&buf));
1188 CX_TEST_ASSERT(buf.size ==
8);
1189 CX_TEST_ASSERT(buf.pos ==
9);
1190 CX_TEST_ASSERT(buf.capacity >
8);
1191 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preptest\0",
9));
1192 }
1193 cxBufferDestroy(&buf);
1194 }
1195
1196 CX_TEST(test_buffer_write_size_overflow) {
1197 CxBuffer buf;
1198 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1199 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1200 buf.capacity =
8;
1201 buf.size = buf.pos =
4;
1202 const char *data =
"testing";
1203 CX_TEST_DO {
1204 size_t written = cxBufferWrite(data,
8,
SIZE_MAX /
4, &buf);
1205 CX_TEST_ASSERT(written ==
0);
1206 CX_TEST_ASSERT(buf.capacity ==
8);
1207 CX_TEST_ASSERT(buf.pos ==
4);
1208 CX_TEST_ASSERT(buf.size ==
4);
1209 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prep\0",
5));
1210 }
1211 cxBufferDestroy(&buf);
1212 }
1213
1214 CX_TEST(test_buffer_write_capacity_overflow) {
1215 CxBuffer buf;
1216 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1217 memcpy(buf.space,
"prep\0\0\0\0\0\0\0\0\0\0\0\0",
16);
1218 buf.capacity =
8;
1219 buf.size = buf.pos =
4;
1220 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1221 const char *data =
"testing";
1222 CX_TEST_DO {
1223 size_t written = cxBufferWrite(data,
1,
SIZE_MAX -
2, &buf);
1224 CX_TEST_ASSERT(written ==
0);
1225 CX_TEST_ASSERT(buf.capacity ==
8);
1226 CX_TEST_ASSERT(buf.pos ==
4);
1227 CX_TEST_ASSERT(buf.size ==
4);
1228 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prep\0",
5));
1229 }
1230 cxBufferDestroy(&buf);
1231 }
1232
1233 CX_TEST(test_buffer_write_only_overwrite) {
1234 CxBuffer buf;
1235 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1236 memcpy(buf.space,
"preptest\0\0\0\0\0\0\0\0",
16);
1237 buf.capacity =
8;
1238 buf.pos =
3;
1239 buf.size =
8;
1240 buf.flags |=
CX_BUFFER_AUTO_EXTEND;
1241 CX_TEST_DO {
1242 size_t written = cxBufferWrite(
"XXX",
2,
2, &buf);
1243 CX_TEST_ASSERT(written ==
2);
1244 CX_TEST_ASSERT(buf.capacity ==
8);
1245 CX_TEST_ASSERT(buf.size ==
8);
1246 CX_TEST_ASSERT(buf.pos ==
7);
1247 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"preXXX\0t",
8));
1248 }
1249 cxBufferDestroy(&buf);
1250 }
1251
1252 CX_TEST(test_buffer_write_flush_at_capacity) {
1253 CxBuffer buf, target;
1254 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1255 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1256 memset(buf.space,
0,
8);
1257 cxBufferPutString(&buf,
"prep");
1258 CX_TEST_DO {
1259 CxBufferFlushConfig flush;
1260 flush.threshold =
0;
1261 flush.blksize =
32;
1262 flush.blkmax =
1;
1263 flush.target = ⌖
1264 flush.wfunc = cxBufferWriteFunc;
1265 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1266 size_t written = cxBufferWrite(
"foo",
1,
3, &buf);
1267 CX_TEST_ASSERT(written ==
3);
1268 CX_TEST_ASSERT(buf.pos ==
7);
1269 CX_TEST_ASSERT(buf.size ==
7);
1270 CX_TEST_ASSERT(target.pos ==
0);
1271 CX_TEST_ASSERT(target.size ==
0);
1272 written = cxBufferWrite(
"hello",
1,
5, &buf);
1273 CX_TEST_ASSERT(written ==
5);
1274 CX_TEST_ASSERT(buf.pos ==
5);
1275 CX_TEST_ASSERT(buf.size ==
5);
1276 CX_TEST_ASSERT(buf.capacity ==
8);
1277 CX_TEST_ASSERT(target.pos ==
7);
1278 CX_TEST_ASSERT(target.size ==
7);
1279 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"hello",
5));
1280 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoo",
7));
1281 }
1282 cxBufferDestroy(&buf);
1283 cxBufferDestroy(&target);
1284 }
1285
1286 CX_TEST(test_buffer_write_flush_at_threshold) {
1287 CxBuffer buf, target;
1288 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1289 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1290 cxBufferPutString(&buf,
"prep");
1291 CX_TEST_DO {
1292 CxBufferFlushConfig flush;
1293 flush.threshold =
16;
1294 flush.blksize =
32;
1295 flush.blkmax =
1;
1296 flush.target = ⌖
1297 flush.wfunc = cxBufferWriteFunc;
1298 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1299 size_t written = cxBufferWrite(
"foobar",
1,
6, &buf);
1300 CX_TEST_ASSERT(written ==
6);
1301 CX_TEST_ASSERT(buf.pos ==
10);
1302 CX_TEST_ASSERT(buf.size ==
10);
1303 CX_TEST_ASSERT(buf.capacity ==
16);
1304 CX_TEST_ASSERT(target.pos ==
0);
1305 CX_TEST_ASSERT(target.size ==
0);
1306 written = cxBufferWrite(
"hello world",
1,
11, &buf);
1307 CX_TEST_ASSERT(written ==
11);
1308 CX_TEST_ASSERT(buf.pos ==
11);
1309 CX_TEST_ASSERT(buf.size ==
11);
1310 CX_TEST_ASSERT(buf.capacity ==
16);
1311 CX_TEST_ASSERT(target.pos ==
10);
1312 CX_TEST_ASSERT(target.size ==
10);
1313 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"hello",
5));
1314 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoobar",
10));
1315 }
1316 cxBufferDestroy(&buf);
1317 cxBufferDestroy(&target);
1318 }
1319
1320 CX_TEST(test_buffer_write_flush_rate_limited_and_buffer_too_small) {
1321
1322
1323
1324
1325 CxBuffer buf, target;
1326 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1327 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1328 cxBufferPutString(&buf,
"prep");
1329 CX_TEST_DO {
1330 CxBufferFlushConfig flush;
1331 flush.threshold =
0;
1332 flush.blksize =
32;
1333 flush.blkmax =
1;
1334 flush.target = ⌖
1335 flush.wfunc = (cx_write_func)mock_write_limited_rate;
1336 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1337 size_t written = cxBufferWrite(
"foo",
1,
3, &buf);
1338 CX_TEST_ASSERT(written ==
3);
1339 CX_TEST_ASSERT(buf.pos ==
7);
1340 CX_TEST_ASSERT(buf.size ==
7);
1341 CX_TEST_ASSERT(target.pos ==
0);
1342 CX_TEST_ASSERT(target.size ==
0);
1343 written = cxBufferWrite(
"hello, world!",
1,
13, &buf);
1344
1345 CX_TEST_ASSERT(written ==
13);
1346 CX_TEST_ASSERT(buf.pos ==
7);
1347 CX_TEST_ASSERT(buf.size ==
7);
1348 CX_TEST_ASSERT(buf.capacity ==
8);
1349 CX_TEST_ASSERT(
0 == memcmp(buf.space,
" world!",
7));
1350 CX_TEST_ASSERT(target.pos ==
13);
1351 CX_TEST_ASSERT(target.size ==
13);
1352 CX_TEST_ASSERT(target.capacity >=
13);
1353 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoohello,",
13));
1354 }
1355 cxBufferDestroy(&buf);
1356 cxBufferDestroy(&target);
1357 }
1358
1359 CX_TEST(test_buffer_write_flush_multibyte) {
1360
1361
1362 CxBuffer buf, target;
1363 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1364 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1365 memset(buf.space,
0,
8);
1366 cxBufferPutString(&buf,
"pre");
1367 CX_TEST_DO {
1368 CxBufferFlushConfig flush;
1369 flush.threshold =
0;
1370 flush.blksize =
4;
1371 flush.blkmax =
2;
1372 flush.target = ⌖
1373 flush.wfunc = cxBufferWriteFunc;
1374 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1375
1376 size_t written = cxBufferWrite(
"foobar",
3,
2, &buf);
1377 CX_TEST_ASSERT(written ==
2);
1378 CX_TEST_ASSERT(buf.pos ==
6);
1379 CX_TEST_ASSERT(buf.size ==
6);
1380 CX_TEST_ASSERT(target.pos ==
3);
1381 CX_TEST_ASSERT(target.size ==
3);
1382 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"foobar",
6));
1383 CX_TEST_ASSERT(
0 == memcmp(target.space,
"pre",
3));
1384
1385 written = cxBufferWrite(
"bazfooBAR",
3,
3, &buf);
1386 CX_TEST_ASSERT(written ==
3);
1387 CX_TEST_ASSERT(buf.pos ==
3);
1388 CX_TEST_ASSERT(buf.size ==
3);
1389 CX_TEST_ASSERT(target.pos ==
15);
1390 CX_TEST_ASSERT(target.size ==
15);
1391 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"BAR",
3));
1392 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prefoobarbazfoo",
15));
1393
1394 buf.flush->blkmax =
3;
1395 written = cxBufferWrite(
"abcdef012",
3,
3, &buf);
1396 CX_TEST_ASSERT(written ==
3);
1397 CX_TEST_ASSERT(buf.pos ==
0);
1398 CX_TEST_ASSERT(buf.size ==
0);
1399 CX_TEST_ASSERT(target.pos ==
27);
1400 CX_TEST_ASSERT(target.size ==
27);
1401 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prefoobarbazfooBARabcdef012",
27));
1402 }
1403 cxBufferDestroy(&buf);
1404 cxBufferDestroy(&target);
1405 }
1406
1407 CX_TEST(test_buffer_write_flush_misaligned) {
1408
1409
1410 CxBuffer buf, target;
1411 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1412 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1413 cxBufferPutString(&buf,
"prep");
1414 CX_TEST_DO {
1415 CxBufferFlushConfig flush;
1416 flush.threshold =
0;
1417 flush.blksize =
32;
1418 flush.blkmax =
1;
1419 flush.target = ⌖
1420 flush.wfunc = cxBufferWriteFunc;
1421 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1422
1423 size_t written = cxBufferWrite(
"foobar",
3,
2, &buf);
1424 CX_TEST_ASSERT(written ==
2);
1425 CX_TEST_ASSERT(buf.pos ==
7);
1426 CX_TEST_ASSERT(buf.size ==
7);
1427 CX_TEST_ASSERT(target.pos ==
3);
1428 CX_TEST_ASSERT(target.size ==
3);
1429 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"pfoobar",
7));
1430 CX_TEST_ASSERT(
0 == memcmp(target.space,
"pre",
3));
1431
1432
1433 written = cxBufferWrite(
"bazfoobar",
3,
3, &buf);
1434 CX_TEST_ASSERT(written ==
2);
1435 CX_TEST_ASSERT(buf.pos ==
7);
1436 CX_TEST_ASSERT(buf.size ==
7);
1437 CX_TEST_ASSERT(target.pos ==
9);
1438 CX_TEST_ASSERT(target.size ==
9);
1439 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"rbazfoo",
7));
1440 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfooba",
9));
1441 }
1442 cxBufferDestroy(&buf);
1443 cxBufferDestroy(&target);
1444 }
1445
1446 CX_TEST(test_buffer_write_flush_target_full) {
1447 CxBuffer buf, target;
1448
1449 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1450 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1451 cxBufferPutString(&buf,
"prep");
1452 CX_TEST_DO {
1453 CxBufferFlushConfig flush;
1454 flush.threshold =
0;
1455 flush.blksize =
32;
1456 flush.blkmax =
1;
1457 flush.target = ⌖
1458 flush.wfunc = cxBufferWriteFunc;
1459 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1460
1461 size_t written = cxBufferWrite(
"foobar",
1,
6, &buf);
1462 CX_TEST_ASSERT(written ==
6);
1463 CX_TEST_ASSERT(buf.pos ==
6);
1464 CX_TEST_ASSERT(buf.size ==
6);
1465 CX_TEST_ASSERT(target.pos ==
4);
1466 CX_TEST_ASSERT(target.size ==
4);
1467 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"foobar",
6));
1468 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prep",
4));
1469
1470 written = cxBufferWrite(
"xyz",
1,
3, &buf);
1471 CX_TEST_ASSERT(written ==
3);
1472 CX_TEST_ASSERT(buf.pos ==
5);
1473 CX_TEST_ASSERT(buf.size ==
5);
1474 CX_TEST_ASSERT(target.pos ==
8);
1475 CX_TEST_ASSERT(target.size ==
8);
1476 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"arxyz",
5));
1477 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1478
1479 written = cxBufferWrite(
"123456",
1,
6, &buf);
1480 CX_TEST_ASSERT(written ==
3);
1481 CX_TEST_ASSERT(buf.pos ==
8);
1482 CX_TEST_ASSERT(buf.size ==
8);
1483 CX_TEST_ASSERT(target.pos ==
8);
1484 CX_TEST_ASSERT(target.size ==
8);
1485 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"arxyz123",
8));
1486 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1487
1488 written = cxBufferWrite(
"baz",
1,
3, &buf);
1489 CX_TEST_ASSERT(written ==
0);
1490 CX_TEST_ASSERT(buf.pos ==
8);
1491 CX_TEST_ASSERT(buf.size ==
8);
1492 CX_TEST_ASSERT(target.pos ==
8);
1493 CX_TEST_ASSERT(target.size ==
8);
1494 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"arxyz123",
8));
1495 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1496 }
1497 cxBufferDestroy(&buf);
1498 cxBufferDestroy(&target);
1499 }
1500
1501 CX_TEST(test_buffer_write_flush_multibyte_target_full) {
1502 CxBuffer buf, target;
1503 cxBufferInit(&target,
NULL,
12, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1504 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1505 CX_TEST_DO {
1506 CxBufferFlushConfig flush;
1507 flush.threshold =
12;
1508 flush.blksize =
8;
1509 flush.blkmax =
2;
1510 flush.target = ⌖
1511 flush.wfunc = cxBufferWriteFunc;
1512 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1513 cxBufferPutString(&buf,
"preparation");
1514 size_t written = cxBufferWrite(
"teststring",
2,
5, &buf);
1515 CX_TEST_ASSERT(written ==
5);
1516 CX_TEST_ASSERT(buf.pos ==
11);
1517 CX_TEST_ASSERT(buf.size ==
11);
1518 CX_TEST_ASSERT(target.pos ==
10);
1519 CX_TEST_ASSERT(target.size ==
10);
1520 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"nteststring",
11));
1521 CX_TEST_ASSERT(
0 == memcmp(target.space,
"preparatio",
10));
1522
1523 cxBufferPop(&buf,
1,
1);
1524
1525 written = cxBufferWrite(
"123456",
2,
3, &buf);
1526 CX_TEST_ASSERT(written ==
2);
1527 CX_TEST_ASSERT(buf.pos ==
12);
1528 CX_TEST_ASSERT(buf.size ==
12);
1529 CX_TEST_ASSERT(target.pos ==
12);
1530 CX_TEST_ASSERT(target.size ==
12);
1531 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"eststrin1234",
12));
1532 CX_TEST_ASSERT(
0 == memcmp(target.space,
"preparationt",
12));
1533 }
1534 cxBufferDestroy(&buf);
1535 cxBufferDestroy(&target);
1536 }
1537
1538 CX_TEST(test_buffer_write_large_data_flush_target_full) {
1539 CxBuffer buf, target;
1540 cxBufferInit(&target,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1541 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1542
1543 target.pos = target.size =
16;
1544 CX_TEST_DO {
1545 CxBufferFlushConfig flush;
1546 flush.threshold =
0;
1547 flush.blksize =
32;
1548 flush.blkmax =
1;
1549 flush.target = ⌖
1550 flush.wfunc = cxBufferWriteFunc;
1551 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1552
1553 size_t written = cxBufferWrite(
"foobarfoobar",
1,
12, &buf);
1554 CX_TEST_ASSERT(written ==
0);
1555 CX_TEST_ASSERT(buf.pos ==
0);
1556 CX_TEST_ASSERT(buf.size ==
0);
1557 CX_TEST_ASSERT(target.pos ==
16);
1558 CX_TEST_ASSERT(target.size ==
16);
1559 }
1560 cxBufferDestroy(&buf);
1561 cxBufferDestroy(&target);
1562 }
1563
1564 CX_TEST(test_buffer_write_flush_at_threshold_target_full) {
1565 CxBuffer buf, target;
1566
1567 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1568
1569 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1570 cxBufferPutString(&buf,
"prep");
1571 CX_TEST_DO {
1572 CxBufferFlushConfig flush;
1573 flush.threshold =
16;
1574 flush.blksize =
4;
1575 flush.blkmax =
2;
1576 flush.target = ⌖
1577 flush.wfunc = cxBufferWriteFunc;
1578 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1579
1580 size_t written = cxBufferWrite(
"foobar",
1,
6, &buf);
1581 CX_TEST_ASSERT(written ==
6);
1582 CX_TEST_ASSERT(buf.pos ==
10);
1583 CX_TEST_ASSERT(buf.size ==
10);
1584 CX_TEST_ASSERT(target.pos ==
0);
1585 CX_TEST_ASSERT(target.size ==
0);
1586 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"prepfoobar",
10));
1587
1588 written = cxBufferWrite(
"12345678",
1,
8, &buf);
1589 CX_TEST_ASSERT(written ==
8);
1590 CX_TEST_ASSERT(buf.pos ==
10);
1591 CX_TEST_ASSERT(buf.size ==
10);
1592 CX_TEST_ASSERT(target.pos ==
8);
1593 CX_TEST_ASSERT(target.size ==
8);
1594 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"ar12345678",
10));
1595 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1596
1597 written = cxBufferWrite(
"ABCDEFGH",
1,
8, &buf);
1598 CX_TEST_ASSERT(written ==
6);
1599 CX_TEST_ASSERT(buf.pos ==
16);
1600 CX_TEST_ASSERT(buf.size ==
16);
1601 CX_TEST_ASSERT(target.pos ==
8);
1602 CX_TEST_ASSERT(target.size ==
8);
1603 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"ar12345678ABCDEF",
16));
1604 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1605
1606 written = cxBufferWrite(
"baz",
1,
3, &buf);
1607 CX_TEST_ASSERT(written ==
0);
1608 CX_TEST_ASSERT(buf.pos ==
16);
1609 CX_TEST_ASSERT(buf.size ==
16);
1610 CX_TEST_ASSERT(target.pos ==
8);
1611 CX_TEST_ASSERT(target.size ==
8);
1612 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"ar12345678ABCDEF",
16));
1613 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepfoob",
8));
1614 }
1615 cxBufferDestroy(&buf);
1616 cxBufferDestroy(&target);
1617 }
1618
1619 CX_TEST(test_buffer_pop) {
1620 CxBuffer buf;
1621 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1622 cxBufferPutString(&buf,
"teststring");
1623 CX_TEST_DO {
1624 CX_TEST_ASSERT(buf.pos ==
10);
1625 CX_TEST_ASSERT(buf.size ==
10);
1626 CX_TEST_ASSERT(cxBufferPop(&buf,
1,
3) ==
3);
1627 CX_TEST_ASSERT(buf.pos ==
7);
1628 CX_TEST_ASSERT(buf.size ==
7);
1629 CX_TEST_ASSERT(cxBufferPop(&buf,
2,
2) ==
2);
1630 CX_TEST_ASSERT(buf.pos ==
3);
1631 CX_TEST_ASSERT(buf.size ==
3);
1632 cxBufferPutString(&buf,
"1234");
1633 CX_TEST_ASSERT(buf.pos ==
7);
1634 CX_TEST_ASSERT(buf.size ==
7);
1635 buf.pos =
3;
1636 CX_TEST_ASSERT(cxBufferPop(&buf,
2,
1) ==
1);
1637 CX_TEST_ASSERT(buf.pos ==
3);
1638 CX_TEST_ASSERT(buf.size ==
5);
1639 CX_TEST_ASSERT(cxBufferPop(&buf,
1,
3) ==
3);
1640 CX_TEST_ASSERT(buf.pos ==
2);
1641 CX_TEST_ASSERT(buf.size ==
2);
1642 cxBufferPut(&buf,
'c');
1643 CX_TEST_ASSERT(buf.pos ==
3);
1644 CX_TEST_ASSERT(buf.size ==
3);
1645 CX_TEST_ASSERT(cxBufferPop(&buf,
2,
2) ==
1);
1646 CX_TEST_ASSERT(buf.pos ==
1);
1647 CX_TEST_ASSERT(buf.size ==
1);
1648 CX_TEST_ASSERT(cxBufferPop(&buf,
1,
3) ==
1);
1649 CX_TEST_ASSERT(buf.pos ==
0);
1650 CX_TEST_ASSERT(buf.size ==
0);
1651 }
1652 cxBufferDestroy(&buf);
1653 }
1654
1655 CX_TEST(test_buffer_flush) {
1656 CxBuffer buf, target;
1657 cxBufferInit(&target,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_AUTO_EXTEND);
1658 cxBufferInit(&buf,
NULL,
8, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1659 cxBufferPutString(&buf,
"prepare");
1660 CX_TEST_DO {
1661 CxBufferFlushConfig flush;
1662 flush.threshold =
0;
1663 flush.blksize =
2;
1664 flush.blkmax =
2;
1665 flush.target = ⌖
1666 flush.wfunc = cxBufferWriteFunc;
1667 CX_TEST_ASSERT(
0 == cxBufferEnableFlushing(&buf, flush));
1668 CX_TEST_ASSERT(buf.size ==
7);
1669 buf.pos =
5;
1670 size_t flushed = cxBufferFlush(&buf);
1671 CX_TEST_ASSERT(flushed == flush.blkmax * flush.blksize);
1672 CX_TEST_ASSERT(buf.pos ==
1);
1673 CX_TEST_ASSERT(buf.size ==
3);
1674 CX_TEST_ASSERT(target.pos ==
4);
1675 CX_TEST_ASSERT(target.size ==
4);
1676 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"are",
3));
1677 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prep",
4));
1678 flushed = cxBufferFlush(&buf);
1679 CX_TEST_ASSERT(flushed ==
1);
1680 CX_TEST_ASSERT(buf.pos ==
0);
1681 CX_TEST_ASSERT(buf.size ==
2);
1682 CX_TEST_ASSERT(target.pos ==
5);
1683 CX_TEST_ASSERT(target.size ==
5);
1684 CX_TEST_ASSERT(
0 == memcmp(buf.space,
"re",
2));
1685 CX_TEST_ASSERT(
0 == memcmp(target.space,
"prepa",
5));
1686 }
1687 cxBufferDestroy(&buf);
1688 cxBufferDestroy(&target);
1689 }
1690
1691 CX_TEST(test_buffer_get) {
1692 CxBuffer buf;
1693 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1694 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1695 buf.capacity =
12;
1696 buf.size =
9;
1697 buf.pos =
2;
1698 CX_TEST_DO {
1699 CX_TEST_ASSERT(cxBufferGet(&buf) ==
'm');
1700 CX_TEST_ASSERT(cxBufferGet(&buf) ==
'e');
1701 CX_TEST_ASSERT(cxBufferGet(&buf) ==
' ');
1702 CX_TEST_ASSERT(cxBufferGet(&buf) ==
'd');
1703 CX_TEST_ASSERT(buf.pos ==
6);
1704 }
1705 cxBufferDestroy(&buf);
1706 }
1707
1708 CX_TEST(test_buffer_get_eof) {
1709 CxBuffer buf;
1710 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1711 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1712 buf.capacity =
12;
1713 buf.pos = buf.size =
9;
1714 CX_TEST_DO {
1715 CX_TEST_ASSERT(cxBufferGet(&buf) ==
EOF);
1716 }
1717 cxBufferDestroy(&buf);
1718 }
1719
1720 CX_TEST(test_buffer_read) {
1721 CxBuffer buf;
1722 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1723 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1724 buf.capacity =
12;
1725 buf.size =
9;
1726 buf.pos =
2;
1727 CX_TEST_DO {
1728 char target[
4];
1729 size_t read = cxBufferRead(&target,
1,
4, &buf);
1730 CX_TEST_ASSERT(read ==
4);
1731 CX_TEST_ASSERT(
0 == memcmp(&target,
"me d",
4));
1732 CX_TEST_ASSERT(buf.pos ==
6);
1733
1734
1735 errno =
0;
1736 read = cxBufferRead(&target,
4,
SIZE_MAX/
2, &buf);
1737 CX_TEST_ASSERT(read ==
0);
1738 CX_TEST_ASSERT(errno ==
EOVERFLOW);
1739 }
1740 cxBufferDestroy(&buf);
1741 }
1742
1743 CX_TEST(test_buffer_read_oob) {
1744 CxBuffer buf;
1745 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1746 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1747 buf.capacity =
12;
1748 buf.size =
9;
1749 buf.pos =
6;
1750 CX_TEST_DO {
1751 char target[
4];
1752 size_t read = cxBufferRead(&target,
1,
4, &buf);
1753 CX_TEST_ASSERT(read ==
3);
1754 CX_TEST_ASSERT(
0 == memcmp(&target,
"ata",
3));
1755 CX_TEST_ASSERT(buf.pos ==
9);
1756 }
1757 cxBufferDestroy(&buf);
1758 }
1759
1760 CX_TEST(test_buffer_read_oob_multibyte) {
1761 CxBuffer buf;
1762 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1763 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1764 buf.capacity =
12;
1765 buf.size =
9;
1766 buf.pos =
6;
1767 CX_TEST_DO {
1768 char target[
4];
1769 target[
2] =
'\0';
1770 size_t read = cxBufferRead(&target,
2,
2, &buf);
1771 CX_TEST_ASSERT(read ==
1);
1772 CX_TEST_ASSERT(
0 == memcmp(&target,
"at\0",
3));
1773 CX_TEST_ASSERT(buf.pos ==
8);
1774 }
1775 cxBufferDestroy(&buf);
1776 }
1777
1778 CX_TEST(test_buffer_read_eof) {
1779 CxBuffer buf;
1780 cxBufferInit(&buf,
NULL,
16, cxDefaultAllocator,
CX_BUFFER_DEFAULT);
1781 memcpy(buf.space,
"some data\0\0\0\0\0\0\0",
16);
1782 buf.capacity =
12;
1783 buf.size = buf.pos =
9;
1784 CX_TEST_DO {
1785 char target[
4];
1786 size_t read = cxBufferRead(&target,
1,
1, &buf);
1787 CX_TEST_ASSERT(read ==
0);
1788 CX_TEST_ASSERT(buf.pos ==
9);
1789 }
1790 cxBufferDestroy(&buf);
1791 }
1792
1793 CxTestSuite *cx_test_suite_buffer(
void) {
1794 CxTestSuite *suite = cx_test_suite_new(
"buffer");
1795
1796 cx_test_register(suite, test_buffer_init_wrap_space);
1797 cx_test_register(suite, test_buffer_init_wrap_space_auto_extend);
1798 cx_test_register(suite, test_buffer_init_wrap_space_auto_free);
1799 cx_test_register(suite, test_buffer_init_fresh_space);
1800 cx_test_register(suite, test_buffer_init_on_heap);
1801 cx_test_register(suite, test_buffer_create_defaulted_allocator);
1802 cx_test_register(suite, test_buffer_minimum_capacity_sufficient);
1803 cx_test_register(suite, test_buffer_minimum_capacity_extend);
1804 cx_test_register(suite, test_buffer_shrink);
1805 cx_test_register(suite, test_buffer_shrink_copy_on_write);
1806 cx_test_register(suite, test_buffer_shrink_copy_on_extend);
1807 cx_test_register(suite, test_buffer_reserve);
1808 cx_test_register(suite, test_buffer_clear);
1809 cx_test_register(suite, test_buffer_clear_copy_on_write);
1810 cx_test_register(suite, test_buffer_reset);
1811 cx_test_register(suite, test_buffer_seek_set_zero);
1812 cx_test_register(suite, test_buffer_seek_set_valid);
1813 cx_test_register(suite, test_buffer_seek_set_invalid);
1814 cx_test_register(suite, test_buffer_seek_cur_zero);
1815 cx_test_register(suite, test_buffer_seek_cur_valid_positive);
1816 cx_test_register(suite, test_buffer_seek_cur_valid_negative);
1817 cx_test_register(suite, test_buffer_seek_cur_invalid_positive);
1818 cx_test_register(suite, test_buffer_seek_cur_invalid_negative);
1819 cx_test_register(suite, test_buffer_seek_end_zero);
1820 cx_test_register(suite, test_buffer_seek_end_valid);
1821 cx_test_register(suite, test_buffer_seek_end_invalid);
1822 cx_test_register(suite, test_buffer_seek_whence_invalid);
1823 cx_test_register(suite, test_buffer_eof_reached);
1824 cx_test_register(suite, test_buffer_eof_not_reached);
1825 cx_test_register(suite, test_buffer_shift_left_zero);
1826 cx_test_register(suite, test_buffer_shift_left_zero_offset_interface);
1827 cx_test_register(suite, test_buffer_shift_left_standard);
1828 cx_test_register(suite, test_buffer_shift_left_overshift);
1829 cx_test_register(suite, test_buffer_shift_left_overshift_pos_only);
1830 cx_test_register(suite, test_buffer_shift_left_offset_interface);
1831 cx_test_register(suite, test_buffer_shift_left_copy_on_write);
1832 cx_test_register(suite, test_buffer_shift_right_zero);
1833 cx_test_register(suite, test_buffer_shift_right_zero_offset_interface);
1834 cx_test_register(suite, test_buffer_shift_right_standard);
1835 cx_test_register(suite, test_buffer_shift_right_overshift_discard);
1836 cx_test_register(suite, test_buffer_shift_right_overshift_extend);
1837 cx_test_register(suite, test_buffer_shift_right_offset_interface);
1838 cx_test_register(suite, test_buffer_shift_right_copy_on_write);
1839 cx_test_register(suite, test_buffer_shift_right_overflow);
1840 cx_test_register(suite, test_buffer_write_size_one_fit);
1841 cx_test_register(suite, test_buffer_write_size_one_discard);
1842 cx_test_register(suite, test_buffer_write_size_one_extend);
1843 cx_test_register(suite, test_buffer_write_multibyte_fit);
1844 cx_test_register(suite, test_buffer_write_multibyte_discard);
1845 cx_test_register(suite, test_buffer_write_multibyte_extend);
1846 cx_test_register(suite, test_buffer_write_copy_on_write);
1847 cx_test_register(suite, test_buffer_append);
1848 cx_test_register(suite, test_buffer_append_flush);
1849 cx_test_register(suite, test_buffer_put_fit);
1850 cx_test_register(suite, test_buffer_put_discard);
1851 cx_test_register(suite, test_buffer_put_extend);
1852 cx_test_register(suite, test_buffer_put_copy_on_write);
1853 cx_test_register(suite, test_buffer_put_string_fit);
1854 cx_test_register(suite, test_buffer_put_string_discard);
1855 cx_test_register(suite, test_buffer_put_string_extend);
1856 cx_test_register(suite, test_buffer_put_string_copy_on_extend);
1857 cx_test_register(suite, test_buffer_put_string_copy_on_write);
1858 cx_test_register(suite, test_buffer_terminate);
1859 cx_test_register(suite, test_buffer_write_size_overflow);
1860 cx_test_register(suite, test_buffer_write_capacity_overflow);
1861 cx_test_register(suite, test_buffer_write_only_overwrite);
1862 cx_test_register(suite, test_buffer_write_flush_at_capacity);
1863 cx_test_register(suite, test_buffer_write_flush_at_threshold);
1864 cx_test_register(suite, test_buffer_write_flush_at_threshold_target_full);
1865 cx_test_register(suite, test_buffer_write_flush_rate_limited_and_buffer_too_small);
1866 cx_test_register(suite, test_buffer_write_flush_multibyte);
1867 cx_test_register(suite, test_buffer_write_flush_misaligned);
1868 cx_test_register(suite, test_buffer_write_flush_target_full);
1869 cx_test_register(suite, test_buffer_write_flush_multibyte_target_full);
1870 cx_test_register(suite, test_buffer_write_large_data_flush_target_full);
1871 cx_test_register(suite, test_buffer_pop);
1872 cx_test_register(suite, test_buffer_flush);
1873 cx_test_register(suite, test_buffer_get);
1874 cx_test_register(suite, test_buffer_get_eof);
1875 cx_test_register(suite, test_buffer_read);
1876 cx_test_register(suite, test_buffer_read_oob);
1877 cx_test_register(suite, test_buffer_read_oob_multibyte);
1878 cx_test_register(suite, test_buffer_read_eof);
1879
1880 return suite;
1881 }
1882