src/buffer.c

changeset 1028
3e4905241838
parent 1024
8f99f6c28bd3
child 1030
06091e067bee
--- a/src/buffer.c	Thu Dec 19 12:00:20 2024 +0100
+++ b/src/buffer.c	Thu Dec 19 21:33:45 2024 +0100
@@ -31,14 +31,12 @@
 #include <stdio.h>
 #include <string.h>
 
-static int buffer_copy_on_write(CxBuffer* buffer, size_t newcap) {
+static int buffer_copy_on_write(CxBuffer* buffer) {
     if (0 == (buffer->flags & CX_BUFFER_COPY_ON_WRITE)) return 0;
-    if (newcap == 0) newcap = buffer->capacity;
-    void *newspace = cxMalloc(buffer->allocator, newcap);
+    void *newspace = cxMalloc(buffer->allocator, buffer->capacity);
     if (NULL == newspace) return -1;
     memcpy(newspace, buffer->space, buffer->size);
     buffer->space = newspace;
-    buffer->capacity = newcap;
     buffer->flags &= ~CX_BUFFER_COPY_ON_WRITE;
     buffer->flags |= CX_BUFFER_FREE_CONTENTS;
     return 0;
@@ -54,6 +52,9 @@
     if (allocator == NULL) {
         allocator = cxDefaultAllocator;
     }
+    if (flags & CX_BUFFER_COPY_ON_EXTEND) {
+        flags |= CX_BUFFER_AUTO_EXTEND;
+    }
     buffer->allocator = allocator;
     buffer->flags = flags;
     if (!space) {
@@ -170,8 +171,16 @@
         return 0;
     }
 
-    if (buffer->flags & CX_BUFFER_COPY_ON_WRITE) {
-        return buffer_copy_on_write(buffer, newcap);
+    const int force_copy_flags = CX_BUFFER_COPY_ON_WRITE | CX_BUFFER_COPY_ON_EXTEND;
+    if (buffer->flags & force_copy_flags) {
+        void *newspace = cxMalloc(buffer->allocator, newcap);
+        if (NULL == newspace) return -1;
+        memcpy(newspace, buffer->space, buffer->size);
+        buffer->space = newspace;
+        buffer->capacity = newcap;
+        buffer->flags &= ~force_copy_flags;
+        buffer->flags |= CX_BUFFER_FREE_CONTENTS;
+        return 0;
     } else if (cxReallocate(buffer->allocator,
                      (void **) &buffer->bytes, newcap) == 0) {
         buffer->capacity = newcap;
@@ -224,7 +233,7 @@
 ) {
     // optimize for easy case
     if (size == 1 && (buffer->capacity - buffer->pos) >= nitems) {
-        if (buffer_copy_on_write(buffer, 0)) return 0;
+        if (buffer_copy_on_write(buffer)) return 0;
         memcpy(buffer->bytes + buffer->pos, ptr, nitems);
         buffer->pos += nitems;
         if (buffer->pos > buffer->size) {
@@ -311,7 +320,7 @@
             return cxBufferWrite(ptr, size, nitems, buffer);
         }
     } else {
-        if (buffer_copy_on_write(buffer, 0)) return 0;
+        if (buffer_copy_on_write(buffer)) return 0;
         memcpy(buffer->bytes + buffer->pos, ptr, len);
         buffer->pos += len;
         if (buffer->pos > buffer->size) {
@@ -395,7 +404,7 @@
     if (shift >= buffer->size) {
         buffer->pos = buffer->size = 0;
     } else {
-        if (buffer_copy_on_write(buffer, 0)) return -1;
+        if (buffer_copy_on_write(buffer)) return -1;
         memmove(buffer->bytes, buffer->bytes + shift, buffer->size - shift);
         buffer->size -= shift;
 
@@ -430,7 +439,7 @@
     }
 
     if (movebytes > 0) {
-        if (buffer_copy_on_write(buffer, 0)) return -1;
+        if (buffer_copy_on_write(buffer)) return -1;
         memmove(buffer->bytes + shift, buffer->bytes, movebytes);
         buffer->size = shift + movebytes;
     }

mercurial