#184 #170 more thorough flush testing

Mon, 25 Jul 2022 15:29:56 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 25 Jul 2022 15:29:56 +0200
changeset 567
f90a7cfe2480
parent 566
d3100c987a39
child 568
8eda32d09e3d

#184 #170 more thorough flush testing

Also adds proper doc for write function.

src/buffer.c file | annotate | diff | comparison | revisions
src/cx/buffer.h file | annotate | diff | comparison | revisions
test/test_buffer.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/buffer.c	Mon Jul 25 14:16:49 2022 +0200
     1.2 +++ b/src/buffer.c	Mon Jul 25 15:29:56 2022 +0200
     1.3 @@ -248,7 +248,8 @@
     1.4                  // try again with the remaining stuff
     1.5                  unsigned char const *new_ptr = ptr;
     1.6                  new_ptr += items_flush * size;
     1.7 -                return cxBufferWrite(new_ptr, size, items_keep, buffer);
     1.8 +                // report the directly flushed items as written plus the remaining stuff
     1.9 +                return items_flush + cxBufferWrite(new_ptr, size, items_keep, buffer);
    1.10              } else {
    1.11                  // all items have been flushed - report them as written
    1.12                  return nitems;
    1.13 @@ -257,7 +258,7 @@
    1.14              // nothing could be flushed at all, we immediately give up without writing any data
    1.15              return 0;
    1.16          } else {
    1.17 -            // we were partially successful, we have shift left and try again
    1.18 +            // we were partially successful, we shift left and try again
    1.19              cxBufferShiftLeft(buffer, flush_pos);
    1.20              return cxBufferWrite(ptr, size, nitems, buffer);
    1.21          }
     2.1 --- a/src/cx/buffer.h	Mon Jul 25 14:16:49 2022 +0200
     2.2 +++ b/src/cx/buffer.h	Mon Jul 25 15:29:56 2022 +0200
     2.3 @@ -310,7 +310,20 @@
     2.4  /**
     2.5   * Writes data to a CxBuffer.
     2.6   *
     2.7 - * The position of the buffer is increased by the number of bytes written.
     2.8 + * If flushing is enabled and the buffer needs to flush, the data is flushed to
     2.9 + * the target until the target signals that it cannot take more data by
    2.10 + * returning zero via the respective write function. In that case, the remaining
    2.11 + * data in this buffer is shifted to the beginning of this buffer so that the
    2.12 + * newly available space can be used to append as much data as possible. This
    2.13 + * function only stops writing more elements, when the flush target and this
    2.14 + * buffer are both incapable of taking more data or all data has been written.
    2.15 + * The number returned by this function is the total number of elements that
    2.16 + * could be written during the process. It does not necessarily mean that those
    2.17 + * elements are still in this buffer, because some of them could have also be
    2.18 + * flushed already.
    2.19 + *
    2.20 + * If automatic flushing is not enabled, the position of the buffer is increased
    2.21 + * by the number of bytes written.
    2.22   *
    2.23   * \note The signature is compatible with the fwrite() family of functions.
    2.24   *
     3.1 --- a/test/test_buffer.cpp	Mon Jul 25 14:16:49 2022 +0200
     3.2 +++ b/test/test_buffer.cpp	Mon Jul 25 15:29:56 2022 +0200
     3.3 @@ -351,6 +351,23 @@
     3.4      }
     3.5  };
     3.6  
     3.7 +static size_t mock_write_limited_rate(
     3.8 +        void const *ptr,
     3.9 +        size_t size,
    3.10 +        __attribute__((unused)) size_t nitems,
    3.11 +        CxBuffer *buffer
    3.12 +) {
    3.13 +    // simulate limited target drain capacity
    3.14 +    static bool full = false;
    3.15 +    if (full) {
    3.16 +        full = false;
    3.17 +        return 0;
    3.18 +    } else {
    3.19 +        full = true;
    3.20 +        return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer);
    3.21 +    }
    3.22 +}
    3.23 +
    3.24  TEST_F(BufferWrite, SizeOneFit) {
    3.25      const char *data = "test";
    3.26      ASSERT_EQ(buf.capacity, 8);
    3.27 @@ -595,6 +612,33 @@
    3.28      EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0);
    3.29  }
    3.30  
    3.31 +TEST_F(BufferWrite, FlushRateLimited) {
    3.32 +    enableFlushing();
    3.33 +    // limit the rate of the flush function and the capacity of the target
    3.34 +    target.capacity = 16;
    3.35 +    target.flags &= ~CX_BUFFER_AUTO_EXTEND;
    3.36 +    buf.flush_func = (cx_write_func) mock_write_limited_rate;
    3.37 +    ASSERT_EQ(buf.capacity, 8);
    3.38 +    ASSERT_EQ(buf.pos, 4);
    3.39 +    size_t written = cxBufferWrite("foo", 1, 3, &buf);
    3.40 +    EXPECT_EQ(written, 3);
    3.41 +    ASSERT_EQ(buf.pos, 7);
    3.42 +    ASSERT_EQ(buf.size, 7);
    3.43 +    ASSERT_EQ(target.pos, 0);
    3.44 +    ASSERT_EQ(target.size, 0);
    3.45 +    written = cxBufferWrite("hello, world!", 1, 13, &buf);
    3.46 +    // " world!" fits into this buffer, the remaining stuff is flushed out
    3.47 +    EXPECT_EQ(written, 13);
    3.48 +    EXPECT_EQ(buf.pos, 7);
    3.49 +    EXPECT_EQ(buf.size, 7);
    3.50 +    EXPECT_EQ(buf.capacity, 8);
    3.51 +    EXPECT_EQ(memcmp(buf.space, " world!", 7), 0);
    3.52 +    EXPECT_EQ(target.pos, 13);
    3.53 +    ASSERT_EQ(target.size, 13);
    3.54 +    EXPECT_EQ(target.capacity, 16);
    3.55 +    EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0);
    3.56 +}
    3.57 +
    3.58  class BufferSeek : public BufferFixture {
    3.59  };
    3.60  

mercurial