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, alloc, space, 16, CX_BUFFER_DEFAULT); 43 CX_TEST_ASSERT(buf.space == space); 44 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0); 45 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0); 46 CX_TEST_ASSERT(buf.pos == 0); 47 CX_TEST_ASSERT(buf.size == 0); 48 CX_TEST_ASSERT(buf.capacity == 16); 49 CX_TEST_ASSERT(buf.max_capacity == SIZE_MAX); 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, alloc, space, 16, CX_BUFFER_AUTO_EXTEND); 67 CX_TEST_ASSERT(buf.space == space); 68 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND); 69 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == 0); 70 CX_TEST_ASSERT(buf.pos == 0); 71 CX_TEST_ASSERT(buf.size == 0); 72 CX_TEST_ASSERT(buf.capacity == 16); 73 CX_TEST_ASSERT(buf.max_capacity == SIZE_MAX); 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, alloc, space, 16, CX_BUFFER_FREE_CONTENTS); 91 CX_TEST_ASSERT(buf.space == space); 92 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0); 93 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS); 94 CX_TEST_ASSERT(buf.pos == 0); 95 CX_TEST_ASSERT(buf.size == 0); 96 CX_TEST_ASSERT(buf.capacity == 16); 97 CX_TEST_ASSERT(buf.max_capacity == SIZE_MAX); 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, alloc, NULL, 8, CX_BUFFER_DEFAULT); 113 CX_TEST_ASSERT(buf.space != NULL); 114 CX_TEST_ASSERT((buf.flags & CX_BUFFER_AUTO_EXTEND) == 0); 115 CX_TEST_ASSERT((buf.flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS); 116 CX_TEST_ASSERT(buf.pos == 0); 117 CX_TEST_ASSERT(buf.size == 0); 118 CX_TEST_ASSERT(buf.capacity == 8); 119 CX_TEST_ASSERT(buf.max_capacity == SIZE_MAX); 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(alloc, space, 16, CX_BUFFER_FREE_CONTENTS); 136 CX_TEST_ASSERT(buf != NULL); 137 CX_TEST_ASSERT(buf->space == space); 138 CX_TEST_ASSERT((buf->flags & CX_BUFFER_AUTO_EXTEND) == 0); 139 CX_TEST_ASSERT((buf->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS); 140 CX_TEST_ASSERT(buf->pos == 0); 141 CX_TEST_ASSERT(buf->size == 0); 142 CX_TEST_ASSERT(buf->capacity == 16); 143 CX_TEST_ASSERT(buf->max_capacity == SIZE_MAX); 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, NULL, 16, 0); 155 CX_TEST_ASSERT(buf != NULL); 156 CX_TEST_ASSERT(buf->space != NULL); 157 CX_TEST_ASSERT((buf->flags & CX_BUFFER_AUTO_EXTEND) == 0); 158 CX_TEST_ASSERT((buf->flags & CX_BUFFER_FREE_CONTENTS) == CX_BUFFER_FREE_CONTENTS); 159 CX_TEST_ASSERT(buf->pos == 0); 160 CX_TEST_ASSERT(buf->size == 0); 161 CX_TEST_ASSERT(buf->capacity == 16); 162 CX_TEST_ASSERT(buf->max_capacity == SIZE_MAX); 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, alloc, space, 8, 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, alloc, space, 8, 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_maximum_capacity) { 218 CxBuffer buf; 219 cxBufferInit(&buf, NULL, NULL, 256, CX_BUFFER_AUTO_EXTEND); 220 CX_TEST_DO { 221 // set maximum capacity 222 CX_TEST_ASSERT(0 == cxBufferMaximumCapacity(&buf, 512)); 223 CX_TEST_ASSERT(buf.capacity == 256); 224 CX_TEST_ASSERT(buf.max_capacity == 512); 225 // increase maximum capacity again 226 CX_TEST_ASSERT(0 == cxBufferMaximumCapacity(&buf, 1024)); 227 CX_TEST_ASSERT(buf.capacity == 256); 228 CX_TEST_ASSERT(buf.max_capacity == 1024); 229 // try to reduce maximum capacity below current capacity 230 CX_TEST_ASSERT(0 != cxBufferMaximumCapacity(&buf, 128)); 231 CX_TEST_ASSERT(buf.capacity == 256); 232 CX_TEST_ASSERT(buf.max_capacity == 1024); 233 234 // try to reserve more than the maximum 235 CX_TEST_ASSERT(0 == cxBufferMaximumCapacity(&buf, 512)); 236 CX_TEST_ASSERT(0 != cxBufferReserve(&buf, 600)); 237 CX_TEST_ASSERT(buf.capacity == 256); 238 CX_TEST_ASSERT(buf.max_capacity == 512); 239 CX_TEST_ASSERT(0 == cxBufferReserve(&buf, 512)); 240 CX_TEST_ASSERT(buf.capacity == 512); 241 CX_TEST_ASSERT(buf.max_capacity == 512); 242 243 // make sure that cxBufferMinimumCapacity() is capped at the limit 244 CX_TEST_ASSERT(0 == cxBufferMaximumCapacity(&buf, 777)); 245 CX_TEST_ASSERT(0 != cxBufferMinimumCapacity(&buf, 800)); 246 CX_TEST_ASSERT(buf.capacity == 512); 247 CX_TEST_ASSERT(buf.max_capacity == 777); 248 CX_TEST_ASSERT(0 == cxBufferMinimumCapacity(&buf, 700)); 249 CX_TEST_ASSERT(buf.capacity == 777); 250 CX_TEST_ASSERT(buf.max_capacity == 777); 251 } 252 cxBufferDestroy(&buf); 253 } 254 255 CX_TEST(test_buffer_shrink) { 256 CxTestingAllocator talloc; 257 cx_testing_allocator_init(&talloc); 258 CxAllocator *alloc = &talloc.base; 259 CX_TEST_DO { 260 CxBuffer buf; 261 cxBufferInit(&buf, alloc, NULL, 16, CX_BUFFER_FREE_CONTENTS); 262 cxBufferPutString(&buf, "Testing"); 263 CX_TEST_ASSERT(buf.capacity == 16); 264 CX_TEST_ASSERT(buf.size == 7); 265 cxBufferShrink(&buf, 4); 266 CX_TEST_ASSERT(buf.capacity == 11); 267 CX_TEST_ASSERT(buf.size == 7); 268 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 7) == 0); 269 cxBufferDestroy(&buf); 270 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 271 } 272 cx_testing_allocator_destroy(&talloc); 273 } 274 275 CX_TEST(test_buffer_shrink_copy_on_write) { 276 CxTestingAllocator talloc; 277 cx_testing_allocator_init(&talloc); 278 CxAllocator *alloc = &talloc.base; 279 CX_TEST_DO { 280 CxBuffer buf; 281 const char* space = "Testing"; 282 cxBufferInit(&buf, alloc, (void*)space, 16, CX_BUFFER_COPY_ON_WRITE); 283 buf.size = 8; 284 CX_TEST_ASSERT(buf.capacity == 16); 285 cxBufferShrink(&buf, 4); 286 CX_TEST_ASSERT(buf.capacity == 16); 287 CX_TEST_ASSERT(buf.size == 8); 288 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0); 289 CX_TEST_ASSERT(talloc.alloc_total == 0); 290 cxBufferDestroy(&buf); 291 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 292 } 293 cx_testing_allocator_destroy(&talloc); 294 } 295 296 CX_TEST(test_buffer_shrink_copy_on_extend) { 297 CxTestingAllocator talloc; 298 cx_testing_allocator_init(&talloc); 299 CxAllocator *alloc = &talloc.base; 300 CX_TEST_DO { 301 CxBuffer buf; 302 char space[16] = "Testing"; 303 cxBufferInit(&buf, alloc, space, 16, CX_BUFFER_COPY_ON_EXTEND); 304 buf.size = 8; 305 CX_TEST_ASSERT(buf.capacity == 16); 306 cxBufferShrink(&buf, 4); 307 CX_TEST_ASSERT(buf.capacity == 16); 308 CX_TEST_ASSERT(buf.size == 8); 309 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0); 310 CX_TEST_ASSERT(talloc.alloc_total == 0); 311 cxBufferDestroy(&buf); 312 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 313 } 314 cx_testing_allocator_destroy(&talloc); 315 } 316 317 CX_TEST(test_buffer_reserve) { 318 CxTestingAllocator talloc; 319 cx_testing_allocator_init(&talloc); 320 CxAllocator *alloc = &talloc.base; 321 CX_TEST_DO { 322 CxBuffer buf; 323 char space[16] = "Testing"; 324 cxBufferInit(&buf, alloc, space, 16, CX_BUFFER_COPY_ON_EXTEND); 325 buf.size = 8; 326 CX_TEST_ASSERT(buf.capacity == 16); 327 CX_TEST_ASSERT(talloc.alloc_total == 0); 328 // reserve to grow 329 cxBufferReserve(&buf, 32); 330 CX_TEST_ASSERT(buf.capacity == 32); 331 CX_TEST_ASSERT(buf.size == 8); 332 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0); 333 CX_TEST_ASSERT(talloc.alloc_total > 0); 334 CX_TEST_ASSERT((buf.flags & CX_BUFFER_COPY_ON_EXTEND) == 0); 335 // reserve to shrink 336 buf.size = 24; 337 cxBufferReserve(&buf, 16); 338 CX_TEST_ASSERT(buf.capacity == 16); 339 CX_TEST_ASSERT(buf.size == 16); 340 CX_TEST_ASSERT(memcmp(buf.space, "Testing", 8) == 0); 341 // reserve to free 342 cxBufferReserve(&buf, 0); 343 CX_TEST_ASSERT(buf.capacity == 0); 344 CX_TEST_ASSERT(buf.size == 0); 345 CX_TEST_ASSERT(buf.space == NULL); 346 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 347 cxBufferDestroy(&buf); 348 } 349 cx_testing_allocator_destroy(&talloc); 350 } 351 352 CX_TEST(test_buffer_clear) { 353 char space[16]; 354 strcpy(space, "clear test"); 355 CxBuffer buf; 356 cxBufferInit(&buf, cxDefaultAllocator, space, 16, CX_BUFFER_DEFAULT); 357 CX_TEST_DO { 358 CX_TEST_ASSERT(buf.size == 0); 359 // only clear the used part of the buffer 360 cxBufferClear(&buf); 361 CX_TEST_ASSERT(0 == memcmp(space, "clear test", 10)); 362 buf.size = 5; 363 buf.pos = 3; 364 cxBufferClear(&buf); 365 CX_TEST_ASSERT(0 == memcmp(space, "\0\0\0\0\0 test", 10)); 366 CX_TEST_ASSERT(buf.size == 0); 367 CX_TEST_ASSERT(buf.pos == 0); 368 } 369 cxBufferDestroy(&buf); 370 } 371 372 CX_TEST(test_buffer_clear_copy_on_write) { 373 char space[16]; 374 strcpy(space, "clear test"); 375 CxBuffer buf; 376 cxBufferInit(&buf, cxDefaultAllocator, space, 16, CX_BUFFER_COPY_ON_WRITE); 377 CX_TEST_DO { 378 buf.size = 5; 379 buf.pos = 3; 380 cxBufferClear(&buf); 381 CX_TEST_ASSERT(0 == memcmp(space, "clear test", 10)); 382 CX_TEST_ASSERT(buf.size == 0); 383 CX_TEST_ASSERT(buf.pos == 0); 384 } 385 cxBufferDestroy(&buf); 386 } 387 388 CX_TEST(test_buffer_reset) { 389 char space[16]; 390 strcpy(space, "reset test"); 391 CxBuffer buf; 392 cxBufferInit(&buf, cxDefaultAllocator, space, 16, CX_BUFFER_DEFAULT); 393 CX_TEST_DO { 394 buf.size = 5; 395 buf.pos = 3; 396 cxBufferReset(&buf); 397 CX_TEST_ASSERT(0 == memcmp(space, "reset test", 10)); 398 CX_TEST_ASSERT(buf.size == 0); 399 CX_TEST_ASSERT(buf.pos == 0); 400 } 401 cxBufferDestroy(&buf); 402 } 403 404 CX_TEST(test_buffer_seek_set_zero) { 405 CxBuffer buf; 406 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 407 buf.size = 6; 408 buf.pos = 3; 409 CX_TEST_DO { 410 int result = cxBufferSeek(&buf, 0, SEEK_SET); 411 CX_TEST_ASSERT(result == 0); 412 CX_TEST_ASSERT(buf.pos == 0); 413 } 414 cxBufferDestroy(&buf); 415 } 416 417 CX_TEST(test_buffer_seek_set_valid) { 418 CxBuffer buf; 419 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 420 buf.size = 6; 421 buf.pos = 3; 422 CX_TEST_DO { 423 int result = cxBufferSeek(&buf, 5, SEEK_SET); 424 CX_TEST_ASSERT(result == 0); 425 CX_TEST_ASSERT(buf.pos == 5); 426 } 427 cxBufferDestroy(&buf); 428 } 429 430 CX_TEST(test_buffer_seek_set_invalid) { 431 CxBuffer buf; 432 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 433 buf.size = 6; 434 buf.pos = 3; 435 CX_TEST_DO { 436 int result = cxBufferSeek(&buf, 7, SEEK_SET); 437 CX_TEST_ASSERT(result != 0); 438 CX_TEST_ASSERT(buf.pos == 3); 439 } 440 cxBufferDestroy(&buf); 441 } 442 443 CX_TEST(test_buffer_seek_cur_zero) { 444 CxBuffer buf; 445 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 446 buf.size = 6; 447 buf.pos = 3; 448 CX_TEST_DO { 449 int result = cxBufferSeek(&buf, 0, SEEK_CUR); 450 CX_TEST_ASSERT(result == 0); 451 CX_TEST_ASSERT(buf.pos == 3); 452 } 453 cxBufferDestroy(&buf); 454 } 455 456 CX_TEST(test_buffer_seek_cur_valid_positive) { 457 CxBuffer buf; 458 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 459 buf.size = 6; 460 buf.pos = 3; 461 CX_TEST_DO { 462 int result = cxBufferSeek(&buf, 2, SEEK_CUR); 463 CX_TEST_ASSERT(result == 0); 464 CX_TEST_ASSERT(buf.pos == 5); 465 } 466 cxBufferDestroy(&buf); 467 } 468 469 CX_TEST(test_buffer_seek_cur_valid_negative) { 470 CxBuffer buf; 471 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 472 buf.size = 6; 473 buf.pos = 3; 474 CX_TEST_DO { 475 int result = cxBufferSeek(&buf, -3, SEEK_CUR); 476 CX_TEST_ASSERT(result == 0); 477 CX_TEST_ASSERT(buf.pos == 0); 478 } 479 cxBufferDestroy(&buf); 480 } 481 482 CX_TEST(test_buffer_seek_cur_invalid_positive) { 483 CxBuffer buf; 484 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 485 buf.size = 6; 486 buf.pos = 3; 487 CX_TEST_DO { 488 int result = cxBufferSeek(&buf, 4, SEEK_CUR); 489 CX_TEST_ASSERT(result != 0); 490 CX_TEST_ASSERT(buf.pos == 3); 491 } 492 cxBufferDestroy(&buf); 493 } 494 495 CX_TEST(test_buffer_seek_cur_invalid_negative) { 496 CxBuffer buf; 497 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 498 buf.size = 6; 499 buf.pos = 3; 500 CX_TEST_DO { 501 int result = cxBufferSeek(&buf, -4, SEEK_CUR); 502 CX_TEST_ASSERT(result != 0); 503 CX_TEST_ASSERT(buf.pos == 3); 504 } 505 cxBufferDestroy(&buf); 506 } 507 508 CX_TEST(test_buffer_seek_end_zero) { 509 CxBuffer buf; 510 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 511 buf.size = 6; 512 buf.pos = 3; 513 CX_TEST_DO { 514 int result = cxBufferSeek(&buf, 0, SEEK_END); 515 CX_TEST_ASSERT(result == 0); 516 CX_TEST_ASSERT(buf.pos == 6); 517 } 518 cxBufferDestroy(&buf); 519 } 520 521 CX_TEST(test_buffer_seek_end_valid) { 522 CxBuffer buf; 523 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 524 buf.size = 6; 525 buf.pos = 3; 526 CX_TEST_DO { 527 int result = cxBufferSeek(&buf, -6, SEEK_END); 528 CX_TEST_ASSERT(result == 0); 529 CX_TEST_ASSERT(buf.pos == 0); 530 } 531 cxBufferDestroy(&buf); 532 } 533 534 CX_TEST(test_buffer_seek_end_invalid) { 535 CxBuffer buf; 536 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 537 buf.size = 6; 538 buf.pos = 3; 539 CX_TEST_DO { 540 int result = cxBufferSeek(&buf, 1, SEEK_END); 541 CX_TEST_ASSERT(result != 0); 542 CX_TEST_ASSERT(buf.pos == 3); 543 } 544 cxBufferDestroy(&buf); 545 } 546 547 CX_TEST(test_buffer_seek_whence_invalid) { 548 CxBuffer buf; 549 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 550 buf.size = 6; 551 buf.pos = 3; 552 CX_TEST_DO { 553 int result = cxBufferSeek(&buf, 2, 9000); 554 CX_TEST_ASSERT(result != 0); 555 CX_TEST_ASSERT(buf.size == 6); 556 CX_TEST_ASSERT(buf.pos == 3); 557 } 558 cxBufferDestroy(&buf); 559 } 560 561 CX_TEST(test_buffer_eof_reached) { 562 CxBuffer buf; 563 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 564 buf.size = buf.pos = 3; 565 CX_TEST_DO { 566 CX_TEST_ASSERT(cxBufferEof(&buf)); 567 buf.pos = buf.size - 1; 568 CX_TEST_ASSERT(!cxBufferEof(&buf)); 569 cxBufferPut(&buf, 'a'); 570 CX_TEST_ASSERT(cxBufferEof(&buf)); 571 } 572 cxBufferDestroy(&buf); 573 } 574 575 CX_TEST(test_buffer_eof_not_reached) { 576 CxBuffer buf; 577 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 578 buf.size = 6; 579 CX_TEST_DO { 580 buf.pos = buf.size - 1; 581 CX_TEST_ASSERT(!cxBufferEof(&buf)); 582 buf.pos = 0; 583 cxBufferWrite("test", 1, 5, &buf); 584 CX_TEST_ASSERT(!cxBufferEof(&buf)); 585 } 586 cxBufferDestroy(&buf); 587 } 588 589 #define TEST_BUFFER_SHIFT_SETUP(buf) \ 590 CxTestingAllocator talloc; \ 591 cx_testing_allocator_init(&talloc); \ 592 CxAllocator *alloc = &talloc.base; \ 593 CxBuffer buf; \ 594 cxBufferInit(&buf, alloc, NULL, 16, CX_BUFFER_DEFAULT); \ 595 memcpy(buf.space, "test____XXXXXXXX", 16); \ 596 buf.capacity = 8; \ 597 buf.pos = 4; \ 598 buf.size = 4 599 #define TEST_BUFFER_SHIFT_TEARDOWN(buf) \ 600 cxBufferDestroy(&buf); \ 601 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); \ 602 cx_testing_allocator_destroy(&talloc) 603 604 605 CX_TEST(test_buffer_shift_left_zero) { 606 TEST_BUFFER_SHIFT_SETUP(buf); 607 CX_TEST_DO { 608 int ret = cxBufferShiftLeft(&buf, 0); 609 CX_TEST_ASSERT(ret == 0); 610 CX_TEST_ASSERT(buf.pos == 4); 611 CX_TEST_ASSERT(buf.size == 4); 612 CX_TEST_ASSERT(memcmp(buf.space, "test____XXXXXXXX", 16) == 0); 613 TEST_BUFFER_SHIFT_TEARDOWN(buf); 614 } 615 } 616 617 CX_TEST(test_buffer_shift_left_zero_offset_interface) { 618 TEST_BUFFER_SHIFT_SETUP(buf); 619 CX_TEST_DO { 620 int ret = cxBufferShift(&buf, -0); 621 CX_TEST_ASSERT(ret == 0); 622 CX_TEST_ASSERT(buf.pos == 4); 623 CX_TEST_ASSERT(buf.size == 4); 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_standard) { 630 TEST_BUFFER_SHIFT_SETUP(buf); 631 CX_TEST_DO { 632 int ret = cxBufferShiftLeft(&buf, 2); 633 CX_TEST_ASSERT(ret == 0); 634 CX_TEST_ASSERT(buf.pos == 2); 635 CX_TEST_ASSERT(buf.size == 2); 636 CX_TEST_ASSERT(memcmp(buf.space, "stst____XXXXXXXX", 16) == 0); 637 TEST_BUFFER_SHIFT_TEARDOWN(buf); 638 } 639 } 640 641 CX_TEST(test_buffer_shift_left_overshift) { 642 TEST_BUFFER_SHIFT_SETUP(buf); 643 CX_TEST_DO { 644 int ret = cxBufferShiftLeft(&buf, 6); 645 CX_TEST_ASSERT(ret == 0); 646 CX_TEST_ASSERT(buf.pos == 0); 647 CX_TEST_ASSERT(buf.size == 0); 648 CX_TEST_ASSERT(memcmp(buf.space, "test____XXXXXXXX", 16) == 0); 649 TEST_BUFFER_SHIFT_TEARDOWN(buf); 650 } 651 } 652 653 CX_TEST(test_buffer_shift_left_overshift_pos_only) { 654 TEST_BUFFER_SHIFT_SETUP(buf); 655 buf.pos = 2; 656 CX_TEST_DO { 657 int ret = cxBufferShiftLeft(&buf, 3); 658 CX_TEST_ASSERT(ret == 0); 659 CX_TEST_ASSERT(buf.pos == 0); 660 CX_TEST_ASSERT(buf.size == 1); 661 CX_TEST_ASSERT(memcmp(buf.space, "test____XXXXXXXX", 16) == 0); 662 TEST_BUFFER_SHIFT_TEARDOWN(buf); 663 } 664 } 665 666 CX_TEST(test_buffer_shift_left_offset_interface) { 667 TEST_BUFFER_SHIFT_SETUP(buf); 668 buf.pos = 3; 669 CX_TEST_DO { 670 int ret = cxBufferShift(&buf, -2); 671 CX_TEST_ASSERT(ret == 0); 672 CX_TEST_ASSERT(buf.pos == 1); 673 CX_TEST_ASSERT(buf.size == 2); 674 CX_TEST_ASSERT(memcmp(buf.space, "stst____XXXXXXXX", 16) == 0); 675 TEST_BUFFER_SHIFT_TEARDOWN(buf); 676 } 677 } 678 679 CX_TEST(test_buffer_shift_left_copy_on_write) { 680 TEST_BUFFER_SHIFT_SETUP(buf); 681 buf.flags |= CX_BUFFER_COPY_ON_WRITE; 682 char *original = buf.space; 683 CX_TEST_DO { 684 int ret = cxBufferShiftLeft(&buf, 2); 685 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 686 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS)); 687 CX_TEST_ASSERT(ret == 0); 688 CX_TEST_ASSERT(buf.pos == 2); 689 CX_TEST_ASSERT(buf.size == 2); 690 CX_TEST_ASSERT(memcmp(original, "test____XXXXXXXX", 16) == 0); 691 CX_TEST_ASSERT(memcmp(buf.space, "st", 2) == 0); 692 cxFree(buf.allocator, original); 693 TEST_BUFFER_SHIFT_TEARDOWN(buf); 694 } 695 } 696 697 CX_TEST(test_buffer_shift_right_zero) { 698 TEST_BUFFER_SHIFT_SETUP(buf); 699 CX_TEST_DO { 700 int ret = cxBufferShiftRight(&buf, 0); 701 CX_TEST_ASSERT(ret == 0); 702 CX_TEST_ASSERT(buf.pos == 4); 703 CX_TEST_ASSERT(buf.size == 4); 704 CX_TEST_ASSERT(memcmp(buf.space, "test____XXXXXXXX", 16) == 0); 705 TEST_BUFFER_SHIFT_TEARDOWN(buf); 706 } 707 } 708 709 CX_TEST(test_buffer_shift_right_zero_offset_interface) { 710 TEST_BUFFER_SHIFT_SETUP(buf); 711 CX_TEST_DO { 712 int ret = cxBufferShift(&buf, +0); 713 CX_TEST_ASSERT(ret == 0); 714 CX_TEST_ASSERT(buf.pos == 4); 715 CX_TEST_ASSERT(buf.size == 4); 716 CX_TEST_ASSERT(memcmp(buf.space, "test____XXXXXXXX", 16) == 0); 717 TEST_BUFFER_SHIFT_TEARDOWN(buf); 718 } 719 } 720 721 CX_TEST(test_buffer_shift_right_standard) { 722 TEST_BUFFER_SHIFT_SETUP(buf); 723 CX_TEST_DO { 724 int ret = cxBufferShiftRight(&buf, 3); 725 CX_TEST_ASSERT(ret == 0); 726 CX_TEST_ASSERT(buf.pos == 7); 727 CX_TEST_ASSERT(buf.size == 7); 728 CX_TEST_ASSERT(memcmp(buf.space, "testest_XXXXXXXX", 16) == 0); 729 TEST_BUFFER_SHIFT_TEARDOWN(buf); 730 } 731 } 732 733 CX_TEST(test_buffer_shift_right_overshift_discard) { 734 TEST_BUFFER_SHIFT_SETUP(buf); 735 CX_TEST_DO { 736 int ret = cxBufferShiftRight(&buf, 6); 737 CX_TEST_ASSERT(ret == 0); 738 CX_TEST_ASSERT(buf.pos == 8); 739 CX_TEST_ASSERT(buf.size == 8); 740 CX_TEST_ASSERT(buf.capacity == 8); 741 CX_TEST_ASSERT(memcmp(buf.space, "test__teXXXXXXXX", 16) == 0); 742 TEST_BUFFER_SHIFT_TEARDOWN(buf); 743 } 744 } 745 746 CX_TEST(test_buffer_shift_right_overshift_extend) { 747 TEST_BUFFER_SHIFT_SETUP(buf); 748 buf.flags |= CX_BUFFER_AUTO_EXTEND; 749 CX_TEST_DO { 750 int ret = cxBufferShiftRight(&buf, 6); 751 CX_TEST_ASSERT(ret == 0); 752 CX_TEST_ASSERT(buf.pos == 10); 753 CX_TEST_ASSERT(buf.size == 10); 754 CX_TEST_ASSERT(buf.capacity >= 10); 755 // cannot assert more than 10 bytes because 756 // the buffer was required to reallocate the space 757 CX_TEST_ASSERT(memcmp(buf.space, "test__test", 10) == 0); 758 TEST_BUFFER_SHIFT_TEARDOWN(buf); 759 } 760 } 761 762 CX_TEST(test_buffer_shift_right_offset_interface) { 763 TEST_BUFFER_SHIFT_SETUP(buf); 764 buf.pos = 3; 765 CX_TEST_DO { 766 int ret = cxBufferShift(&buf, 2); 767 CX_TEST_ASSERT(ret == 0); 768 CX_TEST_ASSERT(buf.pos == 5); 769 CX_TEST_ASSERT(buf.size == 6); 770 CX_TEST_ASSERT(memcmp(buf.space, "tetest__XXXXXXXX", 16) == 0); 771 TEST_BUFFER_SHIFT_TEARDOWN(buf); 772 } 773 } 774 775 CX_TEST(test_buffer_shift_right_copy_on_write) { 776 TEST_BUFFER_SHIFT_SETUP(buf); 777 buf.flags |= CX_BUFFER_COPY_ON_WRITE; 778 char *original = buf.space; 779 CX_TEST_DO { 780 int ret = cxBufferShiftRight(&buf, 3); 781 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 782 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS)); 783 CX_TEST_ASSERT(ret == 0); 784 CX_TEST_ASSERT(buf.pos == 7); 785 CX_TEST_ASSERT(buf.size == 7); 786 CX_TEST_ASSERT(memcmp(original, "test____XXXXXXXX", 16) == 0); 787 CX_TEST_ASSERT(memcmp(buf.space, "testest", 7) == 0); 788 cxFree(buf.allocator, original); 789 TEST_BUFFER_SHIFT_TEARDOWN(buf); 790 } 791 } 792 793 CX_TEST(test_buffer_shift_right_overflow) { 794 TEST_BUFFER_SHIFT_SETUP(buf); 795 CX_TEST_DO { 796 errno = 0; 797 int ret = cxBufferShiftRight(&buf, SIZE_MAX - 2); 798 CX_TEST_ASSERT(ret != 0); 799 CX_TEST_ASSERT(errno == EOVERFLOW); 800 TEST_BUFFER_SHIFT_TEARDOWN(buf); 801 } 802 } 803 804 CX_TEST(test_buffer_write_size_one_fit) { 805 CxBuffer buf; 806 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 807 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 808 buf.capacity = 8; 809 buf.size = buf.pos = 4; 810 const char *data = "test"; 811 CX_TEST_DO { 812 size_t written = cxBufferWrite(data, 1, 4, &buf); 813 CX_TEST_ASSERT(written == 4); 814 CX_TEST_ASSERT(buf.size == 8); 815 CX_TEST_ASSERT(buf.pos == 8); 816 CX_TEST_ASSERT(buf.capacity == 8); 817 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 818 } 819 820 cxBufferDestroy(&buf); 821 } 822 823 CX_TEST(test_buffer_write_size_one_discard) { 824 CxBuffer buf; 825 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 826 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 827 buf.capacity = 8; 828 buf.size = buf.pos = 4; 829 const char *data = "testing"; 830 CX_TEST_DO { 831 size_t written = cxBufferWrite(data, 1, 7, &buf); 832 CX_TEST_ASSERT(written == 4); 833 CX_TEST_ASSERT(buf.size == 8); 834 CX_TEST_ASSERT(buf.pos == 8); 835 CX_TEST_ASSERT(buf.capacity == 8); 836 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); 837 } 838 cxBufferDestroy(&buf); 839 } 840 841 CX_TEST(test_buffer_write_size_one_extend) { 842 CxBuffer buf; 843 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 844 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 845 buf.capacity = 8; 846 buf.size = buf.pos = 4; 847 buf.flags |= CX_BUFFER_AUTO_EXTEND; 848 const char *data = "testing"; 849 CX_TEST_DO { 850 size_t written = cxBufferWrite(data, 1, 7, &buf); 851 CX_TEST_ASSERT(written == 7); 852 CX_TEST_ASSERT(buf.size == 11); 853 CX_TEST_ASSERT(buf.pos == 11); 854 CX_TEST_ASSERT(buf.capacity >= 11); 855 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 856 } 857 cxBufferDestroy(&buf); 858 } 859 860 CX_TEST(test_buffer_write_copy_on_write) { 861 CxBuffer buf; 862 char original[16] = "preparedXXXXXXX"; 863 cxBufferInit(&buf, cxDefaultAllocator, original, 16, CX_BUFFER_COPY_ON_WRITE); 864 buf.capacity = 8; 865 buf.size = 8; 866 buf.pos = 0; 867 const char *data = "testing"; 868 CX_TEST_DO { 869 size_t written = cxBufferWrite(data, 1, 7, &buf); 870 CX_TEST_ASSERT(written == 7); 871 CX_TEST_ASSERT(buf.size == 8); 872 CX_TEST_ASSERT(buf.pos == 7); 873 CX_TEST_ASSERT(buf.capacity == 8); 874 CX_TEST_ASSERT(0 == memcmp(buf.space, "testingd", 8)); 875 CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16)); 876 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 877 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS)); 878 } 879 cxBufferDestroy(&buf); 880 } 881 882 CX_TEST(test_buffer_write_multibyte_fit) { 883 CxBuffer buf; 884 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 885 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 886 buf.capacity = 8; 887 buf.size = buf.pos = 4; 888 const char *data = "test"; 889 CX_TEST_DO { 890 size_t written = cxBufferWrite(data, 2, 2, &buf); 891 CX_TEST_ASSERT(written == 2); 892 CX_TEST_ASSERT(buf.size == 8); 893 CX_TEST_ASSERT(buf.pos == 8); 894 CX_TEST_ASSERT(buf.capacity == 8); 895 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 896 } 897 cxBufferDestroy(&buf); 898 } 899 900 CX_TEST(test_buffer_write_multibyte_discard) { 901 CxBuffer buf; 902 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 903 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 904 buf.capacity = 8; 905 buf.size = 4; 906 buf.pos = 3; 907 const char *data = "testing"; 908 CX_TEST_DO { 909 size_t written = cxBufferWrite(data, 2, 4, &buf); 910 // remember: whole elements are discarded if they do not fit 911 CX_TEST_ASSERT(written == 2); 912 CX_TEST_ASSERT(buf.size == 7); 913 CX_TEST_ASSERT(buf.pos == 7); 914 CX_TEST_ASSERT(buf.capacity == 8); 915 CX_TEST_ASSERT(0 == memcmp(buf.space, "pretest\0", 8)); 916 } 917 cxBufferDestroy(&buf); 918 } 919 920 CX_TEST(test_buffer_write_multibyte_extend) { 921 CxBuffer buf; 922 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 923 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 924 buf.capacity = 8; 925 buf.size = 4; 926 buf.pos = 3; 927 buf.flags |= CX_BUFFER_AUTO_EXTEND; 928 const char *data = "tester"; 929 CX_TEST_DO { 930 size_t written = cxBufferWrite(data, 2, 3, &buf); 931 // remember: whole elements are discarded if they do not fit 932 CX_TEST_ASSERT(written == 3); 933 CX_TEST_ASSERT(buf.size == 9); 934 CX_TEST_ASSERT(buf.pos == 9); 935 CX_TEST_ASSERT(buf.capacity >= 9); 936 CX_TEST_ASSERT(0 == memcmp(buf.space, "pretester", 9)); 937 } 938 cxBufferDestroy(&buf); 939 } 940 941 CX_TEST(test_buffer_append) { 942 CxBuffer buf; 943 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_AUTO_EXTEND); 944 memcpy(buf.space, "prepXXXX\0\0\0\0\0\0\0\0", 16); 945 buf.capacity = 8; 946 buf.size = 6; 947 buf.pos = 4; 948 CX_TEST_DO { 949 size_t written = cxBufferAppend("testing", 1, 7, &buf); 950 CX_TEST_ASSERT(written == 7); 951 CX_TEST_ASSERT(buf.size == 13); 952 CX_TEST_ASSERT(buf.pos == 4); 953 CX_TEST_ASSERT(buf.capacity >= 13); 954 CX_TEST_ASSERT(0 == memcmp(buf.space, "prepXXtesting", 13)); 955 } 956 cxBufferDestroy(&buf); 957 } 958 959 CX_TEST(test_buffer_append_string) { 960 CxBuffer buf; 961 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_AUTO_EXTEND); 962 memcpy(buf.space, "prepXXXX\0\0\0\0\0\0\0\0", 16); 963 buf.capacity = 8; 964 buf.size = 6; 965 buf.pos = 4; 966 CX_TEST_DO { 967 size_t written = cxBufferAppendString(&buf, "testing"); 968 CX_TEST_ASSERT(written == 7); 969 CX_TEST_ASSERT(buf.size == 13); 970 CX_TEST_ASSERT(buf.pos == 4); 971 CX_TEST_ASSERT(buf.capacity >= 13); 972 CX_TEST_ASSERT(0 == memcmp(buf.space, "prepXXtesting", 13)); 973 } 974 cxBufferDestroy(&buf); 975 } 976 977 CX_TEST(test_buffer_put_fit) { 978 CxBuffer buf; 979 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 980 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 981 buf.capacity = 8; 982 buf.size = buf.pos = 4; 983 CX_TEST_DO { 984 int c = cxBufferPut(&buf, 0x200 | 'a'); 985 CX_TEST_ASSERT(c == 'a'); 986 CX_TEST_ASSERT(buf.size == 5); 987 CX_TEST_ASSERT(buf.pos == 5); 988 CX_TEST_ASSERT(buf.capacity == 8); 989 CX_TEST_ASSERT(0 == memcmp(buf.space, "prepa\0", 6)); 990 } 991 cxBufferDestroy(&buf); 992 } 993 994 CX_TEST(test_buffer_put_discard) { 995 CxBuffer buf; 996 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 997 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 998 buf.capacity = 8; 999 buf.size = 4; 1000 buf.pos = 8; 1001 CX_TEST_DO { 1002 int c = cxBufferPut(&buf, 0x200 | 'a'); 1003 CX_TEST_ASSERT(c == EOF); 1004 CX_TEST_ASSERT(buf.size == 4); 1005 CX_TEST_ASSERT(buf.pos == 8); 1006 CX_TEST_ASSERT(buf.capacity == 8); 1007 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0\0", 9)); 1008 } 1009 cxBufferDestroy(&buf); 1010 } 1011 1012 CX_TEST(test_buffer_put_extend) { 1013 CxBuffer buf; 1014 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1015 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1016 buf.capacity = 8; 1017 buf.size = 4; 1018 buf.pos = 8; 1019 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1020 CX_TEST_DO { 1021 int c = cxBufferPut(&buf, 0x200 | 'a'); 1022 CX_TEST_ASSERT(c == 'a'); 1023 CX_TEST_ASSERT(buf.size == 9); 1024 CX_TEST_ASSERT(buf.pos == 9); 1025 CX_TEST_ASSERT(buf.capacity >= 9); 1026 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0\0\0\0a", 9)); 1027 } 1028 cxBufferDestroy(&buf); 1029 } 1030 1031 CX_TEST(test_buffer_put_copy_on_write) { 1032 CxBuffer buf; 1033 char original[16] = "preparedXXXXXXX"; 1034 cxBufferInit(&buf, cxDefaultAllocator, original, 16, CX_BUFFER_COPY_ON_WRITE); 1035 buf.capacity = 8; 1036 buf.size = 8; 1037 buf.pos = 8; 1038 CX_TEST_DO { 1039 int c = cxBufferPut(&buf, 0x200 | 'a'); 1040 CX_TEST_ASSERT(c == EOF); 1041 CX_TEST_ASSERT(buf.size == 8); 1042 CX_TEST_ASSERT(buf.pos == 8); 1043 CX_TEST_ASSERT(buf.capacity == 8); 1044 CX_TEST_ASSERT(0 == memcmp(buf.space, "prepared", 8)); 1045 // discarded, no write happend! 1046 CX_TEST_ASSERT(original == buf.space); 1047 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 1048 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_FREE_CONTENTS)); 1049 // now actually write somewhere 1050 buf.pos = 2; 1051 c = cxBufferPut(&buf, 0x200 | 'a'); 1052 CX_TEST_ASSERT(c == 'a'); 1053 CX_TEST_ASSERT(buf.size == 8); 1054 CX_TEST_ASSERT(buf.pos == 3); 1055 CX_TEST_ASSERT(buf.capacity == 8); 1056 CX_TEST_ASSERT(0 == memcmp(buf.space, "prapared", 8)); 1057 CX_TEST_ASSERT(original != buf.space); 1058 CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16)); 1059 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 1060 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS)); 1061 } 1062 cxBufferDestroy(&buf); 1063 } 1064 1065 CX_TEST(test_buffer_put_string_fit) { 1066 CxBuffer buf; 1067 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1068 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1069 buf.capacity = 8; 1070 buf.size = buf.pos = 4; 1071 const char *data = "test"; 1072 CX_TEST_DO { 1073 size_t written = cxBufferPutString(&buf, data); 1074 CX_TEST_ASSERT(written == 4); 1075 CX_TEST_ASSERT(buf.size == 8); 1076 CX_TEST_ASSERT(buf.pos == 8); 1077 CX_TEST_ASSERT(buf.capacity == 8); 1078 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 1079 } 1080 cxBufferDestroy(&buf); 1081 } 1082 1083 CX_TEST(test_buffer_put_string_discard) { 1084 CxBuffer buf; 1085 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1086 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1087 buf.capacity = 8; 1088 buf.size = buf.pos = 4; 1089 const char *data = "testing"; 1090 CX_TEST_DO { 1091 size_t written = cxBufferPutString(&buf, data); 1092 CX_TEST_ASSERT(written == 4); 1093 CX_TEST_ASSERT(buf.size == 8); 1094 CX_TEST_ASSERT(buf.pos == 8); 1095 CX_TEST_ASSERT(buf.capacity == 8); 1096 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); 1097 } 1098 cxBufferDestroy(&buf); 1099 } 1100 1101 CX_TEST(test_buffer_put_string_extend) { 1102 CxBuffer buf; 1103 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1104 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1105 buf.capacity = 8; 1106 buf.size = buf.pos = 4; 1107 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1108 const char *data = "testing"; 1109 CX_TEST_DO { 1110 size_t written = cxBufferPutString(&buf, data); 1111 CX_TEST_ASSERT(written == 7); 1112 CX_TEST_ASSERT(buf.size == 11); 1113 CX_TEST_ASSERT(buf.pos == 11); 1114 CX_TEST_ASSERT(buf.capacity >= 11); 1115 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 1116 } 1117 cxBufferDestroy(&buf); 1118 } 1119 1120 CX_TEST(test_buffer_put_string_copy_on_extend) { 1121 CxTestingAllocator talloc; 1122 cx_testing_allocator_init(&talloc); 1123 const CxAllocator *alloc = &talloc.base; 1124 CxBuffer buf; 1125 char original[16] = "preparedXXXXXXX"; 1126 CX_TEST_DO { 1127 cxBufferInit(&buf, alloc, original, 16, CX_BUFFER_COPY_ON_EXTEND); 1128 buf.capacity = 8; 1129 buf.size = buf.pos = 4; 1130 size_t written = cxBufferPutString(&buf, "test"); 1131 CX_TEST_ASSERT(written == 4); 1132 CX_TEST_ASSERT(buf.size == 8); 1133 CX_TEST_ASSERT(buf.pos == 8); 1134 CX_TEST_ASSERT(buf.capacity == 8); 1135 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest", 8)); 1136 CX_TEST_ASSERT(original == buf.space); 1137 written = cxBufferPutString(&buf, "ing"); 1138 CX_TEST_ASSERT(written == 3); 1139 CX_TEST_ASSERT(buf.size == 11); 1140 CX_TEST_ASSERT(buf.pos == 11); 1141 CX_TEST_ASSERT(buf.capacity >= 11); 1142 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 1143 CX_TEST_ASSERT(original != buf.space); 1144 CX_TEST_ASSERT(0 == memcmp(original, "preptestXXXXXXX\0", 16)); 1145 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1146 cxBufferDestroy(&buf); 1147 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1148 cx_testing_allocator_destroy(&talloc); 1149 } 1150 } 1151 1152 CX_TEST(test_buffer_put_string_copy_on_write) { 1153 CxBuffer buf; 1154 char original[16] = "preparedXXXXXXX"; 1155 cxBufferInit(&buf, cxDefaultAllocator, original, 16, CX_BUFFER_COPY_ON_WRITE); 1156 buf.capacity = 8; 1157 buf.size = 8; 1158 buf.pos = 4; 1159 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1160 const char *data = "testing"; 1161 CX_TEST_DO { 1162 size_t written = cxBufferPutString(&buf, data); 1163 CX_TEST_ASSERT(written == 7); 1164 CX_TEST_ASSERT(buf.size == 11); 1165 CX_TEST_ASSERT(buf.pos == 11); 1166 CX_TEST_ASSERT(buf.capacity >= 11); 1167 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11)); 1168 CX_TEST_ASSERT(original != buf.space); 1169 CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16)); 1170 CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE)); 1171 CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS)); 1172 } 1173 cxBufferDestroy(&buf); 1174 } 1175 1176 CX_TEST(test_buffer_terminate) { 1177 CxBuffer buf; 1178 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1179 memcpy(buf.space, "prepAAAAAA\0\0\0\0\0\0", 16); 1180 buf.capacity = 8; 1181 buf.size = buf.pos = 4; 1182 const char *data = "test"; 1183 CX_TEST_DO { 1184 size_t written = cxBufferPutString(&buf, data); 1185 CX_TEST_ASSERT(0 != cxBufferTerminate(&buf)); 1186 CX_TEST_ASSERT(written == 4); 1187 CX_TEST_ASSERT(buf.size == 8); 1188 CX_TEST_ASSERT(buf.pos == 8); 1189 CX_TEST_ASSERT(buf.capacity == 8); 1190 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptestAA", 10)); 1191 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1192 CX_TEST_ASSERT(0 == cxBufferTerminate(&buf)); 1193 CX_TEST_ASSERT(buf.size == 8); 1194 CX_TEST_ASSERT(buf.pos == 8); 1195 CX_TEST_ASSERT(buf.capacity == 9); 1196 CX_TEST_ASSERT(0 == memcmp(buf.space, "preptest\0", 9)); 1197 } 1198 cxBufferDestroy(&buf); 1199 } 1200 1201 CX_TEST(test_buffer_terminate_copy_on_write) { 1202 CxTestingAllocator talloc; 1203 cx_testing_allocator_init(&talloc); 1204 CxAllocator *alloc = &talloc.base; 1205 CxBuffer buf; 1206 cxBufferInit(&buf, alloc, "prepAAAAAA\0\0\0\0\0\0", 16, 1207 CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_DO_NOT_FREE); 1208 buf.capacity = 8; 1209 buf.size = buf.pos = 4; 1210 CX_TEST_DO { 1211 CX_TEST_ASSERT(0 == cxBufferTerminate(&buf)); 1212 CX_TEST_ASSERT(buf.size == 4); 1213 CX_TEST_ASSERT(buf.pos == 4); 1214 CX_TEST_ASSERT(buf.capacity == 5); 1215 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); 1216 // check if the memory was copied 1217 CX_TEST_ASSERT(cx_testing_allocator_used(&talloc)); 1218 CX_TEST_ASSERT(!cx_testing_allocator_verify(&talloc)); 1219 cxFree(alloc, buf.space); 1220 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 1221 } 1222 cxBufferDestroy(&buf); 1223 cx_testing_allocator_destroy(&talloc); 1224 } 1225 1226 CX_TEST(test_buffer_write_size_overflow) { 1227 CxBuffer buf; 1228 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1229 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1230 buf.capacity = 8; 1231 buf.size = buf.pos = 4; 1232 const char *data = "testing"; 1233 CX_TEST_DO { 1234 size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf); 1235 CX_TEST_ASSERT(written == 0); 1236 CX_TEST_ASSERT(buf.capacity == 8); 1237 CX_TEST_ASSERT(buf.pos == 4); 1238 CX_TEST_ASSERT(buf.size == 4); 1239 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); 1240 } 1241 cxBufferDestroy(&buf); 1242 } 1243 1244 CX_TEST(test_buffer_write_capacity_overflow) { 1245 CxBuffer buf; 1246 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1247 memcpy(buf.space, "prep\0\0\0\0\0\0\0\0\0\0\0\0", 16); 1248 buf.capacity = 8; 1249 buf.size = buf.pos = 4; 1250 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1251 const char *data = "testing"; 1252 CX_TEST_DO { 1253 size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf); 1254 CX_TEST_ASSERT(written == 0); 1255 CX_TEST_ASSERT(buf.capacity == 8); 1256 CX_TEST_ASSERT(buf.pos == 4); 1257 CX_TEST_ASSERT(buf.size == 4); 1258 CX_TEST_ASSERT(0 == memcmp(buf.space, "prep\0", 5)); 1259 } 1260 cxBufferDestroy(&buf); 1261 } 1262 1263 CX_TEST(test_buffer_write_maximum_capacity_exceeded) { 1264 CxBuffer buf; 1265 cxBufferInit(&buf, cxDefaultAllocator, NULL, 8, CX_BUFFER_AUTO_EXTEND); 1266 CX_TEST_DO { 1267 cxBufferMaximumCapacity(&buf, 30); 1268 size_t written = cxBufferPutString(&buf, "Hello, World!\nHello, Tester!"); 1269 CX_TEST_ASSERT(written == 28); 1270 CX_TEST_ASSERT(buf.capacity == 30); // would be 32 without limit! 1271 CX_TEST_ASSERT(buf.pos == 28); 1272 CX_TEST_ASSERT(buf.size == 28); 1273 cxBufferMaximumCapacity(&buf, 34); 1274 written = cxBufferPutString(&buf, "blubberbla"); 1275 CX_TEST_ASSERT(written == 6); 1276 CX_TEST_ASSERT(buf.capacity == 34); 1277 CX_TEST_ASSERT(buf.pos == 34); 1278 CX_TEST_ASSERT(buf.size == 34); 1279 CX_TEST_ASSERT(0 == memcmp(buf.space, "Hello, World!\nHello, Tester!blubbe", 34)); 1280 1281 // test multi-byte as well 1282 cxBufferMaximumCapacity(&buf, 44); 1283 written = cxBufferWrite("1234abcdABCD", 4, 3, &buf); 1284 CX_TEST_ASSERT(written == 2); 1285 CX_TEST_ASSERT(buf.capacity == 44); 1286 CX_TEST_ASSERT(buf.pos == 42); 1287 CX_TEST_ASSERT(buf.size == 42); 1288 CX_TEST_ASSERT(0 == memcmp(buf.space, "Hello, World!\nHello, Tester!blubbe1234abcd", 42)); 1289 } 1290 cxBufferDestroy(&buf); 1291 } 1292 1293 CX_TEST(test_buffer_write_only_overwrite) { 1294 CxBuffer buf; 1295 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1296 memcpy(buf.space, "preptest\0\0\0\0\0\0\0\0", 16); 1297 buf.capacity = 8; 1298 buf.pos = 3; 1299 buf.size = 8; 1300 buf.flags |= CX_BUFFER_AUTO_EXTEND; 1301 CX_TEST_DO { 1302 size_t written = cxBufferWrite("XXX", 2, 2, &buf); 1303 CX_TEST_ASSERT(written == 2); 1304 CX_TEST_ASSERT(buf.capacity == 8); 1305 CX_TEST_ASSERT(buf.size == 8); 1306 CX_TEST_ASSERT(buf.pos == 7); 1307 CX_TEST_ASSERT(0 == memcmp(buf.space, "preXXX\0t", 8)); 1308 } 1309 cxBufferDestroy(&buf); 1310 } 1311 1312 CX_TEST(test_buffer_pop) { 1313 CxBuffer buf; 1314 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1315 cxBufferPutString(&buf, "teststring"); 1316 CX_TEST_DO { 1317 CX_TEST_ASSERT(buf.pos == 10); 1318 CX_TEST_ASSERT(buf.size == 10); 1319 CX_TEST_ASSERT(cxBufferPop(&buf, 1, 3) == 3); 1320 CX_TEST_ASSERT(buf.pos == 7); 1321 CX_TEST_ASSERT(buf.size == 7); 1322 CX_TEST_ASSERT(cxBufferPop(&buf, 2, 2) == 2); 1323 CX_TEST_ASSERT(buf.pos == 3); 1324 CX_TEST_ASSERT(buf.size == 3); 1325 cxBufferPutString(&buf, "1234"); 1326 CX_TEST_ASSERT(buf.pos == 7); 1327 CX_TEST_ASSERT(buf.size == 7); 1328 buf.pos = 3; 1329 CX_TEST_ASSERT(cxBufferPop(&buf, 2, 1) == 1); 1330 CX_TEST_ASSERT(buf.pos == 3); 1331 CX_TEST_ASSERT(buf.size == 5); 1332 CX_TEST_ASSERT(cxBufferPop(&buf, 1, 3) == 3); 1333 CX_TEST_ASSERT(buf.pos == 2); 1334 CX_TEST_ASSERT(buf.size == 2); 1335 cxBufferPut(&buf, 'c'); 1336 CX_TEST_ASSERT(buf.pos == 3); 1337 CX_TEST_ASSERT(buf.size == 3); 1338 CX_TEST_ASSERT(cxBufferPop(&buf, 2, 2) == 1); 1339 CX_TEST_ASSERT(buf.pos == 1); 1340 CX_TEST_ASSERT(buf.size == 1); 1341 CX_TEST_ASSERT(cxBufferPop(&buf, 1, 3) == 1); 1342 CX_TEST_ASSERT(buf.pos == 0); 1343 CX_TEST_ASSERT(buf.size == 0); 1344 } 1345 cxBufferDestroy(&buf); 1346 } 1347 1348 CX_TEST(test_buffer_get) { 1349 CxBuffer buf; 1350 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1351 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1352 buf.capacity = 12; 1353 buf.size = 9; 1354 buf.pos = 2; 1355 CX_TEST_DO { 1356 CX_TEST_ASSERT(cxBufferGet(&buf) == 'm'); 1357 CX_TEST_ASSERT(cxBufferGet(&buf) == 'e'); 1358 CX_TEST_ASSERT(cxBufferGet(&buf) == ' '); 1359 CX_TEST_ASSERT(cxBufferGet(&buf) == 'd'); 1360 CX_TEST_ASSERT(buf.pos == 6); 1361 } 1362 cxBufferDestroy(&buf); 1363 } 1364 1365 CX_TEST(test_buffer_get_eof) { 1366 CxBuffer buf; 1367 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1368 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1369 buf.capacity = 12; 1370 buf.pos = buf.size = 9; 1371 CX_TEST_DO { 1372 CX_TEST_ASSERT(cxBufferGet(&buf) == EOF); 1373 } 1374 cxBufferDestroy(&buf); 1375 } 1376 1377 CX_TEST(test_buffer_read) { 1378 CxBuffer buf; 1379 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1380 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1381 buf.capacity = 12; 1382 buf.size = 9; 1383 buf.pos = 2; 1384 CX_TEST_DO { 1385 char target[4]; 1386 size_t read = cxBufferRead(&target, 1, 4, &buf); 1387 CX_TEST_ASSERT(read == 4); 1388 CX_TEST_ASSERT(0 == memcmp(&target, "me d", 4)); 1389 CX_TEST_ASSERT(buf.pos == 6); 1390 1391 // overflow 1392 errno = 0; 1393 read = cxBufferRead(&target, 4, SIZE_MAX/2, &buf); 1394 CX_TEST_ASSERT(read == 0); 1395 CX_TEST_ASSERT(errno == EOVERFLOW); 1396 } 1397 cxBufferDestroy(&buf); 1398 } 1399 1400 CX_TEST(test_buffer_read_oob) { 1401 CxBuffer buf; 1402 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1403 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1404 buf.capacity = 12; 1405 buf.size = 9; 1406 buf.pos = 6; 1407 CX_TEST_DO { 1408 char target[4]; 1409 size_t read = cxBufferRead(&target, 1, 4, &buf); 1410 CX_TEST_ASSERT(read == 3); 1411 CX_TEST_ASSERT(0 == memcmp(&target, "ata", 3)); 1412 CX_TEST_ASSERT(buf.pos == 9); 1413 } 1414 cxBufferDestroy(&buf); 1415 } 1416 1417 CX_TEST(test_buffer_read_oob_multibyte) { 1418 CxBuffer buf; 1419 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1420 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1421 buf.capacity = 12; 1422 buf.size = 9; 1423 buf.pos = 6; 1424 CX_TEST_DO { 1425 char target[4]; 1426 target[2] = '\0'; 1427 size_t read = cxBufferRead(&target, 2, 2, &buf); 1428 CX_TEST_ASSERT(read == 1); 1429 CX_TEST_ASSERT(0 == memcmp(&target, "at\0", 3)); 1430 CX_TEST_ASSERT(buf.pos == 8); 1431 } 1432 cxBufferDestroy(&buf); 1433 } 1434 1435 CX_TEST(test_buffer_read_eof) { 1436 CxBuffer buf; 1437 cxBufferInit(&buf, cxDefaultAllocator, NULL, 16, CX_BUFFER_DEFAULT); 1438 memcpy(buf.space, "some data\0\0\0\0\0\0\0", 16); 1439 buf.capacity = 12; 1440 buf.size = buf.pos = 9; 1441 CX_TEST_DO { 1442 char target[4]; 1443 size_t read = cxBufferRead(&target, 1, 1, &buf); 1444 CX_TEST_ASSERT(read == 0); 1445 CX_TEST_ASSERT(buf.pos == 9); 1446 } 1447 cxBufferDestroy(&buf); 1448 } 1449 1450 CxTestSuite *cx_test_suite_buffer(void) { 1451 CxTestSuite *suite = cx_test_suite_new("buffer"); 1452 1453 cx_test_register(suite, test_buffer_init_wrap_space); 1454 cx_test_register(suite, test_buffer_init_wrap_space_auto_extend); 1455 cx_test_register(suite, test_buffer_init_wrap_space_auto_free); 1456 cx_test_register(suite, test_buffer_init_fresh_space); 1457 cx_test_register(suite, test_buffer_init_on_heap); 1458 cx_test_register(suite, test_buffer_create_defaulted_allocator); 1459 cx_test_register(suite, test_buffer_minimum_capacity_sufficient); 1460 cx_test_register(suite, test_buffer_minimum_capacity_extend); 1461 cx_test_register(suite, test_buffer_maximum_capacity); 1462 cx_test_register(suite, test_buffer_shrink); 1463 cx_test_register(suite, test_buffer_shrink_copy_on_write); 1464 cx_test_register(suite, test_buffer_shrink_copy_on_extend); 1465 cx_test_register(suite, test_buffer_reserve); 1466 cx_test_register(suite, test_buffer_clear); 1467 cx_test_register(suite, test_buffer_clear_copy_on_write); 1468 cx_test_register(suite, test_buffer_reset); 1469 cx_test_register(suite, test_buffer_seek_set_zero); 1470 cx_test_register(suite, test_buffer_seek_set_valid); 1471 cx_test_register(suite, test_buffer_seek_set_invalid); 1472 cx_test_register(suite, test_buffer_seek_cur_zero); 1473 cx_test_register(suite, test_buffer_seek_cur_valid_positive); 1474 cx_test_register(suite, test_buffer_seek_cur_valid_negative); 1475 cx_test_register(suite, test_buffer_seek_cur_invalid_positive); 1476 cx_test_register(suite, test_buffer_seek_cur_invalid_negative); 1477 cx_test_register(suite, test_buffer_seek_end_zero); 1478 cx_test_register(suite, test_buffer_seek_end_valid); 1479 cx_test_register(suite, test_buffer_seek_end_invalid); 1480 cx_test_register(suite, test_buffer_seek_whence_invalid); 1481 cx_test_register(suite, test_buffer_eof_reached); 1482 cx_test_register(suite, test_buffer_eof_not_reached); 1483 cx_test_register(suite, test_buffer_shift_left_zero); 1484 cx_test_register(suite, test_buffer_shift_left_zero_offset_interface); 1485 cx_test_register(suite, test_buffer_shift_left_standard); 1486 cx_test_register(suite, test_buffer_shift_left_overshift); 1487 cx_test_register(suite, test_buffer_shift_left_overshift_pos_only); 1488 cx_test_register(suite, test_buffer_shift_left_offset_interface); 1489 cx_test_register(suite, test_buffer_shift_left_copy_on_write); 1490 cx_test_register(suite, test_buffer_shift_right_zero); 1491 cx_test_register(suite, test_buffer_shift_right_zero_offset_interface); 1492 cx_test_register(suite, test_buffer_shift_right_standard); 1493 cx_test_register(suite, test_buffer_shift_right_overshift_discard); 1494 cx_test_register(suite, test_buffer_shift_right_overshift_extend); 1495 cx_test_register(suite, test_buffer_shift_right_offset_interface); 1496 cx_test_register(suite, test_buffer_shift_right_copy_on_write); 1497 cx_test_register(suite, test_buffer_shift_right_overflow); 1498 cx_test_register(suite, test_buffer_write_size_one_fit); 1499 cx_test_register(suite, test_buffer_write_size_one_discard); 1500 cx_test_register(suite, test_buffer_write_size_one_extend); 1501 cx_test_register(suite, test_buffer_write_multibyte_fit); 1502 cx_test_register(suite, test_buffer_write_multibyte_discard); 1503 cx_test_register(suite, test_buffer_write_multibyte_extend); 1504 cx_test_register(suite, test_buffer_write_copy_on_write); 1505 cx_test_register(suite, test_buffer_append); 1506 cx_test_register(suite, test_buffer_append_string); 1507 cx_test_register(suite, test_buffer_put_fit); 1508 cx_test_register(suite, test_buffer_put_discard); 1509 cx_test_register(suite, test_buffer_put_extend); 1510 cx_test_register(suite, test_buffer_put_copy_on_write); 1511 cx_test_register(suite, test_buffer_put_string_fit); 1512 cx_test_register(suite, test_buffer_put_string_discard); 1513 cx_test_register(suite, test_buffer_put_string_extend); 1514 cx_test_register(suite, test_buffer_put_string_copy_on_extend); 1515 cx_test_register(suite, test_buffer_put_string_copy_on_write); 1516 cx_test_register(suite, test_buffer_terminate); 1517 cx_test_register(suite, test_buffer_terminate_copy_on_write); 1518 cx_test_register(suite, test_buffer_write_size_overflow); 1519 cx_test_register(suite, test_buffer_write_capacity_overflow); 1520 cx_test_register(suite, test_buffer_write_maximum_capacity_exceeded); 1521 cx_test_register(suite, test_buffer_write_only_overwrite); 1522 cx_test_register(suite, test_buffer_pop); 1523 cx_test_register(suite, test_buffer_get); 1524 cx_test_register(suite, test_buffer_get_eof); 1525 cx_test_register(suite, test_buffer_read); 1526 cx_test_register(suite, test_buffer_read_oob); 1527 cx_test_register(suite, test_buffer_read_oob_multibyte); 1528 cx_test_register(suite, test_buffer_read_eof); 1529 1530 return suite; 1531 } 1532