src/buffer.c

changeset 539
9cd98da9ee17
parent 538
2cfbcbe86a7c
child 540
47e0f2237a94
     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(

mercurial