src/buffer.c

changeset 1040
1ecf4dbbc60c
parent 1030
06091e067bee
equal deleted inserted replaced
1039:ec62453fc8a6 1040:1ecf4dbbc60c
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;
134 135
135 size_t opos = npos; 136 size_t opos = npos;
136 npos += offset; 137 npos += offset;
137 138
138 if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) { 139 if ((offset > 0 && npos < opos) || (offset < 0 && npos > opos)) {
140 errno = EOVERFLOW;
139 return -1; 141 return -1;
140 } 142 }
141 143
142 if (npos > buffer->size) { 144 if (npos > buffer->size) {
143 return -1; 145 return -1;
245 } 247 }
246 248
247 size_t len; 249 size_t len;
248 size_t nitems_out = nitems; 250 size_t nitems_out = nitems;
249 if (cx_szmul(size, nitems, &len)) { 251 if (cx_szmul(size, nitems, &len)) {
252 errno = EOVERFLOW;
250 return 0; 253 return 0;
251 } 254 }
252 size_t required = buffer->pos + len; 255 size_t required = buffer->pos + len;
253 if (buffer->pos > required) { 256 if (buffer->pos > required) {
254 return 0; 257 return 0;
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) {

mercurial