tests/test_buffer.c

changeset 1516
95b094472e9a
parent 1502
0130ee1ae112
--- a/tests/test_buffer.c	Wed Nov 26 23:22:03 2025 +0100
+++ b/tests/test_buffer.c	Wed Nov 26 23:35:25 2025 +0100
@@ -1478,7 +1478,7 @@
         CX_TEST_ASSERT(target.size == 8);
         CX_TEST_ASSERT(0 == memcmp(buf.space, "arxyz123", 8));
         CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoob", 8));
-        // final test, cannot write anything more
+        // final test - cannot write anything more
         written = cxBufferWrite("baz", 1, 3, &buf);
         CX_TEST_ASSERT(written == 0);
         CX_TEST_ASSERT(buf.pos == 8);
@@ -1492,6 +1492,98 @@
     cxBufferDestroy(&target);
 }
 
+CX_TEST(test_buffer_write_flush_multibyte_target_full) {
+    CxBuffer buf, target;
+    cxBufferInit(&target, NULL, 12, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    cxBufferInit(&buf, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+    CX_TEST_DO {
+        CxBufferFlushConfig flush;
+        flush.threshold = 12;
+        flush.blksize = 8;
+        flush.blkmax = 2;
+        flush.target = ⌖
+        flush.wfunc = cxBufferWriteFunc;
+        CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush));
+        cxBufferPutString(&buf, "preparation");
+        size_t written = cxBufferWrite("teststring", 2, 5, &buf);
+        CX_TEST_ASSERT(written == 5);
+        CX_TEST_ASSERT(buf.pos == 11);
+        CX_TEST_ASSERT(buf.size == 11);
+        CX_TEST_ASSERT(target.pos == 10);
+        CX_TEST_ASSERT(target.size == 10);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "nteststring", 11));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "preparatio", 10));
+        // pop the misaligned byte from the buffer
+        cxBufferPop(&buf, 1, 1);
+        // write three more items, but only one fits into the target and one more into the buffer
+        written = cxBufferWrite("123456", 2, 3, &buf);
+        CX_TEST_ASSERT(written == 2);
+        CX_TEST_ASSERT(buf.pos == 12);
+        CX_TEST_ASSERT(buf.size == 12);
+        CX_TEST_ASSERT(target.pos == 12);
+        CX_TEST_ASSERT(target.size == 12);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "eststrin1234", 12));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "preparationt", 12));
+    }
+    cxBufferDestroy(&buf);
+    cxBufferDestroy(&target);
+}
+
+CX_TEST(test_buffer_write_flush_at_threshold_target_full) {
+    CxBuffer buf, target;
+    // target does NOT auto-extend and can get completely full
+    cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    // source may auto-extend but flushes at a certain threshold
+    cxBufferInit(&buf, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+    cxBufferPutString(&buf, "prep");
+    CX_TEST_DO {
+        CxBufferFlushConfig flush;
+        flush.threshold = 16;
+        flush.blksize = 4;
+        flush.blkmax = 2;
+        flush.target = ⌖
+        flush.wfunc = cxBufferWriteFunc;
+        CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush));
+        // step one - adding 6 bytes does not exceed the threshold
+        size_t written = cxBufferWrite("foobar", 1, 6, &buf);
+        CX_TEST_ASSERT(written == 6);
+        CX_TEST_ASSERT(buf.pos == 10);
+        CX_TEST_ASSERT(buf.size == 10);
+        CX_TEST_ASSERT(target.pos == 0);
+        CX_TEST_ASSERT(target.size == 0);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "prepfoobar", 10));
+        // step two - adding 8 bytes is two too many, two blocks are flushed
+        written = cxBufferWrite("12345678", 1, 8, &buf);
+        CX_TEST_ASSERT(written == 8);
+        CX_TEST_ASSERT(buf.pos == 10);
+        CX_TEST_ASSERT(buf.size == 10);
+        CX_TEST_ASSERT(target.pos == 8);
+        CX_TEST_ASSERT(target.size == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "ar12345678", 10));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoob", 8));
+        // step three - cannot flush more, but can write 6 more bytes
+        written = cxBufferWrite("ABCDEFGH", 1, 8, &buf);
+        CX_TEST_ASSERT(written == 6);
+        CX_TEST_ASSERT(buf.pos == 16);
+        CX_TEST_ASSERT(buf.size == 16);
+        CX_TEST_ASSERT(target.pos == 8);
+        CX_TEST_ASSERT(target.size == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "ar12345678ABCDEF", 16));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoob", 8));
+        // final test - cannot write anything more
+        written = cxBufferWrite("baz", 1, 3, &buf);
+        CX_TEST_ASSERT(written == 0);
+        CX_TEST_ASSERT(buf.pos == 16);
+        CX_TEST_ASSERT(buf.size == 16);
+        CX_TEST_ASSERT(target.pos == 8);
+        CX_TEST_ASSERT(target.size == 8);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "ar12345678ABCDEF", 16));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prepfoob", 8));
+    }
+    cxBufferDestroy(&buf);
+    cxBufferDestroy(&target);
+}
+
 CX_TEST(test_buffer_flush) {
     CxBuffer buf, target;
     cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
@@ -1700,10 +1792,12 @@
     cx_test_register(suite, test_buffer_write_only_overwrite);
     cx_test_register(suite, test_buffer_write_flush_at_capacity);
     cx_test_register(suite, test_buffer_write_flush_at_threshold);
+    cx_test_register(suite, test_buffer_write_flush_at_threshold_target_full);
     cx_test_register(suite, test_buffer_write_flush_rate_limited_and_buffer_too_small);
     cx_test_register(suite, test_buffer_write_flush_multibyte);
     cx_test_register(suite, test_buffer_write_flush_misaligned);
     cx_test_register(suite, test_buffer_write_flush_target_full);
+    cx_test_register(suite, test_buffer_write_flush_multibyte_target_full);
     cx_test_register(suite, test_buffer_flush);
     cx_test_register(suite, test_buffer_get);
     cx_test_register(suite, test_buffer_get_eof);

mercurial