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