tests/test_buffer.c

changeset 1024
8f99f6c28bd3
parent 1007
81b2986d2b04
child 1026
ca20f9ffcb62
--- a/tests/test_buffer.c	Sun Dec 15 15:23:29 2024 +0100
+++ b/tests/test_buffer.c	Wed Dec 18 15:35:42 2024 +0100
@@ -215,6 +215,22 @@
     cxBufferDestroy(&buf);
 }
 
+CX_TEST(test_buffer_clear_copy_on_write) {
+    char space[16];
+    strcpy(space, "clear test");
+    CxBuffer buf;
+    cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_COPY_ON_WRITE);
+    CX_TEST_DO {
+        buf.size = 5;
+        buf.pos = 3;
+        cxBufferClear(&buf);
+        CX_TEST_ASSERT(0 == memcmp(space, "clear test", 10));
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(buf.pos == 0);
+    }
+    cxBufferDestroy(&buf);
+}
+
 CX_TEST(test_buffer_reset) {
     char space[16];
     strcpy(space, "reset test");
@@ -506,6 +522,24 @@
     }
 }
 
+CX_TEST(test_buffer_shift_left_copy_on_write) {
+    TEST_BUFFER_SHIFT_SETUP(buf);
+    buf.flags |= CX_BUFFER_COPY_ON_WRITE;
+    char *original = buf.space;
+    CX_TEST_DO {
+        int ret = cxBufferShiftLeft(&buf, 2);
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS));
+        CX_TEST_ASSERT(ret == 0);
+        CX_TEST_ASSERT(buf.pos == 2);
+        CX_TEST_ASSERT(buf.size == 2);
+        CX_TEST_ASSERT(memcmp(original, "test____XXXXXXXX", 16) == 0);
+        CX_TEST_ASSERT(memcmp(buf.space, "st", 2) == 0);
+        cxFree(buf.allocator, original);
+        TEST_BUFFER_SHIFT_TEARDOWN(buf);
+    }
+}
+
 CX_TEST(test_buffer_shift_right_zero) {
     TEST_BUFFER_SHIFT_SETUP(buf);
     CX_TEST_DO {
@@ -584,6 +618,24 @@
     }
 }
 
+CX_TEST(test_buffer_shift_right_copy_on_write) {
+    TEST_BUFFER_SHIFT_SETUP(buf);
+    buf.flags |= CX_BUFFER_COPY_ON_WRITE;
+    char *original = buf.space;
+    CX_TEST_DO {
+        int ret = cxBufferShiftRight(&buf, 3);
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS));
+        CX_TEST_ASSERT(ret == 0);
+        CX_TEST_ASSERT(buf.pos == 7);
+        CX_TEST_ASSERT(buf.size == 7);
+        CX_TEST_ASSERT(memcmp(original, "test____XXXXXXXX", 16) == 0);
+        CX_TEST_ASSERT(memcmp(buf.space, "testest", 7) == 0);
+        cxFree(buf.allocator, original);
+        TEST_BUFFER_SHIFT_TEARDOWN(buf);
+    }
+}
+
 static size_t mock_write_limited_rate(
         const void *ptr,
         size_t size,
@@ -657,6 +709,28 @@
     cxBufferDestroy(&buf);
 }
 
+CX_TEST(test_buffer_write_copy_on_write) {
+    CxBuffer buf;
+    char original[16] = "preparedXXXXXXX\0";
+    cxBufferInit(&buf, original, 16, cxDefaultAllocator, CX_BUFFER_COPY_ON_WRITE);
+    buf.capacity = 8;
+    buf.size = 8;
+    buf.pos = 0;
+    const char *data = "testing";
+    CX_TEST_DO {
+        size_t written = cxBufferWrite(data, 1, 7, &buf);
+        CX_TEST_ASSERT(written == 7);
+        CX_TEST_ASSERT(buf.size == 8);
+        CX_TEST_ASSERT(buf.pos == 7);
+        CX_TEST_ASSERT(buf.capacity == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "testingd", 8));
+        CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16));
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS));
+    }
+    cxBufferDestroy(&buf);
+}
+
 CX_TEST(test_buffer_write_multibyte_fit) {
     CxBuffer buf;
     cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
@@ -770,6 +844,40 @@
     cxBufferDestroy(&buf);
 }
 
