28 |
28 |
29 #include "cx/buffer.h" |
29 #include "cx/buffer.h" |
30 |
30 |
31 #include <stdio.h> |
31 #include <stdio.h> |
32 #include <string.h> |
32 #include <string.h> |
|
33 #include <errno.h> |
33 |
34 |
34 static int buffer_copy_on_write(CxBuffer* buffer) { |
35 static int buffer_copy_on_write(CxBuffer* buffer) { |
35 if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) return 0; |
36 if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) return 0; |
36 void *newspace = cxMalloc(buffer->allocator, buffer->capacity); |
37 void *newspace = cxMalloc(buffer->allocator, buffer->capacity); |
37 if (NULL == newspace) return -1; |
38 if (NULL == newspace) return -1; |
283 } |
286 } |
284 |
287 |
285 if (perform_flush) { |
288 if (perform_flush) { |
286 size_t flush_max; |
289 size_t flush_max; |
287 if (cx_szmul(buffer->flush_blkmax, buffer->flush_blksize, &flush_max)) { |
290 if (cx_szmul(buffer->flush_blkmax, buffer->flush_blksize, &flush_max)) { |
|
291 errno = EOVERFLOW; |
288 return 0; |
292 return 0; |
289 } |
293 } |
290 size_t flush_pos = buffer->flush_func == NULL || buffer->flush_target == NULL |
294 size_t flush_pos = buffer->flush_func == NULL || buffer->flush_target == NULL |
291 ? buffer->pos |
295 ? buffer->pos |
292 : cx_buffer_write_flush_helper(buffer, buffer->bytes, 1, buffer->pos); |
296 : cx_buffer_write_flush_helper(buffer, buffer->bytes, 1, buffer->pos); |
383 size_t nitems, |
387 size_t nitems, |
384 CxBuffer *buffer |
388 CxBuffer *buffer |
385 ) { |
389 ) { |
386 size_t len; |
390 size_t len; |
387 if (cx_szmul(size, nitems, &len)) { |
391 if (cx_szmul(size, nitems, &len)) { |
|
392 errno = EOVERFLOW; |
388 return 0; |
393 return 0; |
389 } |
394 } |
390 if (buffer->pos + len > buffer->size) { |
395 if (buffer->pos + len > buffer->size) { |
391 len = buffer->size - buffer->pos; |
396 len = buffer->size - buffer->pos; |
392 if (size > 1) len -= len % size; |
397 if (size > 1) len -= len % size; |
434 |
439 |
435 int cxBufferShiftRight( |
440 int cxBufferShiftRight( |
436 CxBuffer *buffer, |
441 CxBuffer *buffer, |
437 size_t shift |
442 size_t shift |
438 ) { |
443 ) { |
|
444 if (buffer->size > SIZE_MAX - shift) { |
|
445 errno = EOVERFLOW; |
|
446 return -1; |
|
447 } |
439 size_t req_capacity = buffer->size + shift; |
448 size_t req_capacity = buffer->size + shift; |
440 size_t movebytes; |
449 size_t movebytes; |
441 |
450 |
442 // auto extend buffer, if required and enabled |
451 // auto extend buffer, if required and enabled |
443 if (buffer->capacity < req_capacity) { |
452 if (buffer->capacity < req_capacity) { |