ucx/buffer.c

changeset 995
2f811eae2424
parent 992
f421aef8f865
equal deleted inserted replaced
994:c9395b30e5c8 995:2f811eae2424
72 72
73 return 0; 73 return 0;
74 } 74 }
75 75
76 void cxBufferDestroy(CxBuffer *buffer) { 76 void cxBufferDestroy(CxBuffer *buffer) {
77 if (buffer->flags & CX_BUFFER_FREE_CONTENTS) { 77 if ((buffer->flags & (CX_BUFFER_FREE_CONTENTS | CX_BUFFER_DO_NOT_FREE))
78 == CX_BUFFER_FREE_CONTENTS) {
78 cxFree(buffer->allocator, buffer->bytes); 79 cxFree(buffer->allocator, buffer->bytes);
79 } 80 }
80 memset(buffer, 0, sizeof(CxBuffer)); 81 memset(buffer, 0, sizeof(CxBuffer));
81 } 82 }
82 83
296 const void *ptr, 297 const void *ptr,
297 size_t size, 298 size_t size,
298 size_t nitems, 299 size_t nitems,
299 CxBuffer *buffer 300 CxBuffer *buffer
300 ) { 301 ) {
302 // trivial case
303 if (size == 0 || nitems == 0) return 0;
304
301 // optimize for easy case 305 // optimize for easy case
302 if (size == 1 && (buffer->capacity - buffer->pos) >= nitems) { 306 if (size == 1 && (buffer->capacity - buffer->pos) >= nitems) {
303 if (buffer_copy_on_write(buffer)) return 0; 307 if (buffer_copy_on_write(buffer)) return 0;
304 memcpy(buffer->bytes + buffer->pos, ptr, nitems); 308 memcpy(buffer->bytes + buffer->pos, ptr, nitems);
305 buffer->pos += nitems; 309 buffer->pos += nitems;
361 const void *ptr, 365 const void *ptr,
362 size_t size, 366 size_t size,
363 size_t nitems, 367 size_t nitems,
364 CxBuffer *buffer 368 CxBuffer *buffer
365 ) { 369 ) {
366 size_t pos = buffer->pos; 370 // trivial case
367 size_t append_pos = buffer->size; 371 if (size == 0 || nitems == 0) return 0;
368 buffer->pos = append_pos; 372
369 size_t written = cxBufferWrite(ptr, size, nitems, buffer); 373 const size_t pos = buffer->pos;
370 // the buffer might have been flushed 374 buffer->pos = buffer->size;
371 // we must compute a possible delta for the position 375 const size_t written = cxBufferWrite(ptr, size, nitems, buffer);
372 // expected: pos = append_pos + written 376 buffer->pos = pos;
373 // -> if this is not the case, there is a delta
374 size_t delta = append_pos + written*size - buffer->pos;
375 if (delta > pos) {
376 buffer->pos = 0;
377 } else {
378 buffer->pos = pos - delta;
379 }
380 return written; 377 return written;
381 } 378 }
382 379
383 int cxBufferPut( 380 int cxBufferPut(
384 CxBuffer *buffer, 381 CxBuffer *buffer,
392 return EOF; 389 return EOF;
393 } 390 }
394 } 391 }
395 392
396 int cxBufferTerminate(CxBuffer *buffer) { 393 int cxBufferTerminate(CxBuffer *buffer) {
397 if (0 == cxBufferPut(buffer, 0)) { 394 // try to extend / shrink the buffer
398 buffer->size = buffer->pos - 1; 395 if (buffer->pos >= buffer->capacity) {
399 return 0; 396 if ((buffer->flags & CX_BUFFER_AUTO_EXTEND) == 0) {
400 } else { 397 return -1;
401 return -1; 398 }
402 } 399 if (cxBufferReserve(buffer, buffer->pos + 1)) {
403 } 400 return -1; // LCOV_EXCL_LINE
404 401 }
405 size_t cxBufferPutString( 402 } else {
406 CxBuffer *buffer, 403 buffer->size = buffer->pos;
407 const char *str 404 cxBufferShrink(buffer, 1);
408 ) { 405 // set the capacity explicitly, in case shrink was skipped due to CoW
409 return cxBufferWrite(str, 1, strlen(str), buffer); 406 buffer->capacity = buffer->size + 1;
407 }
408
409 // check if we are still on read-only memory
410 if (buffer_copy_on_write(buffer)) return -1;
411
412 // write the terminator and exit
413 buffer->space[buffer->pos] = '\0';
414 return 0;
415 }
416
417 size_t cx_buffer_put_string(CxBuffer *buffer, cxstring str) {
418 return cxBufferWrite(str.ptr, 1, str.length, buffer);
419 }
420
421 size_t cx_buffer_append_string(CxBuffer *buffer, cxstring str) {
422 return cxBufferAppend(str.ptr, 1, str.length, buffer);
410 } 423 }
411 424
412 size_t cxBufferRead( 425 size_t cxBufferRead(
413 void *ptr, 426 void *ptr,
414 size_t size, 427 size_t size,

mercurial