| 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, |