tests/test_buffer.c

changeset 1129
cc60b7d07912
parent 1112
22dc2163fffd
--- a/tests/test_buffer.c	Thu Jan 16 18:56:17 2025 +0100
+++ b/tests/test_buffer.c	Thu Jan 16 18:56:44 2025 +0100
@@ -1180,6 +1180,93 @@
     cxBufferDestroy(&target);
 }
 
+CX_TEST(test_buffer_write_flush_multibyte) {
+    // this test case tests that flushing works correctly even when the
+    // contents in the buffer are currently not aligned with the item size
+    CxBuffer buf, target;
+    cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+    cxBufferInit(&buf, NULL, 8, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    memset(buf.space, 0, 8);
+    cxBufferPutString(&buf, "pre");
+    CX_TEST_DO {
+        CxBufferFlushConfig flush;
+        flush.threshold = 0;
+        flush.blksize = 4; // test blksize that is not aligned
+        flush.blkmax = 2; // test with two blocks
+        flush.target = ⌖
+        flush.wfunc = cxBufferWriteFunc;
+        CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush));
+        // first case: string fits after flush
+        size_t written = cxBufferWrite("foobar", 3, 2, &buf);
+        CX_TEST_ASSERT(written == 2);
+        CX_TEST_ASSERT(buf.pos == 6);
+        CX_TEST_ASSERT(buf.size == 6);
+        CX_TEST_ASSERT(target.pos == 3);
+        CX_TEST_ASSERT(target.size == 3);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "foobar", 6));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "pre", 3));
+        // second case: string does not fit, data is relayed, but only two blocks!
+        written = cxBufferWrite("bazfooBAR", 3, 3, &buf);
+        CX_TEST_ASSERT(written == 3);
+        CX_TEST_ASSERT(buf.pos == 3);
+        CX_TEST_ASSERT(buf.size == 3);
+        CX_TEST_ASSERT(target.pos == 15);
+        CX_TEST_ASSERT(target.size == 15);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "BAR", 3));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prefoobarbazfoo", 15));
+        // third case: everything can be relayed, block size is large enough
+        buf.flush->blkmax = 3;
+        written = cxBufferWrite("abcdef012", 3, 3, &buf);
+        CX_TEST_ASSERT(written == 3);
+        CX_TEST_ASSERT(buf.pos == 0);
+        CX_TEST_ASSERT(buf.size == 0);
+        CX_TEST_ASSERT(target.pos == 27);
+        CX_TEST_ASSERT(target.size == 27);
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prefoobarbazfooBARabcdef012", 27));
+    }
+    cxBufferDestroy(&buf);
+    cxBufferDestroy(&target);
+}
+
+CX_TEST(test_buffer_write_flush_misaligned) {
+    // this test case tests that flushing works correctly even when the
+    // contents in the buffer are currently not aligned with the item size
+    CxBuffer buf, target;
+    cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
+    cxBufferInit(&buf, NULL, 8, cxDefaultAllocator, CX_BUFFER_DEFAULT);
+    memset(buf.space, 0, 8);
+    cxBufferPutString(&buf, "prep");
+    CX_TEST_DO {
+        CxBufferFlushConfig flush;
+        flush.threshold = 0;
+        flush.blksize = 32;
+        flush.blkmax = 1;
+        flush.target = ⌖
+        flush.wfunc = cxBufferWriteFunc;
+        CX_TEST_ASSERT(0 == cxBufferEnableFlushing(&buf, flush));
+        // first case: string fits after flush
+        size_t written = cxBufferWrite("foobar", 3, 2, &buf);
+        CX_TEST_ASSERT(written == 2);
+        CX_TEST_ASSERT(buf.pos == 7);
+        CX_TEST_ASSERT(buf.size == 7);
+        CX_TEST_ASSERT(target.pos == 3);
+        CX_TEST_ASSERT(target.size == 3);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "pfoobar", 7));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "pre", 3));
+        // second case: string does not fit, relaying not possible due to misalignment
+        written = cxBufferWrite("bazfoobar", 3, 3, &buf);
+        CX_TEST_ASSERT(written == 0);
+        CX_TEST_ASSERT(buf.pos == 1);
+        CX_TEST_ASSERT(buf.size == 1);
+        CX_TEST_ASSERT(target.pos == 9);
+        CX_TEST_ASSERT(target.size == 9);
+        CX_TEST_ASSERT(0 == memcmp(buf.space, "r", 1));
+        CX_TEST_ASSERT(0 == memcmp(target.space, "prepfooba", 9));
+    }
+    cxBufferDestroy(&buf);
+    cxBufferDestroy(&target);
+}
+
 CX_TEST(test_buffer_flush) {
     CxBuffer buf, target;
     cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
@@ -1377,6 +1464,8 @@
     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_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_flush);
     cx_test_register(suite, test_buffer_get);
     cx_test_register(suite, test_buffer_get_eof);

mercurial