1.1 --- a/src/buffer.c Sat Apr 30 09:03:17 2022 +0200 1.2 +++ b/src/buffer.c Sat Apr 30 09:47:20 2022 +0200 1.3 @@ -32,6 +32,7 @@ 1.4 #include <stdlib.h> 1.5 #include <stdio.h> 1.6 #include <string.h> 1.7 +#include <stdint.h> 1.8 1.9 int cxBufferInit( 1.10 CxBuffer *buffer, 1.11 @@ -53,8 +54,12 @@ 1.12 } 1.13 buffer->capacity = capacity; 1.14 buffer->size = 0; 1.15 + buffer->pos = 0; 1.16 1.17 - buffer->pos = 0; 1.18 + buffer->flush_func = NULL; 1.19 + buffer->flush_blkmax = 0; 1.20 + buffer->flush_blksize = 4096; 1.21 + buffer->flush_threshold = SIZE_MAX; 1.22 1.23 return 0; 1.24 } 1.25 @@ -134,6 +139,7 @@ 1.26 size_t nitems, 1.27 CxBuffer *buffer 1.28 ) { 1.29 + // TODO: optimize for special case size == nitems == 1 1.30 size_t len; 1.31 if (cx_szmul(size, nitems, &len)) { 1.32 return 0; 1.33 @@ -143,15 +149,27 @@ 1.34 return 0; 1.35 } 1.36 1.37 + bool perform_flush = false; 1.38 if (required > buffer->capacity) { 1.39 - if ((buffer->flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND) { 1.40 - if (cxBufferMinimumCapacity(buffer, required)) { 1.41 - return 0; 1.42 + if ((buffer->flags & CX_BUFFER_AUTO_EXTEND) == CX_BUFFER_AUTO_EXTEND && required) { 1.43 + if (buffer->flush_blkmax > 0 && required > buffer->flush_threshold) { 1.44 + perform_flush = true; 1.45 + } else { 1.46 + if (cxBufferMinimumCapacity(buffer, required)) { 1.47 + return 0; 1.48 + } 1.49 } 1.50 } else { 1.51 - len = buffer->capacity - buffer->pos; 1.52 - if (size > 1) { 1.53 - len -= len % size; 1.54 + if (buffer->flush_blkmax > 0) { 1.55 + perform_flush = true; 1.56 + } else { 1.57 + // truncate data to be written, if we can neither extend nor flush 1.58 + len = buffer->capacity - buffer->pos; 1.59 + if (size > 1) { 1.60 + // TODO: this is bugged - it would only discard one element and not as many as required 1.61 + len -= len % size; 1.62 + nitems = len / size; 1.63 + } 1.64 } 1.65 } 1.66 } 1.67 @@ -160,13 +178,25 @@ 1.68 return len; 1.69 } 1.70 1.71 - memcpy(buffer->bytes + buffer->pos, ptr, len); 1.72 - buffer->pos += len; 1.73 - if (buffer->pos > buffer->size) { 1.74 - buffer->size = buffer->pos; 1.75 + if (perform_flush) { 1.76 + // TODO: implement flushing 1.77 + // (1) determine how many bytes to flush (use flushmax = blkmax * blksize) 1.78 + // (2) if len is larger than the number computed in (1) we need more flush cycles, compute how many 1.79 + // (3) determine how many bytes from the buffer shall be flushed 1.80 + // (4) if something remains in the buffer, shift the buffer to the left 1.81 + // (4a) if buffer was shifted, append the new data to the buffer 1.82 + // (4b) if the buffer was flushed entirely AND the new data also fits into flushmax, 1.83 + // directly write the new data to the flush sink 1.84 + return 0; // remove this after implementation 1.85 + } else { 1.86 + memcpy(buffer->bytes + buffer->pos, ptr, len); 1.87 + buffer->pos += len; 1.88 + if (buffer->pos > buffer->size) { 1.89 + buffer->size = buffer->pos; 1.90 + } 1.91 } 1.92 1.93 - return len / size; 1.94 + return nitems; 1.95 } 1.96 1.97 int cxBufferPut(