test/test_buffer.cpp

Mon, 16 May 2022 19:15:44 +0200

author
Mike Becker <universe@uap-core.de>
date
Mon, 16 May 2022 19:15:44 +0200
changeset 547
9e933920dcf9
parent 546
900795d59d03
child 548
459bca1cdf8d
permissions
-rw-r--r--

#170 test buffer seek

     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
     5  *
     6  * Redistribution and use in source and binary forms, with or without
     7  * modification, are permitted provided that the following conditions are met:
     8  *
     9  *   1. Redistributions of source code must retain the above copyright
    10  *      notice, this list of conditions and the following disclaimer.
    11  *
    12  *   2. Redistributions in binary form must reproduce the above copyright
    13  *      notice, this list of conditions and the following disclaimer in the
    14  *      documentation and/or other materials provided with the distribution.
    15  *
    16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    26  * POSSIBILITY OF SUCH DAMAGE.
    27  */
    29 #include "cx/buffer.h"
    31 #include <gtest/gtest.h>
    32 #include "util_allocator.h"
    34 static void expect_default_flush_config(CxBuffer *buf) {
    35     EXPECT_EQ(buf->flush_blkmax, 0);
    36     EXPECT_EQ(buf->flush_blksize, 4096);
    37     EXPECT_EQ(buf->flush_threshold, SIZE_MAX);
    38     EXPECT_EQ(buf->flush_func, nullptr);
    39     EXPECT_EQ(buf->flush_target, nullptr);
    40 }
    42 TEST(BufferInit, WrapSpace) {
    43     CxTestingAllocator alloc;
    44     CxBuffer buf;
    45     void *space = cxMalloc(&alloc, 16);
    46     cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_DEFAULT);
    47     expect_default_flush_config(&buf);
    48     EXPECT_EQ(buf.space, space);
    49     EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
    50     EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
    51     EXPECT_EQ(buf.pos, 0);
    52     EXPECT_EQ(buf.size, 0);
    53     EXPECT_EQ(buf.capacity, 16);
    54     EXPECT_EQ(buf.allocator, &alloc);
    55     cxBufferDestroy(&buf);
    56     EXPECT_FALSE(alloc.verify());
    57     cxFree(&alloc, space);
    58     EXPECT_TRUE(alloc.verify());
    59 }
    61 TEST(BufferInit, WrapSpaceAutoExtend) {
    62     CxTestingAllocator alloc;
    63     CxBuffer buf;
    64     void *space = cxMalloc(&alloc, 16);
    65     cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_AUTO_EXTEND);
    66     expect_default_flush_config(&buf);
    67     EXPECT_EQ(buf.space, space);
    68     EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, CX_BUFFER_AUTO_EXTEND);
    69     EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
    70     EXPECT_EQ(buf.pos, 0);
    71     EXPECT_EQ(buf.size, 0);
    72     EXPECT_EQ(buf.capacity, 16);
    73     EXPECT_EQ(buf.allocator, &alloc);
    74     cxBufferDestroy(&buf);
    75     EXPECT_FALSE(alloc.verify());
    76     cxFree(&alloc, space);
    77     EXPECT_TRUE(alloc.verify());
    78 }
    80 TEST(BufferInit, WrapSpaceAutoFree) {
    81     CxTestingAllocator alloc;
    82     CxBuffer buf;
    83     void *space = cxMalloc(&alloc, 16);
    84     cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
    85     expect_default_flush_config(&buf);
    86     EXPECT_EQ(buf.space, space);
    87     EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
    88     EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
    89     EXPECT_EQ(buf.pos, 0);
    90     EXPECT_EQ(buf.size, 0);
    91     EXPECT_EQ(buf.capacity, 16);
    92     EXPECT_EQ(buf.allocator, &alloc);
    93     EXPECT_FALSE(alloc.verify());
    94     cxBufferDestroy(&buf);
    95     EXPECT_TRUE(alloc.verify());
    96 }
    98 TEST(BufferInit, FreshSpace) {
    99     CxTestingAllocator alloc;
   100     CxBuffer buf;
   101     cxBufferInit(&buf, nullptr, 8, &alloc, CX_BUFFER_DEFAULT);
   102     expect_default_flush_config(&buf);
   103     EXPECT_NE(buf.space, nullptr);
   104     EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
   105     EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
   106     EXPECT_EQ(buf.pos, 0);
   107     EXPECT_EQ(buf.size, 0);
   108     EXPECT_EQ(buf.capacity, 8);
   109     EXPECT_EQ(buf.allocator, &alloc);
   110     EXPECT_FALSE(alloc.verify()); // space is still allocated
   111     cxBufferDestroy(&buf);
   112     EXPECT_TRUE(alloc.verify());
   113 }
   115 class BufferShiftFixture : public ::testing::Test {
   116 protected:
   117     void SetUp() override {
   118         ASSERT_TRUE(alloc.verify());
   119         cxBufferInit(&buf, nullptr, 16, &alloc, CX_BUFFER_DEFAULT);
   120         memcpy(buf.space, "test____________", 16);
   121         buf.capacity = 8; // purposely pretend that the buffer has less capacity s.t. we can test beyond the range
   122         buf.pos = 4;
   123         buf.size = 4;
   124     }
   126     void TearDown() override {
   127         cxBufferDestroy(&buf);
   128         EXPECT_TRUE(alloc.verify());
   129     }
   131     CxTestingAllocator alloc;
   132     CxBuffer buf{};
   133 };
   135 class BufferShiftLeft : public BufferShiftFixture {
   136 };
   138 TEST_F(BufferShiftLeft, Zero) {
   139     ASSERT_EQ(buf.pos, 4);
   140     ASSERT_EQ(buf.size, 4);
   141     int ret = cxBufferShiftLeft(&buf, 0);
   142     EXPECT_EQ(ret, 0);
   143     EXPECT_EQ(buf.pos, 4);
   144     EXPECT_EQ(buf.size, 4);
   145     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   146 }
   148 TEST_F(BufferShiftLeft, ZeroOffsetInterface) {
   149     ASSERT_EQ(buf.pos, 4);
   150     ASSERT_EQ(buf.size, 4);
   151     int ret = cxBufferShift(&buf, -0);
   152     EXPECT_EQ(ret, 0);
   153     EXPECT_EQ(buf.pos, 4);
   154     EXPECT_EQ(buf.size, 4);
   155     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   156 }
   158 TEST_F(BufferShiftLeft, Standard) {
   159     ASSERT_EQ(buf.pos, 4);
   160     ASSERT_EQ(buf.size, 4);
   161     int ret = cxBufferShiftLeft(&buf, 2);
   162     EXPECT_EQ(ret, 0);
   163     EXPECT_EQ(buf.pos, 2);
   164     EXPECT_EQ(buf.size, 2);
   165     EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
   166 }
   168 TEST_F(BufferShiftLeft, Overshift) {
   169     ASSERT_LT(buf.pos, 6);
   170     ASSERT_LT(buf.size, 6);
   171     int ret = cxBufferShiftLeft(&buf, 6);
   172     EXPECT_EQ(ret, 0);
   173     EXPECT_EQ(buf.pos, 0);
   174     EXPECT_EQ(buf.size, 0);
   175     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   176 }
   178 TEST_F(BufferShiftLeft, OvershiftPosOnly) {
   179     buf.pos = 2;
   180     ASSERT_EQ(buf.size, 4);
   181     int ret = cxBufferShiftLeft(&buf, 3);
   182     EXPECT_EQ(ret, 0);
   183     EXPECT_EQ(buf.pos, 0);
   184     EXPECT_EQ(buf.size, 1);
   185     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   186 }
   188 TEST_F(BufferShiftLeft, OffsetInterface) {
   189     buf.pos = 3;
   190     ASSERT_EQ(buf.size, 4);
   191     int ret = cxBufferShift(&buf, -2);
   192     EXPECT_EQ(ret, 0);
   193     EXPECT_EQ(buf.pos, 1);
   194     EXPECT_EQ(buf.size, 2);
   195     EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
   196 }
   198 class BufferShiftRight : public BufferShiftFixture {
   199 };
   201 TEST_F(BufferShiftRight, Zero) {
   202     ASSERT_EQ(buf.pos, 4);
   203     ASSERT_EQ(buf.size, 4);
   204     int ret = cxBufferShiftRight(&buf, 0);
   205     EXPECT_EQ(ret, 0);
   206     EXPECT_EQ(buf.pos, 4);
   207     EXPECT_EQ(buf.size, 4);
   208     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   209 }
   211 TEST_F(BufferShiftRight, ZeroOffsetInterface) {
   212     ASSERT_EQ(buf.pos, 4);
   213     ASSERT_EQ(buf.size, 4);
   214     int ret = cxBufferShift(&buf, +0);
   215     EXPECT_EQ(ret, 0);
   216     EXPECT_EQ(buf.pos, 4);
   217     EXPECT_EQ(buf.size, 4);
   218     EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
   219 }
   221 TEST_F(BufferShiftRight, Standard) {
   222     ASSERT_EQ(buf.pos, 4);
   223     ASSERT_EQ(buf.size, 4);
   224     int ret = cxBufferShiftRight(&buf, 3);
   225     EXPECT_EQ(ret, 0);
   226     EXPECT_EQ(buf.pos, 7);
   227     EXPECT_EQ(buf.size, 7);
   228     EXPECT_TRUE(memcmp(buf.space, "testest_____", 8) == 0);
   229 }
   231 TEST_F(BufferShiftRight, OvershiftDiscard) {
   232     ASSERT_EQ(buf.pos, 4);
   233     ASSERT_EQ(buf.size, 4);
   234     ASSERT_EQ(buf.capacity, 8);
   235     int ret = cxBufferShiftRight(&buf, 6);
   236     EXPECT_EQ(ret, 0);
   237     EXPECT_EQ(buf.pos, 8);
   238     EXPECT_EQ(buf.size, 8);
   239     EXPECT_EQ(buf.capacity, 8);
   240     EXPECT_TRUE(memcmp(buf.space, "test__te____", 8) == 0);
   241 }
   243 TEST_F(BufferShiftRight, OvershiftExtend) {
   244     ASSERT_EQ(buf.pos, 4);
   245     ASSERT_EQ(buf.size, 4);
   246     ASSERT_EQ(buf.capacity, 8);
   247     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   248     int ret = cxBufferShiftRight(&buf, 6);
   249     EXPECT_EQ(ret, 0);
   250     EXPECT_EQ(buf.pos, 10);
   251     EXPECT_EQ(buf.size, 10);
   252     EXPECT_GE(buf.capacity, 10);
   253     EXPECT_TRUE(memcmp(buf.space, "test__test__", 8) == 0);
   254 }
   256 TEST_F(BufferShiftRight, OffsetInterface) {
   257     buf.pos = 3;
   258     ASSERT_EQ(buf.size, 4);
   259     int ret = cxBufferShift(&buf, 2);
   260     EXPECT_EQ(ret, 0);
   261     EXPECT_EQ(buf.pos, 5);
   262     EXPECT_EQ(buf.size, 6);
   263     EXPECT_TRUE(memcmp(buf.space, "tetest______", 8) == 0);
   264 }
   266 TEST(BufferMinimumCapacity, Sufficient) {
   267     CxTestingAllocator alloc;
   268     auto space = cxMalloc(&alloc, 8);
   269     CxBuffer buf;
   270     cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS);
   271     memcpy(space, "Testing", 8);
   272     buf.size = 8;
   273     cxBufferMinimumCapacity(&buf, 6);
   274     EXPECT_EQ(buf.capacity, 8);
   275     EXPECT_EQ(buf.size, 8);
   276     EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
   277     cxBufferDestroy(&buf);
   278     EXPECT_TRUE(alloc.verify());
   279 }
   281 TEST(BufferMinimumCapacity, Extend) {
   282     CxTestingAllocator alloc;
   283     auto space = cxMalloc(&alloc, 8);
   284     CxBuffer buf;
   285     cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
   286     memcpy(space, "Testing", 8);
   287     buf.size = 8;
   288     cxBufferMinimumCapacity(&buf, 16);
   289     EXPECT_EQ(buf.capacity, 16);
   290     EXPECT_EQ(buf.size, 8);
   291     EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
   292     cxBufferDestroy(&buf);
   293     EXPECT_TRUE(alloc.verify());
   294 }
   296 TEST(BufferClear, Test) {
   297     char space[16];
   298     strcpy(space, "clear test");
   299     CxBuffer buf;
   300     cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
   301     ASSERT_EQ(buf.size, 0);
   302     // only clear the used part of the buffer
   303     cxBufferClear(&buf);
   304     EXPECT_EQ(memcmp(space, "clear test", 10), 0);
   305     buf.size = 5;
   306     buf.pos = 3;
   307     cxBufferClear(&buf);
   308     EXPECT_EQ(memcmp(space, "\0\0\0\0\0 test", 10), 0);
   309     EXPECT_EQ(buf.size, 0);
   310     EXPECT_EQ(buf.pos, 0);
   311     cxBufferDestroy(&buf);
   312 }
   314 class BufferWrite : public ::testing::Test {
   315 protected:
   316     CxBuffer buf{}, target{};
   318     void SetUp() override {
   319         cxBufferInit(&target, nullptr, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
   320         cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
   321         buf.capacity = 8; // artificially reduce capacity to check OOB writes
   322         memset(buf.space, 0, 16);
   323         memcpy(buf.space, "prep", 4);
   324         buf.size = buf.pos = 4;
   325     }
   327     void TearDown() override {
   328         cxBufferDestroy(&buf);
   329         cxBufferDestroy(&target);
   330     }
   332     void enableFlushing() {
   333         buf.flush_target = &target;
   334         buf.flush_func = reinterpret_cast<cx_write_func>(cxBufferWrite);
   335         buf.flush_blkmax = 1;
   336     }
   337 };
   339 TEST_F(BufferWrite, SizeOneFit) {
   340     const char *data = "test";
   341     ASSERT_EQ(buf.capacity, 8);
   342     ASSERT_EQ(buf.pos, 4);
   343     ASSERT_EQ(buf.size, 4);
   344     size_t written = cxBufferWrite(data, 1, 4, &buf);
   345     EXPECT_EQ(written, 4);
   346     EXPECT_EQ(buf.size, 8);
   347     EXPECT_EQ(buf.pos, 8);
   348     EXPECT_EQ(buf.capacity, 8);
   349     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
   350 }
   352 TEST_F(BufferWrite, SizeOneDiscard) {
   353     const char *data = "testing";
   354     ASSERT_EQ(buf.capacity, 8);
   355     ASSERT_EQ(buf.pos, 4);
   356     ASSERT_EQ(buf.size, 4);
   357     size_t written = cxBufferWrite(data, 1, 7, &buf);
   358     EXPECT_EQ(written, 4);
   359     EXPECT_EQ(buf.size, 8);
   360     EXPECT_EQ(buf.pos, 8);
   361     EXPECT_EQ(buf.capacity, 8);
   362     EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
   363 }
   365 TEST_F(BufferWrite, SizeOneExtend) {
   366     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   367     const char *data = "testing";
   368     ASSERT_EQ(buf.capacity, 8);
   369     ASSERT_EQ(buf.pos, 4);
   370     ASSERT_EQ(buf.size, 4);
   371     size_t written = cxBufferWrite(data, 1, 7, &buf);
   372     EXPECT_EQ(written, 7);
   373     EXPECT_EQ(buf.size, 11);
   374     EXPECT_EQ(buf.pos, 11);
   375     EXPECT_GE(buf.capacity, 11);
   376     EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
   377 }
   379 TEST_F(BufferWrite, MultibyteFit) {
   380     const char *data = "test";
   381     ASSERT_EQ(buf.capacity, 8);
   382     ASSERT_EQ(buf.pos, 4);
   383     ASSERT_EQ(buf.size, 4);
   384     size_t written = cxBufferWrite(data, 2, 2, &buf);
   385     EXPECT_EQ(written, 2);
   386     EXPECT_EQ(buf.size, 8);
   387     EXPECT_EQ(buf.pos, 8);
   388     EXPECT_EQ(buf.capacity, 8);
   389     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
   390 }
   392 TEST_F(BufferWrite, MultibyteDiscard) {
   393     const char *data = "testing";
   394     ASSERT_EQ(buf.capacity, 8);
   395     ASSERT_EQ(buf.size, 4);
   396     buf.pos = 3;
   397     size_t written = cxBufferWrite(data, 2, 4, &buf);
   398     // remember: whole elements are discarded if they do not fit
   399     EXPECT_EQ(written, 2);
   400     EXPECT_EQ(buf.size, 7);
   401     EXPECT_EQ(buf.pos, 7);
   402     EXPECT_EQ(buf.capacity, 8);
   403     EXPECT_EQ(memcmp(buf.space, "pretest\0", 8), 0);
   404 }
   406 TEST_F(BufferWrite, MultibyteExtend) {
   407     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   408     const char *data = "tester";
   409     ASSERT_EQ(buf.capacity, 8);
   410     ASSERT_EQ(buf.size, 4);
   411     buf.pos = 3;
   412     size_t written = cxBufferWrite(data, 2, 3, &buf);
   413     // remember: whole elements are discarded if they do not fit
   414     EXPECT_EQ(written, 3);
   415     EXPECT_EQ(buf.size, 9);
   416     EXPECT_EQ(buf.pos, 9);
   417     EXPECT_GE(buf.capacity, 9);
   418     EXPECT_EQ(memcmp(buf.space, "pretester\0", 10), 0);
   419 }
   421 TEST_F(BufferWrite, PutcWrapperFit) {
   422     ASSERT_EQ(buf.capacity, 8);
   423     ASSERT_EQ(buf.pos, 4);
   424     ASSERT_EQ(buf.size, 4);
   425     int c = cxBufferPut(&buf, 0x20 | 'a');
   426     EXPECT_EQ(c, 'a');
   427     EXPECT_EQ(buf.size, 5);
   428     EXPECT_EQ(buf.pos, 5);
   429     EXPECT_EQ(buf.capacity, 8);
   430     EXPECT_EQ(memcmp(buf.space, "prepa\0", 6), 0);
   431 }
   433 TEST_F(BufferWrite, PutcWrapperDiscard) {
   434     ASSERT_EQ(buf.capacity, 8);
   435     ASSERT_EQ(buf.size, 4);
   436     buf.pos = 8;
   437     int c = cxBufferPut(&buf, 0x20 | 'a');
   438     EXPECT_EQ(c, EOF);
   439     EXPECT_EQ(buf.size, 4);
   440     EXPECT_EQ(buf.pos, 8);
   441     EXPECT_EQ(buf.capacity, 8);
   442     EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0\0", 9), 0);
   443 }
   445 TEST_F(BufferWrite, PutcWrapperExtend) {
   446     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   447     ASSERT_EQ(buf.capacity, 8);
   448     ASSERT_EQ(buf.size, 4);
   449     buf.pos = 8;
   450     int c = cxBufferPut(&buf, 0x20 | 'a');
   451     EXPECT_EQ(c, 'a');
   452     EXPECT_EQ(buf.size, 9);
   453     EXPECT_EQ(buf.pos, 9);
   454     EXPECT_GE(buf.capacity, 9);
   455     EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0a\0", 10), 0);
   456 }
   458 TEST_F(BufferWrite, PutStringWrapperFit) {
   459     const char *data = "test";
   460     ASSERT_EQ(buf.capacity, 8);
   461     ASSERT_EQ(buf.pos, 4);
   462     ASSERT_EQ(buf.size, 4);
   463     size_t written = cxBufferPutString(&buf, data);
   464     EXPECT_EQ(written, 4);
   465     EXPECT_EQ(buf.size, 8);
   466     EXPECT_EQ(buf.pos, 8);
   467     EXPECT_EQ(buf.capacity, 8);
   468     EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
   469 }
   471 TEST_F(BufferWrite, PutStringWrapperDiscard) {
   472     const char *data = "testing";
   473     ASSERT_EQ(buf.capacity, 8);
   474     ASSERT_EQ(buf.pos, 4);
   475     ASSERT_EQ(buf.size, 4);
   476     size_t written = cxBufferPutString(&buf, data);
   477     EXPECT_EQ(written, 4);
   478     EXPECT_EQ(buf.size, 8);
   479     EXPECT_EQ(buf.pos, 8);
   480     EXPECT_EQ(buf.capacity, 8);
   481     EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
   482 }
   484 TEST_F(BufferWrite, PutStringWrapperExtend) {
   485     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   486     const char *data = "testing";
   487     ASSERT_EQ(buf.capacity, 8);
   488     ASSERT_EQ(buf.pos, 4);
   489     ASSERT_EQ(buf.size, 4);
   490     size_t written = cxBufferPutString(&buf, data);
   491     EXPECT_EQ(written, 7);
   492     EXPECT_EQ(buf.size, 11);
   493     EXPECT_EQ(buf.pos, 11);
   494     EXPECT_GE(buf.capacity, 11);
   495     EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
   496 }
   498 TEST_F(BufferWrite, MultOverflow) {
   499     const char *data = "testing";
   500     ASSERT_EQ(buf.capacity, 8);
   501     ASSERT_EQ(buf.pos, 4);
   502     ASSERT_EQ(buf.size, 4);
   503     size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf);
   504     EXPECT_EQ(written, 0);
   505     EXPECT_EQ(buf.capacity, 8);
   506     EXPECT_EQ(buf.pos, 4);
   507     EXPECT_EQ(buf.size, 4);
   508     EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
   509 }
   511 TEST_F(BufferWrite, MaxCapaOverflow) {
   512     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   513     const char *data = "testing";
   514     ASSERT_EQ(buf.capacity, 8);
   515     ASSERT_EQ(buf.pos, 4);
   516     ASSERT_EQ(buf.size, 4);
   517     size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf);
   518     EXPECT_EQ(written, 0);
   519     EXPECT_EQ(buf.capacity, 8);
   520     EXPECT_EQ(buf.pos, 4);
   521     EXPECT_EQ(buf.size, 4);
   522     EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
   523 }
   525 TEST_F(BufferWrite, OnlyOverwrite) {
   526     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   527     ASSERT_EQ(buf.capacity, 8);
   528     memcpy(buf.space, "preptest", 8);
   529     buf.pos = 3;
   530     buf.size = 8;
   531     size_t written = cxBufferWrite("XXX", 2, 2, &buf);
   532     EXPECT_EQ(written, 2);
   533     EXPECT_EQ(buf.capacity, 8);
   534     EXPECT_EQ(buf.size, 8);
   535     EXPECT_EQ(buf.pos, 7);
   536     EXPECT_EQ(memcmp(buf.space, "preXXX\0t", 8), 0);
   537 }
   539 TEST_F(BufferWrite, FlushAtCapacity) {
   540     enableFlushing();
   541     ASSERT_EQ(buf.capacity, 8);
   542     ASSERT_EQ(buf.pos, 4);
   543     size_t written = cxBufferWrite("foo", 1, 3, &buf);
   544     EXPECT_EQ(written, 3);
   545     ASSERT_EQ(buf.pos, 7);
   546     ASSERT_EQ(buf.size, 7);
   547     ASSERT_EQ(target.pos, 0);
   548     ASSERT_EQ(target.size, 0);
   549     written = cxBufferWrite("hello", 1, 5, &buf);
   550     EXPECT_EQ(written, 5);
   551     EXPECT_EQ(buf.pos, 0);
   552     EXPECT_EQ(buf.size, 0);
   553     EXPECT_EQ(buf.capacity, 8);
   554     EXPECT_EQ(target.pos, 12);
   555     ASSERT_EQ(target.size, 12);
   556     EXPECT_EQ(memcmp(target.space, "prepfoohello", 12), 0);
   557 }
   559 TEST_F(BufferWrite, FlushAtThreshold) {
   560     enableFlushing();
   561     buf.flush_threshold = 12;
   562     buf.flags |= CX_BUFFER_AUTO_EXTEND;
   563     ASSERT_EQ(buf.capacity, 8);
   564     ASSERT_EQ(buf.pos, 4);
   565     size_t written = cxBufferWrite("foobar", 1, 6, &buf);
   566     EXPECT_EQ(written, 6);
   567     ASSERT_EQ(buf.pos, 10);
   568     ASSERT_EQ(buf.size, 10);
   569     ASSERT_GE(buf.capacity, 10);
   570     ASSERT_LE(buf.capacity, 12);
   571     ASSERT_EQ(target.pos, 0);
   572     ASSERT_EQ(target.size, 0);
   573     written = cxBufferWrite("hello", 1, 5, &buf);
   574     EXPECT_EQ(written, 5);
   575     EXPECT_EQ(buf.pos, 0);
   576     EXPECT_EQ(buf.size, 0);
   577     EXPECT_LE(buf.capacity, 12);
   578     EXPECT_EQ(target.pos, 15);
   579     ASSERT_EQ(target.size, 15);
   580     EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0);
   581 }
   583 class BufferSeek : public ::testing::Test {
   584 protected:
   585     void SetUp() override {
   586         cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
   587         buf.size = 6;
   588         buf.pos = 3;
   589     }
   591     void TearDown() override {
   592         cxBufferDestroy(&buf);
   593     }
   595     CxBuffer buf{};
   596 };
   598 TEST_F(BufferSeek, SetZero) {
   599     int result = cxBufferSeek(&buf, 0, SEEK_SET);
   600     EXPECT_EQ(result, 0);
   601     EXPECT_EQ(buf.pos, 0);
   602 }
   604 TEST_F(BufferSeek, SetValid) {
   605     int result = cxBufferSeek(&buf, 5, SEEK_SET);
   606     EXPECT_EQ(result, 0);
   607     EXPECT_EQ(buf.pos, 5);
   608 }
   610 TEST_F(BufferSeek, SetInvalid) {
   611     ASSERT_EQ(buf.pos, 3);
   612     int result = cxBufferSeek(&buf, 6, SEEK_SET);
   613     EXPECT_NE(result, 0);
   614     EXPECT_EQ(buf.pos, 3);
   615 }
   617 TEST_F(BufferSeek, CurZero) {
   618     ASSERT_EQ(buf.pos, 3);
   619     int result = cxBufferSeek(&buf, 0, SEEK_CUR);
   620     EXPECT_EQ(result, 0);
   621     EXPECT_EQ(buf.pos, 3);
   622 }
   624 TEST_F(BufferSeek, CurValidPositive) {
   625     ASSERT_EQ(buf.pos, 3);
   626     int result = cxBufferSeek(&buf, 2, SEEK_CUR);
   627     EXPECT_EQ(result, 0);
   628     EXPECT_EQ(buf.pos, 5);
   629 }
   631 TEST_F(BufferSeek, CurValidNegative) {
   632     ASSERT_EQ(buf.pos, 3);
   633     int result = cxBufferSeek(&buf, -3, SEEK_CUR);
   634     EXPECT_EQ(result, 0);
   635     EXPECT_EQ(buf.pos, 0);
   636 }
   638 TEST_F(BufferSeek, CurInvalidPositive) {
   639     ASSERT_EQ(buf.pos, 3);
   640     int result = cxBufferSeek(&buf, 3, SEEK_CUR);
   641     EXPECT_NE(result, 0);
   642     EXPECT_EQ(buf.pos, 3);
   643 }
   645 TEST_F(BufferSeek, CurInvalidNegative) {
   646     ASSERT_EQ(buf.pos, 3);
   647     int result = cxBufferSeek(&buf, -4, SEEK_CUR);
   648     EXPECT_NE(result, 0);
   649     EXPECT_EQ(buf.pos, 3);
   650 }
   652 TEST_F(BufferSeek, EndZero) {
   653     ASSERT_EQ(buf.size, 6);
   654     int result = cxBufferSeek(&buf, 0, SEEK_END);
   655     // the (past-the-)end position is always invalid
   656     EXPECT_NE(result, 0);
   657     EXPECT_EQ(buf.pos, 3);
   658 }
   660 TEST_F(BufferSeek, EndValid) {
   661     ASSERT_EQ(buf.size, 6);
   662     int result = cxBufferSeek(&buf, -6, SEEK_END);
   663     EXPECT_EQ(result, 0);
   664     EXPECT_EQ(buf.pos, 0);
   665 }
   667 TEST_F(BufferSeek, EndInvalid) {
   668     ASSERT_EQ(buf.size, 6);
   669     int result = cxBufferSeek(&buf, 1, SEEK_END);
   670     EXPECT_NE(result, 0);
   671     EXPECT_EQ(buf.pos, 3);
   672 }
   674 TEST_F(BufferSeek, WhenceInvalid) {
   675     ASSERT_EQ(buf.size, 6);
   676     ASSERT_EQ(buf.pos, 3);
   677     int result = cxBufferSeek(&buf, 2, 9000);
   678     EXPECT_NE(result, 0);
   679     EXPECT_EQ(buf.size, 6);
   680     EXPECT_EQ(buf.pos, 3);
   681 }

mercurial