--- a/test/test_buffer.cpp Mon Jul 25 14:16:49 2022 +0200 +++ b/test/test_buffer.cpp Mon Jul 25 15:29:56 2022 +0200 @@ -351,6 +351,23 @@ } }; +static size_t mock_write_limited_rate( + void const *ptr, + size_t size, + __attribute__((unused)) size_t nitems, + CxBuffer *buffer +) { + // simulate limited target drain capacity + static bool full = false; + if (full) { + full = false; + return 0; + } else { + full = true; + return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer); + } +} + TEST_F(BufferWrite, SizeOneFit) { const char *data = "test"; ASSERT_EQ(buf.capacity, 8); @@ -595,6 +612,33 @@ EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0); } +TEST_F(BufferWrite, FlushRateLimited) { + enableFlushing(); + // limit the rate of the flush function and the capacity of the target + target.capacity = 16; + target.flags &= ~CX_BUFFER_AUTO_EXTEND; + buf.flush_func = (cx_write_func) mock_write_limited_rate; + ASSERT_EQ(buf.capacity, 8); + ASSERT_EQ(buf.pos, 4); + size_t written = cxBufferWrite("foo", 1, 3, &buf); + EXPECT_EQ(written, 3); + ASSERT_EQ(buf.pos, 7); + ASSERT_EQ(buf.size, 7); + ASSERT_EQ(target.pos, 0); + ASSERT_EQ(target.size, 0); + written = cxBufferWrite("hello, world!", 1, 13, &buf); + // " world!" fits into this buffer, the remaining stuff is flushed out + EXPECT_EQ(written, 13); + EXPECT_EQ(buf.pos, 7); + EXPECT_EQ(buf.size, 7); + EXPECT_EQ(buf.capacity, 8); + EXPECT_EQ(memcmp(buf.space, " world!", 7), 0); + EXPECT_EQ(target.pos, 13); + ASSERT_EQ(target.size, 13); + EXPECT_EQ(target.capacity, 16); + EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0); +} + class BufferSeek : public BufferFixture { };