tests/test_buffer.cpp

Mon, 18 Dec 2023 15:13:26 +0100

author
Mike Becker <universe@uap-core.de>
date
Mon, 18 Dec 2023 15:13:26 +0100
changeset 761
61d5197d612b
parent 683
aa0d09f2d81c
child 789
9b2f5661bebd
permissions
-rw-r--r--

add cxBufferReset() - resolves #338

universe@530 1 /*
universe@530 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@530 3 *
universe@530 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
universe@530 5 *
universe@530 6 * Redistribution and use in source and binary forms, with or without
universe@530 7 * modification, are permitted provided that the following conditions are met:
universe@530 8 *
universe@530 9 * 1. Redistributions of source code must retain the above copyright
universe@530 10 * notice, this list of conditions and the following disclaimer.
universe@530 11 *
universe@530 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@530 13 * notice, this list of conditions and the following disclaimer in the
universe@530 14 * documentation and/or other materials provided with the distribution.
universe@530 15 *
universe@530 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@530 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@530 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@530 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@530 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@530 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@530 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@530 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@530 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@530 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@530 26 * POSSIBILITY OF SUCH DAMAGE.
universe@530 27 */
universe@530 28
universe@530 29 #include "cx/buffer.h"
universe@530 30
universe@530 31 #include <gtest/gtest.h>
universe@530 32 #include "util_allocator.h"
universe@530 33
universe@548 34 class BufferFixture : public ::testing::Test {
universe@548 35 protected:
universe@548 36 void SetUp() override {
universe@548 37 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@548 38 buf.size = 6;
universe@548 39 buf.pos = 3;
universe@548 40 }
universe@548 41
universe@548 42 void TearDown() override {
universe@548 43 cxBufferDestroy(&buf);
universe@548 44 }
universe@548 45
universe@548 46 CxBuffer buf{};
universe@548 47 };
universe@548 48
universe@539 49 static void expect_default_flush_config(CxBuffer *buf) {
universe@539 50 EXPECT_EQ(buf->flush_blkmax, 0);
universe@539 51 EXPECT_EQ(buf->flush_blksize, 4096);
universe@539 52 EXPECT_EQ(buf->flush_threshold, SIZE_MAX);
universe@539 53 EXPECT_EQ(buf->flush_func, nullptr);
universe@541 54 EXPECT_EQ(buf->flush_target, nullptr);
universe@539 55 }
universe@539 56
universe@535 57 TEST(BufferInit, WrapSpace) {
universe@535 58 CxTestingAllocator alloc;
universe@530 59 CxBuffer buf;
universe@535 60 void *space = cxMalloc(&alloc, 16);
universe@535 61 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_DEFAULT);
universe@539 62 expect_default_flush_config(&buf);
universe@530 63 EXPECT_EQ(buf.space, space);
universe@530 64 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 65 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@530 66 EXPECT_EQ(buf.pos, 0);
universe@530 67 EXPECT_EQ(buf.size, 0);
universe@530 68 EXPECT_EQ(buf.capacity, 16);
universe@535 69 EXPECT_EQ(buf.allocator, &alloc);
universe@530 70 cxBufferDestroy(&buf);
universe@535 71 EXPECT_FALSE(alloc.verify());
universe@535 72 cxFree(&alloc, space);
universe@535 73 EXPECT_TRUE(alloc.verify());
universe@530 74 }
universe@530 75
universe@539 76 TEST(BufferInit, WrapSpaceAutoExtend) {
universe@539 77 CxTestingAllocator alloc;
universe@539 78 CxBuffer buf;
universe@539 79 void *space = cxMalloc(&alloc, 16);
universe@539 80 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_AUTO_EXTEND);
universe@539 81 expect_default_flush_config(&buf);
universe@539 82 EXPECT_EQ(buf.space, space);
universe@539 83 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, CX_BUFFER_AUTO_EXTEND);
universe@539 84 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, 0);
universe@539 85 EXPECT_EQ(buf.pos, 0);
universe@539 86 EXPECT_EQ(buf.size, 0);
universe@539 87 EXPECT_EQ(buf.capacity, 16);
universe@539 88 EXPECT_EQ(buf.allocator, &alloc);
universe@539 89 cxBufferDestroy(&buf);
universe@539 90 EXPECT_FALSE(alloc.verify());
universe@539 91 cxFree(&alloc, space);
universe@539 92 EXPECT_TRUE(alloc.verify());
universe@539 93 }
universe@539 94
universe@535 95 TEST(BufferInit, WrapSpaceAutoFree) {
universe@535 96 CxTestingAllocator alloc;
universe@530 97 CxBuffer buf;
universe@535 98 void *space = cxMalloc(&alloc, 16);
universe@535 99 cxBufferInit(&buf, space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@539 100 expect_default_flush_config(&buf);
universe@530 101 EXPECT_EQ(buf.space, space);
universe@530 102 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@530 103 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@530 104 EXPECT_EQ(buf.pos, 0);
universe@530 105 EXPECT_EQ(buf.size, 0);
universe@530 106 EXPECT_EQ(buf.capacity, 16);
universe@535 107 EXPECT_EQ(buf.allocator, &alloc);
universe@535 108 EXPECT_FALSE(alloc.verify());
universe@530 109 cxBufferDestroy(&buf);
universe@535 110 EXPECT_TRUE(alloc.verify());
universe@530 111 }
universe@535 112
universe@535 113 TEST(BufferInit, FreshSpace) {
universe@535 114 CxTestingAllocator alloc;
universe@535 115 CxBuffer buf;
universe@535 116 cxBufferInit(&buf, nullptr, 8, &alloc, CX_BUFFER_DEFAULT);
universe@539 117 expect_default_flush_config(&buf);
universe@535 118 EXPECT_NE(buf.space, nullptr);
universe@535 119 EXPECT_EQ(buf.flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@535 120 EXPECT_EQ(buf.flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@535 121 EXPECT_EQ(buf.pos, 0);
universe@535 122 EXPECT_EQ(buf.size, 0);
universe@535 123 EXPECT_EQ(buf.capacity, 8);
universe@535 124 EXPECT_EQ(buf.allocator, &alloc);
universe@535 125 EXPECT_FALSE(alloc.verify()); // space is still allocated
universe@535 126 cxBufferDestroy(&buf);
universe@535 127 EXPECT_TRUE(alloc.verify());
universe@535 128 }
universe@535 129
universe@683 130 TEST(BufferInit, OnHeap) {
universe@683 131 CxTestingAllocator alloc;
universe@683 132 CxBuffer *buf;
universe@683 133 void *space = cxMalloc(&alloc, 16);
universe@683 134 buf = cxBufferCreate(space, 16, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@683 135 EXPECT_NE(buf, nullptr);
universe@683 136 expect_default_flush_config(buf);
universe@683 137 EXPECT_EQ(buf->space, space);
universe@683 138 EXPECT_EQ(buf->flags & CX_BUFFER_AUTO_EXTEND, 0);
universe@683 139 EXPECT_EQ(buf->flags & CX_BUFFER_FREE_CONTENTS, CX_BUFFER_FREE_CONTENTS);
universe@683 140 EXPECT_EQ(buf->pos, 0);
universe@683 141 EXPECT_EQ(buf->size, 0);
universe@683 142 EXPECT_EQ(buf->capacity, 16);
universe@683 143 EXPECT_EQ(buf->allocator, &alloc);
universe@683 144 cxBufferFree(buf);
universe@683 145 EXPECT_TRUE(alloc.verify());
universe@683 146 }
universe@683 147
universe@535 148 class BufferShiftFixture : public ::testing::Test {
universe@535 149 protected:
universe@535 150 void SetUp() override {
universe@535 151 ASSERT_TRUE(alloc.verify());
universe@535 152 cxBufferInit(&buf, nullptr, 16, &alloc, CX_BUFFER_DEFAULT);
universe@535 153 memcpy(buf.space, "test____________", 16);
universe@535 154 buf.capacity = 8; // purposely pretend that the buffer has less capacity s.t. we can test beyond the range
universe@535 155 buf.pos = 4;
universe@535 156 buf.size = 4;
universe@535 157 }
universe@535 158
universe@535 159 void TearDown() override {
universe@535 160 cxBufferDestroy(&buf);
universe@535 161 EXPECT_TRUE(alloc.verify());
universe@535 162 }
universe@535 163
universe@535 164 CxTestingAllocator alloc;
universe@535 165 CxBuffer buf{};
universe@535 166 };
universe@535 167
universe@535 168 class BufferShiftLeft : public BufferShiftFixture {
universe@535 169 };
universe@535 170
universe@535 171 TEST_F(BufferShiftLeft, Zero) {
universe@535 172 ASSERT_EQ(buf.pos, 4);
universe@535 173 ASSERT_EQ(buf.size, 4);
universe@535 174 int ret = cxBufferShiftLeft(&buf, 0);
universe@535 175 EXPECT_EQ(ret, 0);
universe@535 176 EXPECT_EQ(buf.pos, 4);
universe@535 177 EXPECT_EQ(buf.size, 4);
universe@535 178 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 179 }
universe@535 180
universe@547 181 TEST_F(BufferShiftLeft, ZeroOffsetInterface) {
universe@547 182 ASSERT_EQ(buf.pos, 4);
universe@547 183 ASSERT_EQ(buf.size, 4);
universe@547 184 int ret = cxBufferShift(&buf, -0);
universe@547 185 EXPECT_EQ(ret, 0);
universe@547 186 EXPECT_EQ(buf.pos, 4);
universe@547 187 EXPECT_EQ(buf.size, 4);
universe@547 188 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@547 189 }
universe@547 190
universe@535 191 TEST_F(BufferShiftLeft, Standard) {
universe@535 192 ASSERT_EQ(buf.pos, 4);
universe@535 193 ASSERT_EQ(buf.size, 4);
universe@535 194 int ret = cxBufferShiftLeft(&buf, 2);
universe@535 195 EXPECT_EQ(ret, 0);
universe@535 196 EXPECT_EQ(buf.pos, 2);
universe@535 197 EXPECT_EQ(buf.size, 2);
universe@535 198 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 199 }
universe@535 200
universe@535 201 TEST_F(BufferShiftLeft, Overshift) {
universe@535 202 ASSERT_LT(buf.pos, 6);
universe@535 203 ASSERT_LT(buf.size, 6);
universe@535 204 int ret = cxBufferShiftLeft(&buf, 6);
universe@535 205 EXPECT_EQ(ret, 0);
universe@535 206 EXPECT_EQ(buf.pos, 0);
universe@535 207 EXPECT_EQ(buf.size, 0);
universe@535 208 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 209 }
universe@535 210
universe@535 211 TEST_F(BufferShiftLeft, OvershiftPosOnly) {
universe@535 212 buf.pos = 2;
universe@535 213 ASSERT_EQ(buf.size, 4);
universe@535 214 int ret = cxBufferShiftLeft(&buf, 3);
universe@535 215 EXPECT_EQ(ret, 0);
universe@535 216 EXPECT_EQ(buf.pos, 0);
universe@535 217 EXPECT_EQ(buf.size, 1);
universe@535 218 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 219 }
universe@535 220
universe@535 221 TEST_F(BufferShiftLeft, OffsetInterface) {
universe@535 222 buf.pos = 3;
universe@535 223 ASSERT_EQ(buf.size, 4);
universe@535 224 int ret = cxBufferShift(&buf, -2);
universe@535 225 EXPECT_EQ(ret, 0);
universe@535 226 EXPECT_EQ(buf.pos, 1);
universe@535 227 EXPECT_EQ(buf.size, 2);
universe@535 228 EXPECT_TRUE(memcmp(buf.space, "stst________", 8) == 0);
universe@535 229 }
universe@535 230
universe@535 231 class BufferShiftRight : public BufferShiftFixture {
universe@535 232 };
universe@535 233
universe@535 234 TEST_F(BufferShiftRight, Zero) {
universe@535 235 ASSERT_EQ(buf.pos, 4);
universe@535 236 ASSERT_EQ(buf.size, 4);
universe@535 237 int ret = cxBufferShiftRight(&buf, 0);
universe@535 238 EXPECT_EQ(ret, 0);
universe@535 239 EXPECT_EQ(buf.pos, 4);
universe@535 240 EXPECT_EQ(buf.size, 4);
universe@535 241 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@535 242 }
universe@535 243
universe@547 244 TEST_F(BufferShiftRight, ZeroOffsetInterface) {
universe@547 245 ASSERT_EQ(buf.pos, 4);
universe@547 246 ASSERT_EQ(buf.size, 4);
universe@547 247 int ret = cxBufferShift(&buf, +0);
universe@547 248 EXPECT_EQ(ret, 0);
universe@547 249 EXPECT_EQ(buf.pos, 4);
universe@547 250 EXPECT_EQ(buf.size, 4);
universe@547 251 EXPECT_TRUE(memcmp(buf.space, "test________", 8) == 0);
universe@547 252 }
universe@547 253
universe@535 254 TEST_F(BufferShiftRight, Standard) {
universe@535 255 ASSERT_EQ(buf.pos, 4);
universe@535 256 ASSERT_EQ(buf.size, 4);
universe@535 257 int ret = cxBufferShiftRight(&buf, 3);
universe@535 258 EXPECT_EQ(ret, 0);
universe@535 259 EXPECT_EQ(buf.pos, 7);
universe@535 260 EXPECT_EQ(buf.size, 7);
universe@535 261 EXPECT_TRUE(memcmp(buf.space, "testest_____", 8) == 0);
universe@535 262 }
universe@535 263
universe@535 264 TEST_F(BufferShiftRight, OvershiftDiscard) {
universe@535 265 ASSERT_EQ(buf.pos, 4);
universe@535 266 ASSERT_EQ(buf.size, 4);
universe@535 267 ASSERT_EQ(buf.capacity, 8);
universe@535 268 int ret = cxBufferShiftRight(&buf, 6);
universe@535 269 EXPECT_EQ(ret, 0);
universe@535 270 EXPECT_EQ(buf.pos, 8);
universe@535 271 EXPECT_EQ(buf.size, 8);
universe@535 272 EXPECT_EQ(buf.capacity, 8);
universe@535 273 EXPECT_TRUE(memcmp(buf.space, "test__te____", 8) == 0);
universe@535 274 }
universe@535 275
universe@535 276 TEST_F(BufferShiftRight, OvershiftExtend) {
universe@535 277 ASSERT_EQ(buf.pos, 4);
universe@535 278 ASSERT_EQ(buf.size, 4);
universe@535 279 ASSERT_EQ(buf.capacity, 8);
universe@535 280 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@535 281 int ret = cxBufferShiftRight(&buf, 6);
universe@535 282 EXPECT_EQ(ret, 0);
universe@535 283 EXPECT_EQ(buf.pos, 10);
universe@535 284 EXPECT_EQ(buf.size, 10);
universe@535 285 EXPECT_GE(buf.capacity, 10);
universe@535 286 EXPECT_TRUE(memcmp(buf.space, "test__test__", 8) == 0);
universe@535 287 }
universe@535 288
universe@535 289 TEST_F(BufferShiftRight, OffsetInterface) {
universe@535 290 buf.pos = 3;
universe@535 291 ASSERT_EQ(buf.size, 4);
universe@535 292 int ret = cxBufferShift(&buf, 2);
universe@535 293 EXPECT_EQ(ret, 0);
universe@535 294 EXPECT_EQ(buf.pos, 5);
universe@535 295 EXPECT_EQ(buf.size, 6);
universe@535 296 EXPECT_TRUE(memcmp(buf.space, "tetest______", 8) == 0);
universe@535 297 }
universe@535 298
universe@535 299 TEST(BufferMinimumCapacity, Sufficient) {
universe@535 300 CxTestingAllocator alloc;
universe@535 301 auto space = cxMalloc(&alloc, 8);
universe@535 302 CxBuffer buf;
universe@535 303 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS);
universe@535 304 memcpy(space, "Testing", 8);
universe@535 305 buf.size = 8;
universe@535 306 cxBufferMinimumCapacity(&buf, 6);
universe@535 307 EXPECT_EQ(buf.capacity, 8);
universe@535 308 EXPECT_EQ(buf.size, 8);
universe@535 309 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 310 cxBufferDestroy(&buf);
universe@535 311 EXPECT_TRUE(alloc.verify());
universe@535 312 }
universe@535 313
universe@535 314 TEST(BufferMinimumCapacity, Extend) {
universe@535 315 CxTestingAllocator alloc;
universe@535 316 auto space = cxMalloc(&alloc, 8);
universe@535 317 CxBuffer buf;
universe@535 318 cxBufferInit(&buf, space, 8, &alloc, CX_BUFFER_FREE_CONTENTS); // NO auto extend!
universe@535 319 memcpy(space, "Testing", 8);
universe@535 320 buf.size = 8;
universe@535 321 cxBufferMinimumCapacity(&buf, 16);
universe@535 322 EXPECT_EQ(buf.capacity, 16);
universe@535 323 EXPECT_EQ(buf.size, 8);
universe@535 324 EXPECT_TRUE(memcmp(buf.space, "Testing", 8) == 0);
universe@535 325 cxBufferDestroy(&buf);
universe@535 326 EXPECT_TRUE(alloc.verify());
universe@535 327 }
universe@536 328
universe@536 329 TEST(BufferClear, Test) {
universe@536 330 char space[16];
universe@536 331 strcpy(space, "clear test");
universe@536 332 CxBuffer buf;
universe@536 333 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@536 334 ASSERT_EQ(buf.size, 0);
universe@536 335 // only clear the used part of the buffer
universe@536 336 cxBufferClear(&buf);
universe@536 337 EXPECT_EQ(memcmp(space, "clear test", 10), 0);
universe@536 338 buf.size = 5;
universe@536 339 buf.pos = 3;
universe@536 340 cxBufferClear(&buf);
universe@536 341 EXPECT_EQ(memcmp(space, "\0\0\0\0\0 test", 10), 0);
universe@536 342 EXPECT_EQ(buf.size, 0);
universe@536 343 EXPECT_EQ(buf.pos, 0);
universe@538 344 cxBufferDestroy(&buf);
universe@536 345 }
universe@538 346
universe@761 347 TEST(BufferReset, Test) {
universe@761 348 char space[16];
universe@761 349 strcpy(space, "reset test");
universe@761 350 CxBuffer buf;
universe@761 351 cxBufferInit(&buf, space, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@761 352 buf.size = 5;
universe@761 353 buf.pos = 3;
universe@761 354 cxBufferReset(&buf);
universe@761 355 EXPECT_EQ(memcmp(space, "reset test", 10), 0);
universe@761 356 EXPECT_EQ(buf.size, 0);
universe@761 357 EXPECT_EQ(buf.pos, 0);
universe@761 358 cxBufferDestroy(&buf);
universe@761 359 }
universe@761 360
universe@538 361 class BufferWrite : public ::testing::Test {
universe@538 362 protected:
universe@545 363 CxBuffer buf{}, target{};
universe@538 364
universe@538 365 void SetUp() override {
universe@545 366 cxBufferInit(&target, nullptr, 16, cxDefaultAllocator, CX_BUFFER_AUTO_EXTEND);
universe@538 367 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@538 368 buf.capacity = 8; // artificially reduce capacity to check OOB writes
universe@538 369 memset(buf.space, 0, 16);
universe@538 370 memcpy(buf.space, "prep", 4);
universe@538 371 buf.size = buf.pos = 4;
universe@538 372 }
universe@538 373
universe@538 374 void TearDown() override {
universe@538 375 cxBufferDestroy(&buf);
universe@545 376 cxBufferDestroy(&target);
universe@545 377 }
universe@545 378
universe@545 379 void enableFlushing() {
universe@545 380 buf.flush_target = &target;
universe@545 381 buf.flush_func = reinterpret_cast<cx_write_func>(cxBufferWrite);
universe@545 382 buf.flush_blkmax = 1;
universe@538 383 }
universe@538 384 };
universe@538 385
universe@567 386 static size_t mock_write_limited_rate(
universe@567 387 void const *ptr,
universe@567 388 size_t size,
universe@567 389 __attribute__((unused)) size_t nitems,
universe@567 390 CxBuffer *buffer
universe@567 391 ) {
universe@567 392 // simulate limited target drain capacity
universe@567 393 static bool full = false;
universe@567 394 if (full) {
universe@567 395 full = false;
universe@567 396 return 0;
universe@567 397 } else {
universe@567 398 full = true;
universe@567 399 return cxBufferWrite(ptr, size, nitems > 2 ? 2 : nitems, buffer);
universe@567 400 }
universe@567 401 }
universe@567 402
universe@538 403 TEST_F(BufferWrite, SizeOneFit) {
universe@538 404 const char *data = "test";
universe@538 405 ASSERT_EQ(buf.capacity, 8);
universe@538 406 ASSERT_EQ(buf.pos, 4);
universe@541 407 ASSERT_EQ(buf.size, 4);
universe@538 408 size_t written = cxBufferWrite(data, 1, 4, &buf);
universe@538 409 EXPECT_EQ(written, 4);
universe@538 410 EXPECT_EQ(buf.size, 8);
universe@538 411 EXPECT_EQ(buf.pos, 8);
universe@538 412 EXPECT_EQ(buf.capacity, 8);
universe@538 413 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 414 }
universe@538 415
universe@538 416 TEST_F(BufferWrite, SizeOneDiscard) {
universe@538 417 const char *data = "testing";
universe@538 418 ASSERT_EQ(buf.capacity, 8);
universe@538 419 ASSERT_EQ(buf.pos, 4);
universe@541 420 ASSERT_EQ(buf.size, 4);
universe@538 421 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 422 EXPECT_EQ(written, 4);
universe@538 423 EXPECT_EQ(buf.size, 8);
universe@538 424 EXPECT_EQ(buf.pos, 8);
universe@538 425 EXPECT_EQ(buf.capacity, 8);
universe@538 426 EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
universe@538 427 }
universe@538 428
universe@538 429 TEST_F(BufferWrite, SizeOneExtend) {
universe@538 430 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@538 431 const char *data = "testing";
universe@538 432 ASSERT_EQ(buf.capacity, 8);
universe@538 433 ASSERT_EQ(buf.pos, 4);
universe@541 434 ASSERT_EQ(buf.size, 4);
universe@538 435 size_t written = cxBufferWrite(data, 1, 7, &buf);
universe@538 436 EXPECT_EQ(written, 7);
universe@538 437 EXPECT_EQ(buf.size, 11);
universe@538 438 EXPECT_EQ(buf.pos, 11);
universe@538 439 EXPECT_GE(buf.capacity, 11);
universe@538 440 EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
universe@538 441 }
universe@538 442
universe@538 443 TEST_F(BufferWrite, MultibyteFit) {
universe@541 444 const char *data = "test";
universe@541 445 ASSERT_EQ(buf.capacity, 8);
universe@541 446 ASSERT_EQ(buf.pos, 4);
universe@541 447 ASSERT_EQ(buf.size, 4);
universe@541 448 size_t written = cxBufferWrite(data, 2, 2, &buf);
universe@541 449 EXPECT_EQ(written, 2);
universe@541 450 EXPECT_EQ(buf.size, 8);
universe@541 451 EXPECT_EQ(buf.pos, 8);
universe@541 452 EXPECT_EQ(buf.capacity, 8);
universe@541 453 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 454 }
universe@538 455
universe@538 456 TEST_F(BufferWrite, MultibyteDiscard) {
universe@542 457 const char *data = "testing";
universe@541 458 ASSERT_EQ(buf.capacity, 8);
universe@541 459 ASSERT_EQ(buf.size, 4);
universe@541 460 buf.pos = 3;
universe@542 461 size_t written = cxBufferWrite(data, 2, 4, &buf);
universe@538 462 // remember: whole elements are discarded if they do not fit
universe@541 463 EXPECT_EQ(written, 2);
universe@541 464 EXPECT_EQ(buf.size, 7);
universe@541 465 EXPECT_EQ(buf.pos, 7);
universe@541 466 EXPECT_EQ(buf.capacity, 8);
universe@541 467 EXPECT_EQ(memcmp(buf.space, "pretest\0", 8), 0);
universe@538 468 }
universe@538 469
universe@538 470 TEST_F(BufferWrite, MultibyteExtend) {
universe@541 471 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 472 const char *data = "tester";
universe@541 473 ASSERT_EQ(buf.capacity, 8);
universe@541 474 ASSERT_EQ(buf.size, 4);
universe@541 475 buf.pos = 3;
universe@541 476 size_t written = cxBufferWrite(data, 2, 3, &buf);
universe@541 477 // remember: whole elements are discarded if they do not fit
universe@541 478 EXPECT_EQ(written, 3);
universe@541 479 EXPECT_EQ(buf.size, 9);
universe@541 480 EXPECT_EQ(buf.pos, 9);
universe@541 481 EXPECT_GE(buf.capacity, 9);
universe@566 482 EXPECT_EQ(memcmp(buf.space, "pretester", 9), 0);
universe@538 483 }
universe@538 484
universe@538 485 TEST_F(BufferWrite, PutcWrapperFit) {
universe@541 486 ASSERT_EQ(buf.capacity, 8);
universe@541 487 ASSERT_EQ(buf.pos, 4);
universe@541 488 ASSERT_EQ(buf.size, 4);
universe@565 489 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 490 EXPECT_EQ(c, 'a');
universe@541 491 EXPECT_EQ(buf.size, 5);
universe@541 492 EXPECT_EQ(buf.pos, 5);
universe@541 493 EXPECT_EQ(buf.capacity, 8);
universe@541 494 EXPECT_EQ(memcmp(buf.space, "prepa\0", 6), 0);
universe@538 495 }
universe@538 496
universe@538 497 TEST_F(BufferWrite, PutcWrapperDiscard) {
universe@541 498 ASSERT_EQ(buf.capacity, 8);
universe@541 499 ASSERT_EQ(buf.size, 4);
universe@541 500 buf.pos = 8;
universe@565 501 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 502 EXPECT_EQ(c, EOF);
universe@541 503 EXPECT_EQ(buf.size, 4);
universe@541 504 EXPECT_EQ(buf.pos, 8);
universe@541 505 EXPECT_EQ(buf.capacity, 8);
universe@541 506 EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0\0", 9), 0);
universe@538 507 }
universe@538 508
universe@538 509 TEST_F(BufferWrite, PutcWrapperExtend) {
universe@541 510 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 511 ASSERT_EQ(buf.capacity, 8);
universe@541 512 ASSERT_EQ(buf.size, 4);
universe@541 513 buf.pos = 8;
universe@565 514 int c = cxBufferPut(&buf, 0x200 | 'a');
universe@541 515 EXPECT_EQ(c, 'a');
universe@541 516 EXPECT_EQ(buf.size, 9);
universe@541 517 EXPECT_EQ(buf.pos, 9);
universe@541 518 EXPECT_GE(buf.capacity, 9);
universe@566 519 EXPECT_EQ(memcmp(buf.space, "prep\0\0\0\0a", 9), 0);
universe@538 520 }
universe@538 521
universe@538 522 TEST_F(BufferWrite, PutStringWrapperFit) {
universe@541 523 const char *data = "test";
universe@541 524 ASSERT_EQ(buf.capacity, 8);
universe@541 525 ASSERT_EQ(buf.pos, 4);
universe@541 526 ASSERT_EQ(buf.size, 4);
universe@541 527 size_t written = cxBufferPutString(&buf, data);
universe@541 528 EXPECT_EQ(written, 4);
universe@541 529 EXPECT_EQ(buf.size, 8);
universe@541 530 EXPECT_EQ(buf.pos, 8);
universe@541 531 EXPECT_EQ(buf.capacity, 8);
universe@541 532 EXPECT_EQ(memcmp(buf.space, "preptest", 8), 0);
universe@538 533 }
universe@538 534
universe@538 535 TEST_F(BufferWrite, PutStringWrapperDiscard) {
universe@541 536 const char *data = "testing";
universe@541 537 ASSERT_EQ(buf.capacity, 8);
universe@541 538 ASSERT_EQ(buf.pos, 4);
universe@541 539 ASSERT_EQ(buf.size, 4);
universe@541 540 size_t written = cxBufferPutString(&buf, data);
universe@541 541 EXPECT_EQ(written, 4);
universe@541 542 EXPECT_EQ(buf.size, 8);
universe@541 543 EXPECT_EQ(buf.pos, 8);
universe@541 544 EXPECT_EQ(buf.capacity, 8);
universe@541 545 EXPECT_EQ(memcmp(buf.space, "preptest\0", 9), 0);
universe@538 546 }
universe@538 547
universe@538 548 TEST_F(BufferWrite, PutStringWrapperExtend) {
universe@541 549 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 550 const char *data = "testing";
universe@541 551 ASSERT_EQ(buf.capacity, 8);
universe@541 552 ASSERT_EQ(buf.pos, 4);
universe@541 553 ASSERT_EQ(buf.size, 4);
universe@541 554 size_t written = cxBufferPutString(&buf, data);
universe@541 555 EXPECT_EQ(written, 7);
universe@541 556 EXPECT_EQ(buf.size, 11);
universe@541 557 EXPECT_EQ(buf.pos, 11);
universe@541 558 EXPECT_GE(buf.capacity, 11);
universe@541 559 EXPECT_EQ(memcmp(buf.space, "preptesting", 11), 0);
universe@541 560 }
universe@538 561
universe@541 562 TEST_F(BufferWrite, MultOverflow) {
universe@541 563 const char *data = "testing";
universe@541 564 ASSERT_EQ(buf.capacity, 8);
universe@541 565 ASSERT_EQ(buf.pos, 4);
universe@541 566 ASSERT_EQ(buf.size, 4);
universe@541 567 size_t written = cxBufferWrite(data, 8, SIZE_MAX / 4, &buf);
universe@541 568 EXPECT_EQ(written, 0);
universe@541 569 EXPECT_EQ(buf.capacity, 8);
universe@541 570 EXPECT_EQ(buf.pos, 4);
universe@541 571 EXPECT_EQ(buf.size, 4);
universe@541 572 EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
universe@538 573 }
universe@541 574
universe@541 575 TEST_F(BufferWrite, MaxCapaOverflow) {
universe@541 576 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 577 const char *data = "testing";
universe@541 578 ASSERT_EQ(buf.capacity, 8);
universe@541 579 ASSERT_EQ(buf.pos, 4);
universe@541 580 ASSERT_EQ(buf.size, 4);
universe@541 581 size_t written = cxBufferWrite(data, 1, SIZE_MAX - 2, &buf);
universe@541 582 EXPECT_EQ(written, 0);
universe@541 583 EXPECT_EQ(buf.capacity, 8);
universe@541 584 EXPECT_EQ(buf.pos, 4);
universe@541 585 EXPECT_EQ(buf.size, 4);
universe@541 586 EXPECT_EQ(memcmp(buf.space, "prep\0", 5), 0);
universe@541 587 }
universe@541 588
universe@541 589 TEST_F(BufferWrite, OnlyOverwrite) {
universe@541 590 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@541 591 ASSERT_EQ(buf.capacity, 8);
universe@541 592 memcpy(buf.space, "preptest", 8);
universe@541 593 buf.pos = 3;
universe@541 594 buf.size = 8;
universe@541 595 size_t written = cxBufferWrite("XXX", 2, 2, &buf);
universe@541 596 EXPECT_EQ(written, 2);
universe@541 597 EXPECT_EQ(buf.capacity, 8);
universe@541 598 EXPECT_EQ(buf.size, 8);
universe@541 599 EXPECT_EQ(buf.pos, 7);
universe@541 600 EXPECT_EQ(memcmp(buf.space, "preXXX\0t", 8), 0);
universe@541 601 }
universe@545 602
universe@545 603 TEST_F(BufferWrite, FlushAtCapacity) {
universe@545 604 enableFlushing();
universe@545 605 ASSERT_EQ(buf.capacity, 8);
universe@545 606 ASSERT_EQ(buf.pos, 4);
universe@545 607 size_t written = cxBufferWrite("foo", 1, 3, &buf);
universe@545 608 EXPECT_EQ(written, 3);
universe@545 609 ASSERT_EQ(buf.pos, 7);
universe@545 610 ASSERT_EQ(buf.size, 7);
universe@545 611 ASSERT_EQ(target.pos, 0);
universe@545 612 ASSERT_EQ(target.size, 0);
universe@545 613 written = cxBufferWrite("hello", 1, 5, &buf);
universe@545 614 EXPECT_EQ(written, 5);
universe@545 615 EXPECT_EQ(buf.pos, 0);
universe@545 616 EXPECT_EQ(buf.size, 0);
universe@545 617 EXPECT_EQ(buf.capacity, 8);
universe@545 618 EXPECT_EQ(target.pos, 12);
universe@545 619 ASSERT_EQ(target.size, 12);
universe@545 620 EXPECT_EQ(memcmp(target.space, "prepfoohello", 12), 0);
universe@545 621 }
universe@546 622
universe@546 623 TEST_F(BufferWrite, FlushAtThreshold) {
universe@546 624 enableFlushing();
universe@546 625 buf.flush_threshold = 12;
universe@546 626 buf.flags |= CX_BUFFER_AUTO_EXTEND;
universe@546 627 ASSERT_EQ(buf.capacity, 8);
universe@546 628 ASSERT_EQ(buf.pos, 4);
universe@546 629 size_t written = cxBufferWrite("foobar", 1, 6, &buf);
universe@546 630 EXPECT_EQ(written, 6);
universe@546 631 ASSERT_EQ(buf.pos, 10);
universe@546 632 ASSERT_EQ(buf.size, 10);
universe@546 633 ASSERT_GE(buf.capacity, 10);
universe@546 634 ASSERT_LE(buf.capacity, 12);
universe@546 635 ASSERT_EQ(target.pos, 0);
universe@546 636 ASSERT_EQ(target.size, 0);
universe@546 637 written = cxBufferWrite("hello", 1, 5, &buf);
universe@546 638 EXPECT_EQ(written, 5);
universe@546 639 EXPECT_EQ(buf.pos, 0);
universe@546 640 EXPECT_EQ(buf.size, 0);
universe@546 641 EXPECT_LE(buf.capacity, 12);
universe@546 642 EXPECT_EQ(target.pos, 15);
universe@546 643 ASSERT_EQ(target.size, 15);
universe@546 644 EXPECT_EQ(memcmp(target.space, "prepfoobarhello", 15), 0);
universe@546 645 }
universe@547 646
universe@567 647 TEST_F(BufferWrite, FlushRateLimited) {
universe@567 648 enableFlushing();
universe@567 649 // limit the rate of the flush function and the capacity of the target
universe@567 650 target.capacity = 16;
universe@567 651 target.flags &= ~CX_BUFFER_AUTO_EXTEND;
universe@567 652 buf.flush_func = (cx_write_func) mock_write_limited_rate;
universe@567 653 ASSERT_EQ(buf.capacity, 8);
universe@567 654 ASSERT_EQ(buf.pos, 4);
universe@567 655 size_t written = cxBufferWrite("foo", 1, 3, &buf);
universe@567 656 EXPECT_EQ(written, 3);
universe@567 657 ASSERT_EQ(buf.pos, 7);
universe@567 658 ASSERT_EQ(buf.size, 7);
universe@567 659 ASSERT_EQ(target.pos, 0);
universe@567 660 ASSERT_EQ(target.size, 0);
universe@567 661 written = cxBufferWrite("hello, world!", 1, 13, &buf);
universe@567 662 // " world!" fits into this buffer, the remaining stuff is flushed out
universe@567 663 EXPECT_EQ(written, 13);
universe@567 664 EXPECT_EQ(buf.pos, 7);
universe@567 665 EXPECT_EQ(buf.size, 7);
universe@567 666 EXPECT_EQ(buf.capacity, 8);
universe@567 667 EXPECT_EQ(memcmp(buf.space, " world!", 7), 0);
universe@567 668 EXPECT_EQ(target.pos, 13);
universe@567 669 ASSERT_EQ(target.size, 13);
universe@567 670 EXPECT_EQ(target.capacity, 16);
universe@567 671 EXPECT_EQ(memcmp(target.space, "prepfoohello,", 13), 0);
universe@567 672 }
universe@567 673
universe@548 674 class BufferSeek : public BufferFixture {
universe@547 675 };
universe@547 676
universe@547 677 TEST_F(BufferSeek, SetZero) {
universe@547 678 int result = cxBufferSeek(&buf, 0, SEEK_SET);
universe@547 679 EXPECT_EQ(result, 0);
universe@547 680 EXPECT_EQ(buf.pos, 0);
universe@547 681 }
universe@547 682
universe@547 683 TEST_F(BufferSeek, SetValid) {
universe@547 684 int result = cxBufferSeek(&buf, 5, SEEK_SET);
universe@547 685 EXPECT_EQ(result, 0);
universe@547 686 EXPECT_EQ(buf.pos, 5);
universe@547 687 }
universe@547 688
universe@547 689 TEST_F(BufferSeek, SetInvalid) {
universe@547 690 ASSERT_EQ(buf.pos, 3);
universe@547 691 int result = cxBufferSeek(&buf, 6, SEEK_SET);
universe@547 692 EXPECT_NE(result, 0);
universe@547 693 EXPECT_EQ(buf.pos, 3);
universe@547 694 }
universe@547 695
universe@547 696 TEST_F(BufferSeek, CurZero) {
universe@547 697 ASSERT_EQ(buf.pos, 3);
universe@547 698 int result = cxBufferSeek(&buf, 0, SEEK_CUR);
universe@547 699 EXPECT_EQ(result, 0);
universe@547 700 EXPECT_EQ(buf.pos, 3);
universe@547 701 }
universe@547 702
universe@547 703 TEST_F(BufferSeek, CurValidPositive) {
universe@547 704 ASSERT_EQ(buf.pos, 3);
universe@547 705 int result = cxBufferSeek(&buf, 2, SEEK_CUR);
universe@547 706 EXPECT_EQ(result, 0);
universe@547 707 EXPECT_EQ(buf.pos, 5);
universe@547 708 }
universe@547 709
universe@547 710 TEST_F(BufferSeek, CurValidNegative) {
universe@547 711 ASSERT_EQ(buf.pos, 3);
universe@547 712 int result = cxBufferSeek(&buf, -3, SEEK_CUR);
universe@547 713 EXPECT_EQ(result, 0);
universe@547 714 EXPECT_EQ(buf.pos, 0);
universe@547 715 }
universe@547 716
universe@547 717 TEST_F(BufferSeek, CurInvalidPositive) {
universe@547 718 ASSERT_EQ(buf.pos, 3);
universe@547 719 int result = cxBufferSeek(&buf, 3, SEEK_CUR);
universe@547 720 EXPECT_NE(result, 0);
universe@547 721 EXPECT_EQ(buf.pos, 3);
universe@547 722 }
universe@547 723
universe@547 724 TEST_F(BufferSeek, CurInvalidNegative) {
universe@547 725 ASSERT_EQ(buf.pos, 3);
universe@547 726 int result = cxBufferSeek(&buf, -4, SEEK_CUR);
universe@547 727 EXPECT_NE(result, 0);
universe@547 728 EXPECT_EQ(buf.pos, 3);
universe@547 729 }
universe@547 730
universe@547 731 TEST_F(BufferSeek, EndZero) {
universe@547 732 ASSERT_EQ(buf.size, 6);
universe@547 733 int result = cxBufferSeek(&buf, 0, SEEK_END);
universe@547 734 // the (past-the-)end position is always invalid
universe@547 735 EXPECT_NE(result, 0);
universe@547 736 EXPECT_EQ(buf.pos, 3);
universe@547 737 }
universe@547 738
universe@547 739 TEST_F(BufferSeek, EndValid) {
universe@547 740 ASSERT_EQ(buf.size, 6);
universe@547 741 int result = cxBufferSeek(&buf, -6, SEEK_END);
universe@547 742 EXPECT_EQ(result, 0);
universe@547 743 EXPECT_EQ(buf.pos, 0);
universe@547 744 }
universe@547 745
universe@547 746 TEST_F(BufferSeek, EndInvalid) {
universe@547 747 ASSERT_EQ(buf.size, 6);
universe@547 748 int result = cxBufferSeek(&buf, 1, SEEK_END);
universe@547 749 EXPECT_NE(result, 0);
universe@547 750 EXPECT_EQ(buf.pos, 3);
universe@547 751 }
universe@547 752
universe@547 753 TEST_F(BufferSeek, WhenceInvalid) {
universe@547 754 ASSERT_EQ(buf.size, 6);
universe@547 755 ASSERT_EQ(buf.pos, 3);
universe@547 756 int result = cxBufferSeek(&buf, 2, 9000);
universe@547 757 EXPECT_NE(result, 0);
universe@547 758 EXPECT_EQ(buf.size, 6);
universe@547 759 EXPECT_EQ(buf.pos, 3);
universe@548 760 }
universe@548 761
universe@548 762 class BufferEof : public BufferFixture {
universe@548 763 };
universe@548 764
universe@548 765 TEST_F(BufferEof, Reached) {
universe@548 766 buf.pos = buf.size;
universe@548 767 EXPECT_TRUE(cxBufferEof(&buf));
universe@548 768 buf.pos = buf.size - 1;
universe@548 769 ASSERT_FALSE(cxBufferEof(&buf));
universe@548 770 cxBufferPut(&buf, 'a');
universe@548 771 EXPECT_TRUE(cxBufferEof(&buf));
universe@548 772 }
universe@548 773
universe@548 774 TEST_F(BufferEof, NotReached) {
universe@548 775 buf.pos = buf.size - 1;
universe@548 776 EXPECT_FALSE(cxBufferEof(&buf));
universe@548 777 buf.pos = 0;
universe@548 778 cxBufferWrite("test", 1, 5, &buf);
universe@548 779 EXPECT_FALSE(cxBufferEof(&buf));
universe@548 780 }
universe@568 781
universe@568 782 class BufferRead : public ::testing::Test {
universe@568 783 protected:
universe@568 784 CxBuffer buf{};
universe@568 785
universe@568 786 void SetUp() override {
universe@568 787 cxBufferInit(&buf, nullptr, 16, cxDefaultAllocator, CX_BUFFER_DEFAULT);
universe@568 788 buf.capacity = 8; // artificially reduce capacity to check OOB writes
universe@568 789 memset(buf.space, 0, 16);
universe@568 790 memcpy(buf.space, "some data", 9);
universe@568 791 buf.size = 9;
universe@568 792 }
universe@568 793
universe@568 794 void TearDown() override {
universe@568 795 cxBufferDestroy(&buf);
universe@568 796 }
universe@568 797 };
universe@568 798
universe@568 799 TEST_F(BufferRead, GetByte) {
universe@568 800 buf.pos = 2;
universe@568 801 EXPECT_EQ(cxBufferGet(&buf), 'm');
universe@568 802 EXPECT_EQ(cxBufferGet(&buf), 'e');
universe@568 803 EXPECT_EQ(cxBufferGet(&buf), ' ');
universe@568 804 EXPECT_EQ(cxBufferGet(&buf), 'd');
universe@568 805 EXPECT_EQ(buf.pos, 6);
universe@568 806 }
universe@568 807
universe@568 808 TEST_F(BufferRead, GetEof) {
universe@568 809 buf.pos = buf.size;
universe@568 810 EXPECT_EQ(cxBufferGet(&buf), EOF);
universe@568 811 }
universe@569 812
universe@569 813 TEST_F(BufferRead, ReadWithinBounds) {
universe@569 814 buf.pos = 2;
universe@569 815 char target[4];
universe@569 816 auto read = cxBufferRead(&target, 1, 4, &buf);
universe@569 817 ASSERT_EQ(read, 4);
universe@569 818 EXPECT_EQ(memcmp(&target, "me d", 4), 0);
universe@569 819 EXPECT_EQ(buf.pos, 6);
universe@569 820 }
universe@569 821
universe@569 822 TEST_F(BufferRead, ReadOutOfBounds) {
universe@569 823 buf.pos = 6;
universe@569 824 char target[4];
universe@569 825 auto read = cxBufferRead(&target, 1, 4, &buf);
universe@569 826 ASSERT_EQ(read, 3);
universe@569 827 EXPECT_EQ(memcmp(&target, "ata", 3), 0);
universe@569 828 EXPECT_EQ(buf.pos, 9);
universe@569 829 }
universe@569 830
universe@569 831 TEST_F(BufferRead, ReadOutOfBoundsMultibyte) {
universe@569 832 buf.pos = 6;
universe@569 833 char target[4];
universe@569 834 target[2] = '\0';
universe@569 835 auto read = cxBufferRead(&target, 2, 2, &buf);
universe@569 836 ASSERT_EQ(read, 1);
universe@569 837 EXPECT_EQ(memcmp(&target, "at\0", 3), 0);
universe@569 838 EXPECT_EQ(buf.pos, 8);
universe@569 839 }
universe@569 840
universe@569 841 TEST_F(BufferRead, ReadEof) {
universe@569 842 buf.pos = 9;
universe@569 843 char target[4];
universe@569 844 auto read = cxBufferRead(&target, 1, 1, &buf);
universe@569 845 ASSERT_EQ(read, 0);
universe@569 846 EXPECT_EQ(buf.pos, 9);
universe@569 847 }

mercurial