1//
2// FIFOBufferTest.cpp
3//
4// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "FIFOBufferTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Buffer.h"
15#include "Poco/Exception.h"
16#include "Poco/Delegate.h"
17#include "Poco/FIFOBuffer.h"
18#include <iostream>
19#include <memory>
20#include <cstring>
21
22
23// NOTE: using for certain namespace
24using Poco::BasicFIFOBuffer;
25using Poco::FIFOBuffer;
26using Poco::Buffer;
27using Poco::InvalidAccessException;
28using Poco::delegate;
29using std::memcpy;
30
31
32FIFOBufferTest::FIFOBufferTest(const std::string& rName):
33 CppUnit::TestCase(rName),
34 _notToReadable(0),
35 _notToWritable(0),
36 _readableToNot(0),
37 _writableToNot(0)
38{
39}
40
41
42FIFOBufferTest::~FIFOBufferTest()
43{
44}
45
46void FIFOBufferTest::onReadable(bool& b)
47{
48 if (b) ++_notToReadable;
49 else ++_readableToNot;
50};
51
52
53void FIFOBufferTest::onWritable(bool& b)
54{
55 if (b) ++_notToWritable;
56 else ++_writableToNot;
57}
58
59void FIFOBufferTest::testNextWrite()
60{
61 // String length is 88 characters.
62 const int BUFFER_SIZE = 128;
63 std::string text("The Quick Brown Dog Jumps Over The Lazy Fox.");
64 BasicFIFOBuffer<char> buffer(BUFFER_SIZE);
65 buffer.write(text.data(), text.size());
66 char cbuffer[BUFFER_SIZE];
67 std::memset(cbuffer, 0, buffer.size());
68
69 buffer.read(cbuffer, 4);
70
71 assertTrue (std::string(cbuffer, 4) == std::string("The "));
72
73 buffer.peek(cbuffer, buffer.used());
74 assertTrue (std::string(cbuffer, buffer.used()) ==
75 std::string("Quick Brown Dog Jumps Over The Lazy Fox."));
76
77 memcpy(buffer.next(), "The ", 4);
78 buffer.advance(4);
79
80 buffer.peek(cbuffer, buffer.used());
81
82 assertTrue (std::string("Quick Brown Dog Jumps Over The Lazy Fox.The ") == std::string(cbuffer, buffer.used()));
83}
84
85
86void FIFOBufferTest::testEOFAndError()
87{
88 typedef FIFOBuffer::Type T;
89
90 FIFOBuffer f(20, true);
91
92 assertTrue (f.isEmpty());
93 assertTrue (!f.isFull());
94
95 Buffer<T> b(10);
96 std::vector<T> v;
97
98 f.readable += delegate(this, &FIFOBufferTest::onReadable);
99 f.writable += delegate(this, &FIFOBufferTest::onWritable);
100
101 for (T c = '0'; c < '0' + 10; ++c)
102 v.push_back(c);
103
104 std::memcpy(b.begin(), &v[0], sizeof(T) * v.size());
105 assertTrue (0 == _notToReadable);
106 assertTrue (0 == _readableToNot);
107 assertTrue (10 == f.write(b));
108 assertTrue (1 == _notToReadable);
109 assertTrue (0 == _readableToNot);
110 assertTrue (20 == f.size());
111 assertTrue (10 == f.used());
112 assertTrue (!f.isEmpty());
113 f.setEOF();
114 assertTrue (0 == _notToWritable);
115 assertTrue (1 == _writableToNot);
116 assertTrue (f.hasEOF());
117 assertTrue (!f.isEOF());
118 assertTrue (1 == _notToReadable);
119 assertTrue (0 == _readableToNot);
120 assertTrue (20 == f.size());
121 assertTrue (10 == f.used());
122 assertTrue (0 == f.write(b));
123 assertTrue (!f.isEmpty());
124 assertTrue (5 == f.read(b, 5));
125 assertTrue (1 == _notToReadable);
126 assertTrue (0 == _readableToNot);
127 assertTrue (f.hasEOF());
128 assertTrue (!f.isEOF());
129 assertTrue (5 == f.read(b, 5));
130 assertTrue (1 == _notToReadable);
131 assertTrue (1 == _readableToNot);
132 assertTrue (f.hasEOF());
133 assertTrue (f.isEOF());
134 assertTrue (0 == _notToWritable);
135 assertTrue (1 == _writableToNot);
136
137 f.setEOF(false);
138 assertTrue (!f.hasEOF());
139 assertTrue (!f.isEOF());
140 assertTrue (1 == _notToWritable);
141 assertTrue (1 == _writableToNot);
142 assertTrue (1 == _notToReadable);
143 assertTrue (1 == _readableToNot);
144
145 assertTrue (5 == f.write(b));
146 assertTrue (1 == _notToWritable);
147 assertTrue (1 == _writableToNot);
148 assertTrue (2 == _notToReadable);
149 assertTrue (1 == _readableToNot);
150 assertTrue (20 == f.size());
151 assertTrue (5 == f.used());
152 f.setError();
153 assertTrue (0 == f.write(b));
154
155 try
156 {
157 f.copy(b.begin(), 5);
158 fail ("must throw InvalidAccessException");
159 }
160 catch (InvalidAccessException&) { }
161
162 try
163 {
164 f.advance(5);
165 fail ("must throw InvalidAccessException");
166 }
167 catch (InvalidAccessException&) { }
168
169 assertTrue (1 == _notToWritable);
170 assertTrue (2 == _writableToNot);
171 assertTrue (2 == _notToReadable);
172 assertTrue (2 == _readableToNot);
173 assertTrue (20 == f.size());
174 assertTrue (0 == f.used());
175 f.setError(false);
176 assertTrue (2 == _notToWritable);
177 assertTrue (2 == _writableToNot);
178 assertTrue (2 == _notToReadable);
179 assertTrue (2 == _readableToNot);
180 assertTrue (20 == f.size());
181 assertTrue (0 == f.used());
182 assertTrue (5 == f.write(b));
183 assertTrue (2 == _notToWritable);
184 assertTrue (2 == _writableToNot);
185 assertTrue (3 == _notToReadable);
186 assertTrue (2 == _readableToNot);
187 assertTrue (20 == f.size());
188 assertTrue (5 == f.used());
189}
190
191
192void FIFOBufferTest::testChar()
193{
194 typedef FIFOBuffer::Type T;
195
196 FIFOBuffer f(20, true);
197
198 assertTrue (f.isEmpty());
199 assertTrue (!f.isFull());
200
201 Buffer<T> b(10);
202 std::vector<T> v;
203
204 f.readable += delegate(this, &FIFOBufferTest::onReadable);
205 f.writable += delegate(this, &FIFOBufferTest::onWritable);
206
207 for (T c = '0'; c < '0' + 10; ++c)
208 v.push_back(c);
209
210 std::memcpy(b.begin(), &v[0], sizeof(T) * v.size());
211 assertTrue (0 == _notToReadable);
212 assertTrue (0 == _readableToNot);
213 f.write(b);
214 assertTrue (1 == _notToReadable);
215 assertTrue (0 == _readableToNot);
216 assertTrue (20 == f.size());
217 assertTrue (10 == f.used());
218 assertTrue (!f.isEmpty());
219 assertTrue ('0' == f[0]);
220 assertTrue ('1' == f[1]);
221 assertTrue ('2' == f[2]);
222 assertTrue ('3' == f[3]);
223 assertTrue ('4' == f[4]);
224 assertTrue ('5' == f[5]);
225 assertTrue ('6' == f[6]);
226 assertTrue ('7' == f[7]);
227 assertTrue ('8' == f[8]);
228 assertTrue ('9' == f[9]);
229
230 b.resize(5);
231 f.read(b, b.size());
232 assertTrue (20 == f.size());
233 assertTrue (5 == f.used());
234 assertTrue (!f.isEmpty());
235 assertTrue ('5' == f[0]);
236 assertTrue ('6' == f[1]);
237 assertTrue ('7' == f[2]);
238 assertTrue ('8' == f[3]);
239 assertTrue ('9' == f[4]);
240 try { T i = f[10]; fail ("must fail"); }
241 catch (InvalidAccessException&) { }
242
243 v.clear();
244 for (T c = 'a'; c < 'a' + 10; ++c)
245 v.push_back(c);
246
247 b.resize(10);
248 std::memcpy(b.begin(), &v[0], sizeof(T) * v.size());
249 f.write(b);
250 assertTrue (20 == f.size());
251 assertTrue (15 == f.used());
252 assertTrue (!f.isEmpty());
253 assertTrue ('5' == f[0]);
254 assertTrue ('6' == f[1]);
255 assertTrue ('7' == f[2]);
256 assertTrue ('8' == f[3]);
257 assertTrue ('9' == f[4]);
258 assertTrue ('a' == f[5]);
259 assertTrue ('b' == f[6]);
260 assertTrue ('c' == f[7]);
261 assertTrue ('d' == f[8]);
262 assertTrue ('e' == f[9]);
263 assertTrue ('f' == f[10]);
264 assertTrue ('g' == f[11]);
265 assertTrue ('h' == f[12]);
266 assertTrue ('i' == f[13]);
267 assertTrue ('j' == f[14]);
268 try { T i = f[15]; fail ("must fail"); }
269 catch (InvalidAccessException&) { }
270
271 f.read(b, 10);
272 assertTrue (20 == f.size());
273 assertTrue (5 == f.used());
274 assertTrue (!f.isEmpty());
275 assertTrue ('f' == f[0]);
276 assertTrue ('g' == f[1]);
277 assertTrue ('h' == f[2]);
278 assertTrue ('i' == f[3]);
279 assertTrue ('j' == f[4]);
280 try { T i = f[5]; fail ("must fail"); }
281 catch (InvalidAccessException&) { }
282
283 assertTrue (1 == _notToReadable);
284 assertTrue (0 == _readableToNot);
285 assertTrue (0 == _notToWritable);
286 assertTrue (0 == _writableToNot);
287 f.read(b, 6);
288 assertTrue (1 == _notToReadable);
289 assertTrue (1 == _readableToNot);
290 assertTrue (0 == _notToWritable);
291 assertTrue (0 == _writableToNot);
292
293 assertTrue (5 == b.size());
294 assertTrue (20 == f.size());
295 assertTrue (0 == f.used());
296 try { T i = f[0]; fail ("must fail"); }
297 catch (InvalidAccessException&) { }
298 assertTrue (f.isEmpty());
299
300 assertTrue (1 == _notToReadable);
301 assertTrue (1 == _readableToNot);
302 assertTrue (0 == _notToWritable);
303 assertTrue (0 == _writableToNot);
304 assertTrue (5 == f.write(b));
305 assertTrue (2 == _notToReadable);
306 assertTrue (1 == _readableToNot);
307 assertTrue (0 == _notToWritable);
308 assertTrue (0 == _writableToNot);
309
310 assertTrue (20 == f.size());
311 assertTrue (5 == f.used());
312 assertTrue (!f.isEmpty());
313 assertTrue ('f' == f[0]);
314 assertTrue ('g' == f[1]);
315 assertTrue ('h' == f[2]);
316 assertTrue ('i' == f[3]);
317 assertTrue ('j' == f[4]);
318
319 f.resize(10);
320 assertTrue (10 == f.size());
321 assertTrue (5 == f.used());
322 assertTrue (!f.isEmpty());
323 assertTrue ('f' == f[0]);
324 assertTrue ('g' == f[1]);
325 assertTrue ('h' == f[2]);
326 assertTrue ('i' == f[3]);
327 assertTrue ('j' == f[4]);
328
329 assertTrue (2 == _notToReadable);
330 assertTrue (1 == _readableToNot);
331 assertTrue (0 == _notToWritable);
332 assertTrue (0 == _writableToNot);
333 f.resize(3, false);
334 assertTrue (2 == _notToReadable);
335 assertTrue (2 == _readableToNot);
336 assertTrue (0 == _notToWritable);
337 assertTrue (0 == _writableToNot);
338 assertTrue (3 == f.size());
339 assertTrue (0 == f.used());
340 assertTrue (f.isEmpty());
341
342 b.resize(3);
343 b[0] = 'x';
344 b[1] = 'y';
345 b[2] = 'z';
346 f.resize(3);
347
348 assertTrue (2 == _notToReadable);
349 assertTrue (2 == _readableToNot);
350 assertTrue (0 == _notToWritable);
351 assertTrue (0 == _writableToNot);
352 f.write(b);
353 assertTrue (3 == _notToReadable);
354 assertTrue (2 == _readableToNot);
355 assertTrue (0 == _notToWritable);
356 assertTrue (1 == _writableToNot);
357 assertTrue (f.isFull());
358
359 f.read(b);
360 assertTrue (3 == _notToReadable);
361 assertTrue (3 == _readableToNot);
362 assertTrue (1 == _notToWritable);
363 assertTrue (1 == _writableToNot);
364 assertTrue (f.isEmpty());
365
366 f.resize(10);
367 assertTrue (10 == f.size());
368 assertTrue (0 == f.used());
369 assertTrue (10 == f.available());
370 assertTrue (f.isEmpty());
371
372 assertTrue (3 == _notToReadable);
373 assertTrue (3 == _readableToNot);
374 assertTrue (1 == _notToWritable);
375 assertTrue (1 == _writableToNot);
376 f.write(b);
377 assertTrue (4 == _notToReadable);
378 assertTrue (3 == _readableToNot);
379 assertTrue (1 == _notToWritable);
380 assertTrue (1 == _writableToNot);
381
382 assertTrue (10 == f.size());
383 assertTrue (3 == f.used());
384 assertTrue (7 == f.available());
385 assertTrue (!f.isEmpty());
386
387 f.drain(1);
388 assertTrue (4 == _notToReadable);
389 assertTrue (3 == _readableToNot);
390 assertTrue (1 == _notToWritable);
391 assertTrue (1 == _writableToNot);
392
393 assertTrue (10 == f.size());
394 assertTrue (2 == f.used());
395 assertTrue (8 == f.available());
396 assertTrue (!f.isEmpty());
397
398 f.drain(2);
399 assertTrue (4 == _notToReadable);
400 assertTrue (4 == _readableToNot);
401 assertTrue (1 == _notToWritable);
402 assertTrue (1 == _writableToNot);
403
404 assertTrue (10 == f.size());
405 assertTrue (0 == f.used());
406 assertTrue (10 == f.available());
407 assertTrue (f.isEmpty());
408
409 f.write(b);
410 assertTrue (5 == _notToReadable);
411 assertTrue (4 == _readableToNot);
412 assertTrue (1 == _notToWritable);
413 assertTrue (1 == _writableToNot);
414
415 assertTrue (10 == f.size());
416 assertTrue (3 == f.used());
417 assertTrue (7 == f.available());
418 assertTrue (!f.isEmpty());
419
420 f.drain();
421 assertTrue (5 == _notToReadable);
422 assertTrue (5 == _readableToNot);
423 assertTrue (1 == _notToWritable);
424 assertTrue (1 == _writableToNot);
425 assertTrue (10 == f.size());
426 assertTrue (0 == f.used());
427 assertTrue (10 == f.available());
428 assertTrue (f.isEmpty());
429
430 f.write(b, 2);
431 assertTrue (10 == f.size());
432 assertTrue (2 == f.used());
433 assertTrue (8 == f.available());
434 assertTrue (!f.isEmpty());
435
436 assertTrue (6 == _notToReadable);
437 assertTrue (5 == _readableToNot);
438 assertTrue (1 == _notToWritable);
439 assertTrue (1 == _writableToNot);
440
441 f.drain();
442 assertTrue (6 == _notToReadable);
443 assertTrue (6 == _readableToNot);
444 assertTrue (1 == _notToWritable);
445 assertTrue (1 == _writableToNot);
446
447 assertTrue (3 == f.write(b, 10));
448 assertTrue (10 == f.size());
449 assertTrue (3 == f.used());
450 assertTrue (7 == f.available());
451 assertTrue (!f.isEmpty());
452
453 assertTrue (7 == _notToReadable);
454 assertTrue (6 == _readableToNot);
455 assertTrue (1 == _notToWritable);
456 assertTrue (1 == _writableToNot);
457
458 const char arr[3] = {'4', '5', '6' };
459 try
460 {
461 f.copy(&arr[0], 8);
462 fail("must fail");
463 } catch (InvalidAccessException&) { }
464
465 f.copy(&arr[0], 3);
466 assertTrue (7 == _notToReadable);
467 assertTrue (6 == _readableToNot);
468 assertTrue (1 == _notToWritable);
469 assertTrue (1 == _writableToNot);
470
471 assertTrue (10 == f.size());
472 assertTrue (6 == f.used());
473 assertTrue (4 == f.available());
474
475 f.copy(&arr[0], 4);
476 assertTrue (7 == _notToReadable);
477 assertTrue (6 == _readableToNot);
478 assertTrue (1 == _notToWritable);
479 assertTrue (2 == _writableToNot);
480 assertTrue (f.isFull());
481
482 assertTrue (10 == f.size());
483 assertTrue (10 == f.used());
484 assertTrue (0 == f.available());
485
486 try
487 {
488 f.copy(&arr[0], 1);
489 fail("must fail");
490 } catch (InvalidAccessException&) { }
491
492 f.drain(1);
493 assertTrue (7 == _notToReadable);
494 assertTrue (6 == _readableToNot);
495 assertTrue (2 == _notToWritable);
496 assertTrue (2 == _writableToNot);
497
498 f.drain(9);
499 assertTrue (10 == f.size());
500 assertTrue (0 == f.used());
501 assertTrue (10 == f.available());
502
503 const char e[10] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
504 f.copy(&e[0], 10);
505 assertTrue (10 == f.size());
506 assertTrue (10 == f.used());
507 assertTrue (0 == f.available());
508 f.drain(1);
509 f.write(e, 1);
510 assertTrue (10 == f.size());
511 assertTrue (10 == f.used());
512 assertTrue (0 == f.available());
513
514 assertTrue (f[0] == '2');
515 assertTrue (f[1] == '3');
516 assertTrue (f[2] == '4');
517 assertTrue (f[3] == '5');
518 assertTrue (f[4] == '6');
519 assertTrue (f[5] == '7');
520 assertTrue (f[6] == '8');
521 assertTrue (f[7] == '9');
522 assertTrue (f[8] == '0');
523 assertTrue (f[9] == '1');
524
525 f.readable -= delegate(this, &FIFOBufferTest::onReadable);
526 f.writable -= delegate(this, &FIFOBufferTest::onReadable);
527}
528
529
530void FIFOBufferTest::testInt()
531{
532 typedef int T;
533
534 BasicFIFOBuffer<T> f(20);
535 Buffer<T> b(10);
536 std::vector<T> v;
537
538 for (T c = 0; c < 10; ++c)
539 v.push_back(c);
540
541 std::memcpy(b.begin(), &v[0], sizeof(T) * v.size());
542 f.write(b);
543 assertTrue (20 == f.size());
544 assertTrue (10 == f.used());
545 assertTrue (!f.isEmpty());
546 assertTrue (0 == f[0]);
547 assertTrue (1 == f[1]);
548 assertTrue (2 == f[2]);
549 assertTrue (3 == f[3]);
550 assertTrue (4 == f[4]);
551 assertTrue (5 == f[5]);
552 assertTrue (6 == f[6]);
553 assertTrue (7 == f[7]);
554 assertTrue (8 == f[8]);
555 assertTrue (9 == f[9]);
556
557 b.resize(5);
558 f.read(b, b.size());
559 assertTrue (20 == f.size());
560 assertTrue (5 == f.used());
561 assertTrue (!f.isEmpty());
562 assertTrue (5 == f[0]);
563 assertTrue (6 == f[1]);
564 assertTrue (7 == f[2]);
565 assertTrue (8 == f[3]);
566 assertTrue (9 == f[4]);
567 try { T i = f[10]; fail ("must fail"); }
568 catch (InvalidAccessException&) { }
569
570 v.clear();
571 for (T c = 10; c < 20; ++c)
572 v.push_back(c);
573
574 b.resize(10);
575 std::memcpy(b.begin(), &v[0], sizeof(T) * v.size());
576 f.write(b);
577 assertTrue (20 == f.size());
578 assertTrue (15 == f.used());
579 assertTrue (!f.isEmpty());
580 assertTrue (5 == f[0]);
581 assertTrue (6 == f[1]);
582 assertTrue (7 == f[2]);
583 assertTrue (8 == f[3]);
584 assertTrue (9 == f[4]);
585 assertTrue (10 == f[5]);
586 assertTrue (11 == f[6]);
587 assertTrue (12 == f[7]);
588 assertTrue (13 == f[8]);
589 assertTrue (14 == f[9]);
590 assertTrue (15 == f[10]);
591 assertTrue (16 == f[11]);
592 assertTrue (17 == f[12]);
593 assertTrue (18 == f[13]);
594 assertTrue (19 == f[14]);
595 try { T i = f[15]; fail ("must fail"); }
596 catch (InvalidAccessException&) { }
597
598 f.read(b, 10);
599 assertTrue (20 == f.size());
600 assertTrue (5 == f.used());
601 assertTrue (!f.isEmpty());
602 assertTrue (15 == f[0]);
603 assertTrue (16 == f[1]);
604 assertTrue (17 == f[2]);
605 assertTrue (18 == f[3]);
606 assertTrue (19 == f[4]);
607 try { T i = f[5]; fail ("must fail"); }
608 catch (InvalidAccessException&) { }
609
610 f.read(b, 6);
611 assertTrue (5 == b.size());
612 assertTrue (20 == f.size());
613 assertTrue (0 == f.used());
614 try { T i = f[0]; fail ("must fail"); }
615 catch (InvalidAccessException&) { }
616
617 assertTrue (f.isEmpty());
618
619 assertTrue (5 == f.write(b));
620 assertTrue (20 == f.size());
621 assertTrue (5 == f.used());
622 assertTrue (!f.isEmpty());
623 assertTrue (15 == f[0]);
624 assertTrue (16 == f[1]);
625 assertTrue (17 == f[2]);
626 assertTrue (18 == f[3]);
627 assertTrue (19 == f[4]);
628
629 f.resize(10);
630 assertTrue (10 == f.size());
631 assertTrue (5 == f.used());
632 assertTrue (!f.isEmpty());
633 assertTrue (15 == f[0]);
634 assertTrue (16 == f[1]);
635 assertTrue (17 == f[2]);
636 assertTrue (18 == f[3]);
637 assertTrue (19 == f[4]);
638
639 f.drain(9);
640 assertTrue (10 == f.size());
641 assertTrue (0 == f.used());
642 assertTrue (10 == f.available());
643
644 const int e[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
645 f.copy(&e[0], 10);
646 assertTrue (10 == f.size());
647 assertTrue (10 == f.used());
648 assertTrue (0 == f.available());
649 f.drain(1);
650 f.write(e, 1);
651 assertTrue (10 == f.size());
652 assertTrue (10 == f.used());
653 assertTrue (0 == f.available());
654
655 assertTrue (f[0] == 2);
656 assertTrue (f[1] == 3);
657 assertTrue (f[2] == 4);
658 assertTrue (f[3] == 5);
659 assertTrue (f[4] == 6);
660 assertTrue (f[5] == 7);
661 assertTrue (f[6] == 8);
662 assertTrue (f[7] == 9);
663 assertTrue (f[8] == 0);
664 assertTrue (f[9] == 1);
665
666 f.resize(3, false);
667 assertTrue (3 == f.size());
668 assertTrue (0 == f.used());
669 assertTrue (f.isEmpty());
670}
671
672void FIFOBufferTest::setUp()
673{
674 _notToReadable = 0;
675 _notToWritable = 0;
676 _readableToNot = 0;
677 _writableToNot = 0;
678}
679
680
681void FIFOBufferTest::tearDown()
682{
683}
684
685
686CppUnit::Test* FIFOBufferTest::suite()
687{
688 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("FIFOBufferTest");
689
690 CppUnit_addTest(pSuite, FIFOBufferTest, testNextWrite);
691 CppUnit_addTest(pSuite, FIFOBufferTest, testChar);
692 CppUnit_addTest(pSuite, FIFOBufferTest, testInt);
693 CppUnit_addTest(pSuite, FIFOBufferTest, testEOFAndError);
694
695 return pSuite;
696}
697