UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 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)); // space is still allocated 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); // NO auto extend! 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 // below page size, new capacity should be power of two 204 cxBufferMinimumCapacity(&buf, 200); 205 CX_TEST_ASSERT(buf.capacity == 256); 206 207 // greater than page size, new capacity should be multiple of pagesize 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 // reserve to grow 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 // reserve to shrink 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 // reserve to free 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 // only clear the used part of the buffer 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 // cannot assert more than 10 bytes because 719 // the buffer was required to reallocate the space 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 // remember: whole elements are discarded if they do not fit 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 // remember: whole elements are discarded if they do not fit 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 = &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 // second test - position only shifted by one block 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 // discarded, no write happend! 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 // now actually write somewhere 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 = &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 = &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 // the idea is that the target only accepts two bytes and 1322 // then gives up... accepts another two bytes, gives up, etc. 1323 // and at the same time, the written string is too large for 1324 // the buffer (buffer can take 8, we want to write 13) 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 = &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 // " world!" fits into this buffer, the remaining stuff is flushed out 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 // this test case tests that flushing works correctly even when the 1361 // contents in the buffer are currently not aligned with the item size 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; // test blksize that is not aligned 1371 flush.blkmax = 2; // test with two blocks 1372 flush.target = &target; 1373 flush.wfunc = cxBufferWriteFunc; 1374 CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush)); 1375 // first case: string fits after flush 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 // second case: string does not fit, data is relayed, but only two blocks! 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 // third case: everything can be relayed, block size is large enough 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 // this test case tests that flushing works correctly even when the 1409 // contents in the buffer are currently not aligned with the item size 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 = &target; 1420 flush.wfunc = cxBufferWriteFunc; 1421 CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush)); 1422 // first case: string fits after flush 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 // second case: string does not fit, relaying not possible due to misalignment 1432 // string will be truncated (two items fit into buffer, the third does not) 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 // target does NOT auto-extend and can get completely full 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 = &target; 1458 flush.wfunc = cxBufferWriteFunc; 1459 CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush)); 1460 // step one - flush 4 existing bytes, write 6 new bytes 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 // step two - can only flush 4 more bytes, but rest fits into buffer 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 // step three - cannot flush more, but can write 3 more bytes 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 // final test - cannot write anything more 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 = &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 // pop the misaligned byte from the buffer 1523 cxBufferPop(&buf, 1, 1); 1524 // write three more items, but only one fits into the target and one more into the buffer 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 // simulate that the target is full: 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 = &target; 1550 flush.wfunc = cxBufferWriteFunc; 1551 CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush)); 1552 // write more bytes than the buffer can take, but the target is full 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 // target does NOT auto-extend and can get completely full 1567 cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_DEFAULT); 1568 // source may auto-extend but flushes at a certain threshold 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 = &target; 1577 flush.wfunc = cxBufferWriteFunc; 1578 CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush)); 1579 // step one - adding 6 bytes does not exceed the threshold 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 // step two - adding 8 bytes is two too many, two blocks are flushed 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 // step three - cannot flush more, but can write 6 more bytes 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 // final test - cannot write anything more 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 = &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 // overflow 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