+CX_TEST(test_buffer_put_copy_on_write) {
+    CxBuffer buf;
+    char original[16] = "preparedXXXXXXX\0";
+    cxBufferInit(&buf, original, 16, cxDefaultAllocator, CX_BUFFER_COPY_ON_WRITE);
+    buf.capacity = 8;
+    buf.size = 8;
+    buf.pos = 8;
+    CX_TEST_DO {
+        int c = cxBufferPut(&buf, 0x200 | 'a');
+        CX_TEST_ASSERT(c == EOF);
+        CX_TEST_ASSERT(buf.size == 8);
+        CX_TEST_ASSERT(buf.pos == 8);
+        CX_TEST_ASSERT(buf.capacity == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "prepared", 8));
+        // discarded, no write happend!
+        CX_TEST_ASSERT(original == buf.space);
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_FREE_CONTENTS));
+        // now actually write somewhere
+        buf.pos = 2;
+        c = cxBufferPut(&buf, 0x200 | 'a');
+        CX_TEST_ASSERT(c == 'a');
+        CX_TEST_ASSERT(buf.size == 8);
+        CX_TEST_ASSERT(buf.pos == 3);
+        CX_TEST_ASSERT(buf.capacity == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "prapared", 8));
+        CX_TEST_ASSERT(original != buf.space);
+        CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16));
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS));
+    }
+    cxBufferDestroy(&buf);
+}
+
 CX_TEST(test_buffer_put_string_fit) {
     CxBuffer buf;
     cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
@@ -825,6 +933,30 @@
     cxBufferDestroy(&buf);
 }
 
+CX_TEST(test_buffer_put_string_extend_copy_on_write) {
+    CxBuffer buf;
+    char original[16] = "preparedXXXXXXX\0";
+    cxBufferInit(&buf, original, 16, cxDefaultAllocator, CX_BUFFER_COPY_ON_WRITE);
+    buf.capacity = 8;
+    buf.size = 8;
+    buf.pos = 4;
+    buf.flags |= CX_BUFFER_AUTO_EXTEND;
+    const char *data = "testing";
+    CX_TEST_DO {
+        size_t written = cxBufferPutString(&buf, data);
+        CX_TEST_ASSERT(written == 7);
+        CX_TEST_ASSERT(buf.size == 11);
+        CX_TEST_ASSERT(buf.pos == 11);
+        CX_TEST_ASSERT(buf.capacity >= 11);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "preptesting", 11));
+        CX_TEST_ASSERT(original != buf.space);
+        CX_TEST_ASSERT(0 == memcmp(original, "preparedXXXXXXX\0", 16));
+        CX_TEST_ASSERT(0 == (buf.flags & CX_BUFFER_COPY_ON_WRITE));
+        CX_TEST_ASSERT(0 != (buf.flags & CX_BUFFER_FREE_CONTENTS));
+    }
+    cxBufferDestroy(&buf);
+}
+
 CX_TEST(test_buffer_terminate) {
     CxBuffer buf;
     cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
@@ -1113,6 +1245,7 @@
     cx_test_register(suite, test_buffer_minimum_capacity_sufficient);
     cx_test_register(suite, test_buffer_minimum_capacity_extend);
     cx_test_register(suite, test_buffer_clear);
+    cx_test_register(suite, test_buffer_clear_copy_on_write);
     cx_test_register(suite, test_buffer_reset);
     cx_test_register(suite, test_buffer_seek_set_zero);
     cx_test_register(suite, test_buffer_seek_set_valid);
@@ -1134,24 +1267,29 @@
     cx_test_register(suite, test_buffer_shift_left_overshift);
     cx_test_register(suite, test_buffer_shift_left_overshift_pos_only);
     cx_test_register(suite, test_buffer_shift_left_offset_interface);
+    cx_test_register(suite, test_buffer_shift_left_copy_on_write);
     cx_test_register(suite, test_buffer_shift_right_zero);
     cx_test_register(suite, test_buffer_shift_right_zero_offset_interface);
     cx_test_register(suite, test_buffer_shift_right_standard);
     cx_test_register(suite, test_buffer_shift_right_overshift_discard);
     cx_test_register(suite, test_buffer_shift_right_overshift_extend);
     cx_test_register(suite, test_buffer_shift_right_offset_interface);
+    cx_test_register(suite, test_buffer_shift_right_copy_on_write);
     cx_test_register(suite, test_buffer_write_size_one_fit);
     cx_test_register(suite, test_buffer_write_size_one_discard);
     cx_test_register(suite, test_buffer_write_size_one_extend);
     cx_test_register(suite, test_buffer_write_multibyte_fit);
     cx_test_register(suite, test_buffer_write_multibyte_discard);
     cx_test_register(suite, test_buffer_write_multibyte_extend);
+    cx_test_register(suite, test_buffer_write_copy_on_write);
     cx_test_register(suite, test_buffer_put_fit);
     cx_test_register(suite, test_buffer_put_discard);
     cx_test_register(suite, test_buffer_put_extend);
+    cx_test_register(suite, test_buffer_put_copy_on_write);
     cx_test_register(suite, test_buffer_put_string_fit);
     cx_test_register(suite, test_buffer_put_string_discard);
     cx_test_register(suite, test_buffer_put_string_extend);
+    cx_test_register(suite, test_buffer_put_string_extend_copy_on_write);
     cx_test_register(suite, test_buffer_terminate);
     cx_test_register(suite, test_buffer_write_size_overflow);
     cx_test_register(suite, test_buffer_write_capacity_overflow);

mercurial