Fri, 17 Jan 2025 17:55:21 +0100
fix cxBufferAppend() not adjusting position after flush
fixes #565
src/buffer.c | file | annotate | diff | comparison | revisions | |
tests/test_buffer.c | file | annotate | diff | comparison | revisions |
--- a/src/buffer.c Fri Jan 17 17:41:29 2025 +0100 +++ b/src/buffer.c Fri Jan 17 17:55:21 2025 +0100 @@ -356,9 +356,19 @@ CxBuffer *buffer ) { size_t pos = buffer->pos; - buffer->pos = buffer->size; + size_t append_pos = buffer->size; + buffer->pos = append_pos; size_t written = cxBufferWrite(ptr, size, nitems, buffer); - buffer->pos = pos; + // the buffer might have been flushed + // we must compute a possible delta for the position + // expected: pos = append_pos + written + // -> if this is not the case, there is a delta + size_t delta = append_pos + written*size - buffer->pos; + if (delta > pos) { + buffer->pos = 0; + } else { + buffer->pos = pos - delta; + } return written; }
--- a/tests/test_buffer.c Fri Jan 17 17:41:29 2025 +0100 +++ b/tests/test_buffer.c Fri Jan 17 17:55:21 2025 +0100 @@ -792,6 +792,47 @@ cxBufferDestroy(&buf); } +CX_TEST(test_buffer_append_flush) { + CxBuffer buf, target; + cxBufferInit(&buf, NULL, 8, cxDefaultAllocator, CX_BUFFER_DEFAULT); + cxBufferInit(&target, NULL, 8, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND); + memcpy(buf.space, "prepXXXX", 8); + buf.capacity = 8; + buf.size = 6; + buf.pos = 4; + CxBufferFlushConfig flush; + flush.threshold = 0; + flush.blksize = 4; + flush.blkmax = 1; + flush.target = ⌖ + flush.wfunc = cxBufferWriteFunc; + cxBufferEnableFlushing(&buf, flush); + CX_TEST_DO{ + size_t written = cxBufferAppend("testing", 1, 7, &buf); + CX_TEST_ASSERT(written == 7); + CX_TEST_ASSERT(buf.size == 7); + CX_TEST_ASSERTM(buf.pos == 0, "position not correctly reset"); + CX_TEST_ASSERT(buf.capacity == 8); + CX_TEST_ASSERT(target.size == 6); + CX_TEST_ASSERT(target.pos == 6); + CX_TEST_ASSERT(0 == memcmp(buf.space, "testing", 7)); + CX_TEST_ASSERT(0 == memcmp(target.space, "prepXX", 6)); + // second test - position only shifted by one block + buf.pos = 6; + written = cxBufferAppend("foo", 1, 3, &buf); + CX_TEST_ASSERT(written == 3); + CX_TEST_ASSERT(buf.size == 6); + CX_TEST_ASSERTM(buf.pos == 2, "position not correctly adjusted"); + CX_TEST_ASSERT(buf.capacity == 8); + CX_TEST_ASSERT(target.size == 10); + CX_TEST_ASSERT(target.pos == 10); + CX_TEST_ASSERT(0 == memcmp(buf.space, "ingfoo", 6)); + CX_TEST_ASSERT(0 == memcmp(target.space, "prepXXtest", 10)); + } + cxBufferDestroy(&buf); + cxBufferDestroy(&target); +} + CX_TEST(test_buffer_put_fit) { CxBuffer buf; cxBufferInit(&buf, NULL, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT); @@ -1448,6 +1489,7 @@ 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_append); + cx_test_register(suite, test_buffer_append_flush); cx_test_register(suite, test_buffer_put_fit); cx_test_register(suite, test_buffer_put_discard); cx_test_register(suite, test_buffer_put_extend);