testSBuf.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9#include "squid.h"
10#include "base/CharacterSet.h"
11#include "base/TextException.h"
12#include "compat/cppunit.h"
13#include "event.h"
14#include "HttpReply.h"
15#include "MemObject.h"
16#include "sbuf/Algorithms.h"
17#include "sbuf/SBuf.h"
18#include "sbuf/Stream.h"
19#include "tests/SBufFindTest.h"
20#include "unitTestMain.h"
21
22#include <iostream>
23#include <stdexcept>
24#include <unordered_map>
25
26/*
27 * test the SBuf functionalities
28 */
29
30class TestSBuf : public CPPUNIT_NS::TestFixture
31{
67 // CPPUNIT_TEST( testDumpStats ); //fake test, to print alloc stats
69
70protected:
71 void commonInit();
74 void testEqualityTest();
75 void testAppendSBuf();
76 void testAppendCString();
78 void testAppendf();
79 void testPrintf();
80 void testSubscriptOp();
82 void testDumpStats();
83 void testComparisons();
84 void testConsume();
85 void testRawContent();
86 void testRawSpace();
87 void testChop();
88 void testChomp();
89 void testSubstr();
91 void testSBufLength();
92 void testFindChar();
93 void testFindSBuf();
94 void testRFindChar();
95 void testRFindSBuf();
97 void testCopy();
98 void testStringOps();
99 void testGrow();
100 void testReserve();
101 void testStartsWith();
102 void testSBufStream();
103 void testFindFirstOf();
104 void testFindFirstNotOf();
105 void testAutoFind();
106 void testStdStringOps();
107 void testIterators();
108 void testSBufHash();
109};
111
112/* let this test link sanely */
113void
114eventAdd(const char *, EVH *, void *, double, int, bool)
115{}
116int64_t
118{ return 0; }
119/* end of stubs */
120
121// test string
122static const char fox[] = "The quick brown fox jumped over the lazy dog";
123static const char fox1[] = "The quick brown fox ";
124static const char fox2[] = "jumped over the lazy dog";
125
126// TEST: globals variables (default/empty and with contents) are
127// created outside and before any unit tests and memory subsystem
128// initialization. Check for correct constructor operation.
130SBuf literal("The quick brown fox jumped over the lazy dog");
131
132void
134{
135 /* NOTE: Do not initialize memory here because we need
136 * to test correct operation before and after Mem::Init
137 */
138
139 // XXX: partial demo below of how to do constructor unit-test. use scope to ensure each test
140 // is working on local-scope variables constructed fresh for the test, and destructed when
141 // scope exists. use nested scopes to test destructor affects on copied data (MemBlob etc)
142
143 // TEST: default constructor (implicit destructor non-crash test)
144 // test accessors on empty SBuf.
145 {
146 SBuf s1;
147 CPPUNIT_ASSERT_EQUAL(0U,s1.length());
148 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
149 CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
150 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
151 }
152
153 // TEST: copy-construct NULL string (implicit destructor non-crash test)
154 {
155 SBuf s1(nullptr);
156 CPPUNIT_ASSERT_EQUAL(0U,s1.length());
157 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
158 CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
159 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
160 }
161
162 // TEST: copy-construct empty string (implicit destructor non-crash test)
163 {
164 SBuf s1("");
165 CPPUNIT_ASSERT_EQUAL(0U,s1.length());
166 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
167 CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
168 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
169 }
170
171 // TEST: copy-construct from a SBuf
172 {
174 CPPUNIT_ASSERT_EQUAL(0U,s1.length());
175 CPPUNIT_ASSERT_EQUAL(SBuf(""),s1);
176 CPPUNIT_ASSERT_EQUAL(empty_sbuf,s1);
177 CPPUNIT_ASSERT_EQUAL(0,strcmp("",s1.c_str()));
178
179 SBuf s5(literal);
180 CPPUNIT_ASSERT_EQUAL(literal,s5);
181 SBuf s6(fox);
182 CPPUNIT_ASSERT_EQUAL(literal,s6);
183 // XXX: other state checks. expected result of calling any state accessor on s4 ?
184 }
185
186 // TEST: check that COW doesn't happen upon copy-construction
187 {
188 SBuf s1(empty_sbuf), s2(s1);
189 CPPUNIT_ASSERT_EQUAL(s1.rawContent(), s2.rawContent());
190 SBuf s3(literal), s4(literal);
191 CPPUNIT_ASSERT_EQUAL(s3.rawContent(), s4.rawContent());
192 }
193
194 // TEST: sub-string copy
195 {
196 SBuf s1=SBuf(fox+4), s2(fox);
197 SBuf s3=s2.substr(4,s2.length()); //n is out-of-bounds
198 CPPUNIT_ASSERT_EQUAL(s1,s3);
199 SBuf s4=SBuf(fox,4);
200 s3=s2.substr(0,4);
201 CPPUNIT_ASSERT_EQUAL(s4,s3);
202 }
203
204 // TEST: go via std::string adapter.
205 {
206 std::string str(fox);
207 SBuf s1(str);
208 CPPUNIT_ASSERT_EQUAL(literal,s1);
209 }
210}
211
212void
214{
215 Mem::Init();
217}
218
219void
221{
222 SBuf s1(fox),s2(fox);
223 CPPUNIT_ASSERT_EQUAL(s1,s1); //self-equality
224 CPPUNIT_ASSERT_EQUAL(s1,s2); //same contents
225 s2.assign("The quick brown fox jumped over the lazy doe");
226 CPPUNIT_ASSERT(!(s1 == s2)); //same length, different contents
227 s2.assign("foo");
228 CPPUNIT_ASSERT(!(s1 == s2)); //different length and contents
229 CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality
230 s2.clear();
231 CPPUNIT_ASSERT(!(s1 == s2)); //null and not-null
232 CPPUNIT_ASSERT(s1 != s2); //while we're ready, let's test inequality
233 s1.clear();
234 CPPUNIT_ASSERT_EQUAL(s1,s2); //null and null
235}
236
237void
239{
240 const SBuf appendix(fox1);
241 const char * const rawAppendix = appendix.rawContent();
242
243 // check whether the optimization that prevents copying when append()ing to
244 // default-constructed SBuf actually works
245 SBuf s0;
246 s0.append(appendix);
247 CPPUNIT_ASSERT_EQUAL(s0.rawContent(), appendix.rawContent());
248 CPPUNIT_ASSERT_EQUAL(s0, appendix);
249
250 // paranoid: check that the above code can actually detect copies
251 SBuf s1(fox1);
252 s1.append(appendix);
253 CPPUNIT_ASSERT(s1.rawContent() != appendix.rawContent());
254 CPPUNIT_ASSERT(s1 != appendix);
255 CPPUNIT_ASSERT_EQUAL(rawAppendix, appendix.rawContent());
256}
257
258void
260{
261 SBuf s1,s2;
262 s1.Printf("%s:%d:%03.3f","fox",10,12345.67);
263 s2.assign("fox:10:12345.670");
264 CPPUNIT_ASSERT_EQUAL(s1,s2);
265}
266
267void
269{
270 SBuf s1(fox1);
271 s1.append(fox2);
272 CPPUNIT_ASSERT_EQUAL(s1,literal);
273}
274
275void
277{
278 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
279 {
280 SBuf alpha(alphabet), s;
281 s.append(alphabet,5).append(alphabet+5);
282 CPPUNIT_ASSERT_EQUAL(alpha,s);
283 }
284 {
285 SBuf s;
286 std::string control;
287 s.append(alphabet,5).append("\0",1).append(alphabet+6,SBuf::npos);
288 control.append(alphabet,5).append(1,'\0').append(alphabet,6,std::string::npos);
289 SBuf scontrol(control); // we need this to test the equality. sigh.
290 CPPUNIT_ASSERT_EQUAL(scontrol,s);
291 }
292 {
293 const char *alphazero="abcdefghijk\0mnopqrstuvwxyz";
294 SBuf s(alphazero,26);
295 std::string str(alphazero,26);
296 CPPUNIT_ASSERT_EQUAL(0,memcmp(str.data(),s.rawContent(),26));
297 }
298}
299
300void
302{
303 SBuf s1,s2;
304 s1.appendf("%s:%d:%03.2f",fox,1234,1234.56);
305 s2.assign("The quick brown fox jumped over the lazy dog:1234:1234.56");
306 CPPUNIT_ASSERT_EQUAL(s2,s1);
307}
308
309void
311{
312 SBuf::GetStats().dump(std::cout);
313 MemBlob::GetStats().dump(std::cout);
314 std::cout << "sizeof(SBuf): " << sizeof(SBuf) << std::endl;
315 std::cout << "sizeof(MemBlob): " << sizeof(MemBlob) << std::endl;
316}
317
318void
320{
321 SBuf chg(literal);
322 CPPUNIT_ASSERT_EQUAL(chg[5],'u');
323 chg.setAt(5,'e');
324 CPPUNIT_ASSERT_EQUAL(literal[5],'u');
325 CPPUNIT_ASSERT_EQUAL(chg[5],'e');
326}
327
328// note: can't use cppunit's CPPUNIT_TEST_EXCEPTION because TextException asserts, and
329// so the test can't be properly completed.
330void
332{
333 char c;
334 c=literal.at(literal.length()); //out of bounds by 1
335 //notreached
336 std::cout << c << std::endl;
337}
338
339static int sign(int v)
340{
341 if (v < 0)
342 return -1;
343 if (v>0)
344 return 1;
345 return 0;
346}
347
348static void
349testComparisonStdFull(const char *left, const char *right)
350{
351 if (sign(strcmp(left, right)) != sign(SBuf(left).cmp(SBuf(right))))
352 std::cerr << std::endl << " cmp(SBuf) npos " << left << " ?= " << right << std::endl;
353 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left, right)), sign(SBuf(left).cmp(SBuf(right))));
354
355 if (sign(strcmp(left, right)) != sign(SBuf(left).cmp(right)))
356 std::cerr << std::endl << " cmp(char*) npos " << left << " ?= " << right << std::endl;
357 CPPUNIT_ASSERT_EQUAL(sign(strcmp(left, right)), sign(SBuf(left).cmp(right)));
358
359 if (sign(strcasecmp(left, right)) != sign(SBuf(left).caseCmp(SBuf(right))))
360 std::cerr << std::endl << " caseCmp(SBuf) npos " << left << " ?= " << right << std::endl;
361 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left, right)), sign(SBuf(left).caseCmp(SBuf(right))));
362
363 if (sign(strcasecmp(left, right)) != sign(SBuf(left).caseCmp(right)))
364 std::cerr << std::endl << " caseCmp(char*) npos " << left << " ?= " << right << std::endl;
365 CPPUNIT_ASSERT_EQUAL(sign(strcasecmp(left, right)), sign(SBuf(left).caseCmp(right)));
366}
367
368static void
369testComparisonStdN(const char *left, const char *right, const size_t n)
370{
371 if (sign(strncmp(left, right, n)) != sign(SBuf(left).cmp(SBuf(right), n)))
372 std::cerr << std::endl << " cmp(SBuf) " << n << ' ' << left << " ?= " << right << std::endl;
373 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left, right, n)), sign(SBuf(left).cmp(SBuf(right), n)));
374
375 if (sign(strncmp(left, right, n)) != sign(SBuf(left).cmp(right, n)))
376 std::cerr << std::endl << " cmp(char*) " << n << ' ' << SBuf(left) << " ?= " << right << std::endl;
377 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left, right, n)), sign(SBuf(left).cmp(right, n)));
378
379 if (sign(strncasecmp(left, right, n)) != sign(SBuf(left).caseCmp(SBuf(right), n)))
380 std::cerr << std::endl << " caseCmp(SBuf) " << n << ' ' << left << " ?= " << right << std::endl;
381 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left, right, n)), sign(SBuf(left).caseCmp(SBuf(right), n)));
382
383 if (sign(strncasecmp(left, right, n)) != sign(SBuf(left).caseCmp(right, n)))
384 std::cerr << std::endl << " caseCmp(char*) " << n << ' ' << SBuf(left) << " ?= " << right << std::endl;
385 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left, right, n)), sign(SBuf(left).caseCmp(right, n)));
386}
387
388static void
389testComparisonStdOneWay(const char *left, const char *right)
390{
391 testComparisonStdFull(left, right);
392 const size_t maxN = 2 + min(strlen(left), strlen(right));
393 for (size_t n = 0; n <= maxN; ++n) {
394 testComparisonStdN(left, right, n);
395 }
396}
397
398static void
399testComparisonStd(const char *s1, const char *s2)
400{
403}
404
405void
407{
408 //same length
409 SBuf s1("foo"),s2("foe");
410 CPPUNIT_ASSERT(s1.cmp(s2)>0);
411 CPPUNIT_ASSERT(s1.caseCmp(s2)>0);
412 CPPUNIT_ASSERT(s2.cmp(s1)<0);
413 CPPUNIT_ASSERT_EQUAL(0,s1.cmp(s2,2));
414 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,2));
415 CPPUNIT_ASSERT(s1 > s2);
416 CPPUNIT_ASSERT(s2 < s1);
417 CPPUNIT_ASSERT_EQUAL(sign(s1.cmp(s2)),sign(strcmp(s1.c_str(),s2.c_str())));
418 //different lengths
419 s1.assign("foo");
420 s2.assign("foof");
421 CPPUNIT_ASSERT(s1.cmp(s2)<0);
422 CPPUNIT_ASSERT_EQUAL(sign(s1.cmp(s2)),sign(strcmp(s1.c_str(),s2.c_str())));
423 CPPUNIT_ASSERT(s1 < s2);
424 // specifying the max-length and overhanging size
425 CPPUNIT_ASSERT_EQUAL(1,SBuf("foolong").caseCmp(SBuf("foo"), 5));
426 // case-insensive comaprison
427 s1 = "foo";
428 s2 = "fOo";
429 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2));
430 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,2));
431 // \0-clenliness test
432 s1.assign("f\0oo",4);
433 s2.assign("f\0Oo",4);
434 CPPUNIT_ASSERT(s1.cmp(s2) > 0);
435 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2));
436 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,3));
437 CPPUNIT_ASSERT_EQUAL(0,s1.caseCmp(s2,2));
438 CPPUNIT_ASSERT_EQUAL(0,s1.cmp(s2,2));
439
440 testComparisonStd("foo", "fooz");
441 testComparisonStd("foo", "foo");
442 testComparisonStd("foo", "f");
443 testComparisonStd("foo", "bar");
444
445 testComparisonStd("foo", "FOOZ");
446 testComparisonStd("foo", "FOO");
447 testComparisonStd("foo", "F");
448
450
451 // rare case C-string input matching SBuf with N>strlen(s)
452 {
453 char *right = xstrdup("foo34567890123456789012345678");
454 SBuf left("fooZYXWVUTSRQPONMLKJIHGFEDCBA");
455 // is 3 bytes in length. NEVER more.
456 right[3] = '\0';
457 left.setAt(3, '\0');
458
459 // pick another spot to truncate at if something goes horribly wrong.
460 right[14] = '\0';
461 left.setAt(14, '\0');
462
463 const SBuf::size_type maxN = 20 + min(left.length(), static_cast<SBuf::size_type>(strlen(right)));
464 for (SBuf::size_type n = 0; n <= maxN; ++n) {
465 if (sign(strncmp(left.rawContent(), right, n)) != sign(left.cmp(right, n)) )
466 std::cerr << std::endl << " cmp(char*) " << n << ' ' << left << " ?= " << right;
467 CPPUNIT_ASSERT_EQUAL(sign(strncmp(left.rawContent(), right, n)), sign(left.cmp(right, n)));
468 if (sign(strncasecmp(left.rawContent(), right, n)) != sign(left.caseCmp(right, n)))
469 std::cerr << std::endl << " caseCmp(char*) " << n << ' ' << left << " ?= " << right;
470 CPPUNIT_ASSERT_EQUAL(sign(strncasecmp(left.rawContent(), right, n)), sign(left.caseCmp(right, n)));
471 }
472 xfree(right);
473 }
474}
475
476void
478{
479 SBuf s1(literal),s2,s3;
480 s2=s1.consume(4);
481 s3.assign("The ");
482 CPPUNIT_ASSERT_EQUAL(s2,s3);
483 s3.assign("quick brown fox jumped over the lazy dog");
484 CPPUNIT_ASSERT_EQUAL(s1,s3);
485 s1.consume(40);
486 CPPUNIT_ASSERT_EQUAL(s1,SBuf());
487}
488
489void
491{
492 SBuf s1(literal);
493 SBuf s2(s1);
494 s2.append("foo");
495 const char *foo;
496 foo = s1.rawContent();
497 CPPUNIT_ASSERT_EQUAL(0,strncmp(fox,foo,s1.length()));
498 foo = s1.c_str();
499 CPPUNIT_ASSERT(!strcmp(fox,foo));
500}
501
502void
504{
505 SBuf s1(literal);
506 SBuf s2(fox1);
507 char *rb=s2.rawAppendStart(strlen(fox2)+1);
508 strcpy(rb,fox2);
509 s2.rawAppendFinish(rb, strlen(fox2));
510 CPPUNIT_ASSERT_EQUAL(s1,s2);
511}
512
513void
515{
516 SBuf s1(literal),s2;
517 s1.chop(4,5);
518 s2.assign("quick");
519 CPPUNIT_ASSERT_EQUAL(s1,s2);
520 s1=literal;
521 s2.clear();
522 s1.chop(5,0);
523 CPPUNIT_ASSERT_EQUAL(s1,s2);
524 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
525 SBuf a(alphabet);
526 std::string s(alphabet); // TODO
527 { //regular chopping
528 SBuf b(a);
529 b.chop(3,3);
530 SBuf ref("def");
531 CPPUNIT_ASSERT_EQUAL(ref,b);
532 }
533 { // chop at end
534 SBuf b(a);
535 b.chop(b.length()-3);
536 SBuf ref("xyz");
537 CPPUNIT_ASSERT_EQUAL(ref,b);
538 }
539 { // chop at beginning
540 SBuf b(a);
541 b.chop(0,3);
542 SBuf ref("abc");
543 CPPUNIT_ASSERT_EQUAL(ref,b);
544 }
545 { // chop to zero length
546 SBuf b(a);
547 b.chop(5,0);
548 SBuf ref("");
549 CPPUNIT_ASSERT_EQUAL(ref,b);
550 }
551 { // chop beyond end (at npos)
552 SBuf b(a);
553 b.chop(SBuf::npos,4);
554 SBuf ref("");
555 CPPUNIT_ASSERT_EQUAL(ref,b);
556 }
557 { // chop beyond end
558 SBuf b(a);
559 b.chop(b.length()+2,4);
560 SBuf ref("");
561 CPPUNIT_ASSERT_EQUAL(ref,b);
562 }
563 { // null-chop
564 SBuf b(a);
565 b.chop(0,b.length());
566 SBuf ref(a);
567 CPPUNIT_ASSERT_EQUAL(ref,b);
568 }
569 { // overflow chopped area
570 SBuf b(a);
571 b.chop(b.length()-3,b.length());
572 SBuf ref("xyz");
573 CPPUNIT_ASSERT_EQUAL(ref,b);
574 }
575}
576
577void
579{
580 SBuf s1("complete string");
581 SBuf s2(s1);
582 s2.trim(SBuf(" ,"));
583 CPPUNIT_ASSERT_EQUAL(s1,s2);
584 s2.assign(" complete string ,");
585 s2.trim(SBuf(" ,"));
586 CPPUNIT_ASSERT_EQUAL(s1,s2);
587 s1.assign(", complete string ,");
588 s2=s1;
589 s2.trim(SBuf(" "));
590 CPPUNIT_ASSERT_EQUAL(s1,s2);
591}
592
593// inspired by SBufFindTest; to be expanded.
595{
597 std::string fullReference, str;
598public:
600 SBuf ref(str);
601 CPPUNIT_ASSERT_EQUAL(ref,sb);
602 }
604 for (int offset=fullString.length()-1; offset >= 0; --offset ) {
605 for (int length=fullString.length()-1-offset; length >= 0; --length) {
606 sb=fullString.substr(offset,length);
607 str=fullReference.substr(offset,length);
609 }
610 }
611 }
612};
613
614void
616{
617 SBuf s1(literal),s2,s3;
618 s2=s1.substr(4,5);
619 s3.assign("quick");
620 CPPUNIT_ASSERT_EQUAL(s2,s3);
621 s1.chop(4,5);
622 CPPUNIT_ASSERT_EQUAL(s1,s2);
623 SBufSubstrAutoTest sat; // work done in the constructor
624}
625
626void
628{
629 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
630 SBuf s1(alphabet);
631 SBuf::size_type idx;
632 SBuf::size_type nposResult=SBuf::npos;
633
634 // FORWARD SEARCH
635 // needle in haystack
636 idx=s1.find('d');
637 CPPUNIT_ASSERT_EQUAL(3U,idx);
638 CPPUNIT_ASSERT_EQUAL('d',s1[idx]);
639
640 // needle not present in haystack
641 idx=s1.find(' '); //fails
642 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
643
644 // search in portion
645 idx=s1.find('e',3U);
646 CPPUNIT_ASSERT_EQUAL(4U,idx);
647
648 // char not in searched portion
649 idx=s1.find('e',5U);
650 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
651
652 // invalid start position
653 idx=s1.find('d',SBuf::npos);
654 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
655
656 // search outside of haystack
657 idx=s1.find('d',s1.length()+1);
658 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
659
660 // REVERSE SEARCH
661 // needle in haystack
662 idx=s1.rfind('d');
663 CPPUNIT_ASSERT_EQUAL(3U, idx);
664 CPPUNIT_ASSERT_EQUAL('d', s1[idx]);
665
666 // needle not present in haystack
667 idx=s1.rfind(' '); //fails
668 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
669
670 // search in portion
671 idx=s1.rfind('e',5);
672 CPPUNIT_ASSERT_EQUAL(4U,idx);
673
674 // char not in searched portion
675 idx=s1.rfind('e',3);
676 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
677
678 // overlong haystack specification
679 idx=s1.rfind('d',s1.length()+1);
680 CPPUNIT_ASSERT_EQUAL(3U,idx);
681}
682
683void
685{
686 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
687 SBuf haystack(alphabet);
688 SBuf::size_type idx;
689 SBuf::size_type nposResult=SBuf::npos;
690
691 // FORWARD search
692 // needle in haystack
693 idx = haystack.find(SBuf("def"));
694 CPPUNIT_ASSERT_EQUAL(3U,idx);
695
696 idx = haystack.find(SBuf("xyz"));
697 CPPUNIT_ASSERT_EQUAL(23U,idx);
698
699 // needle not in haystack, no initial char match
700 idx = haystack.find(SBuf(" eq"));
701 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
702
703 // needle not in haystack, initial sequence match
704 idx = haystack.find(SBuf("deg"));
705 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
706
707 // needle past end of haystack
708 idx = haystack.find(SBuf("xyz1"));
709 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
710
711 // search in portion: needle not in searched part
712 idx = haystack.find(SBuf("def"),7);
713 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
714
715 // search in portion: overhang
716 idx = haystack.find(SBuf("def"),4);
717 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
718
719 // invalid start position
720 idx = haystack.find(SBuf("def"),SBuf::npos);
721 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
722
723 // needle bigger than haystack
724 idx = SBuf("def").find(haystack);
725 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
726
727 // search in a double-matching haystack
728 {
729 SBuf h2=haystack;
730 h2.append(haystack);
731
732 idx = h2.find(SBuf("def"));
733 CPPUNIT_ASSERT_EQUAL(3U,idx);
734
735 idx = h2.find(SBuf("xyzab"));
736 CPPUNIT_ASSERT_EQUAL(23U,idx);
737 }
738
739 // REVERSE search
740 // needle in haystack
741 idx = haystack.rfind(SBuf("def"));
742 CPPUNIT_ASSERT_EQUAL(3U,idx);
743
744 idx = haystack.rfind(SBuf("xyz"));
745 CPPUNIT_ASSERT_EQUAL(23U,idx);
746
747 // needle not in haystack, no initial char match
748 idx = haystack.rfind(SBuf(" eq"));
749 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
750
751 // needle not in haystack, initial sequence match
752 idx = haystack.rfind(SBuf("deg"));
753 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
754
755 // needle past end of haystack
756 idx = haystack.rfind(SBuf("xyz1"));
757 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
758
759 // search in portion: needle in searched part
760 idx = haystack.rfind(SBuf("def"),7);
761 CPPUNIT_ASSERT_EQUAL(3U, idx);
762
763 // search in portion: needle not in searched part
764 idx = haystack.rfind(SBuf("mno"),3);
765 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
766
767 // search in portion: overhang
768 idx = haystack.rfind(SBuf("def"),4);
769 CPPUNIT_ASSERT_EQUAL(3U, idx);
770
771 // npos start position
772 idx = haystack.rfind(SBuf("def"),SBuf::npos);
773 CPPUNIT_ASSERT_EQUAL(3U, idx);
774
775 // needle bigger than haystack
776 idx = SBuf("def").rfind(haystack);
777 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
778
779 // search in a double-matching haystack
780 {
781 SBuf h2=haystack;
782 h2.append(haystack);
783
784 idx = h2.rfind(SBuf("def"));
785 CPPUNIT_ASSERT_EQUAL(29U,idx);
786
787 idx = h2.find(SBuf("xyzab"));
788 CPPUNIT_ASSERT_EQUAL(23U,idx);
789 }
790}
791
792void
794{
795 SBuf s1(literal);
796 SBuf::size_type idx;
797 idx=s1.rfind(' ');
798 CPPUNIT_ASSERT_EQUAL(40U,idx);
799 CPPUNIT_ASSERT_EQUAL(' ',s1[idx]);
800}
801
802void
804{
805 SBuf haystack(literal),afox("fox");
806 SBuf goobar("goobar");
807 SBuf::size_type idx;
808
809 // corner case: search for a zero-length SBuf
810 idx=haystack.rfind(SBuf(""));
811 CPPUNIT_ASSERT_EQUAL(haystack.length(),idx);
812
813 // corner case: search for a needle longer than the haystack
814 idx=afox.rfind(SBuf(" "));
815 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
816
817 idx=haystack.rfind(SBuf("fox"));
818 CPPUNIT_ASSERT_EQUAL(16U,idx);
819
820 // needle not found, no match for first char
821 idx=goobar.rfind(SBuf("foo"));
822 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
823
824 // needle not found, match for first char but no match for SBuf
825 idx=haystack.rfind(SBuf("foe"));
826 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
827
828 SBuf g("g"); //match at the last char
829 idx=haystack.rfind(g);
830 CPPUNIT_ASSERT_EQUAL(43U,idx);
831 CPPUNIT_ASSERT_EQUAL('g',haystack[idx]);
832
833 idx=haystack.rfind(SBuf("The"));
834 CPPUNIT_ASSERT_EQUAL(0U,idx);
835
836 haystack.append("The");
837 idx=haystack.rfind(SBuf("The"));
838 CPPUNIT_ASSERT_EQUAL(44U,idx);
839
840 //partial match
841 haystack="The quick brown fox";
842 SBuf needle("foxy lady");
843 idx=haystack.rfind(needle);
844 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
845}
846
847void
849{
850 SBuf s(fox);
851 CPPUNIT_ASSERT_EQUAL(strlen(fox),(size_t)s.length());
852}
853
854void
856{
857 char buf[40]; //shorter than literal()
858 SBuf s(fox1),s2;
859 CPPUNIT_ASSERT_EQUAL(s.length(),s.copy(buf,40));
860 CPPUNIT_ASSERT_EQUAL(0,strncmp(s.rawContent(),buf,s.length()));
861 s=literal;
862 CPPUNIT_ASSERT_EQUAL(40U,s.copy(buf,40));
863 s2.assign(buf,40);
864 s.chop(0,40);
865 CPPUNIT_ASSERT_EQUAL(s2,s);
866}
867
868void
870{
871 SBuf sng(ToLower(literal)),
872 ref("the quick brown fox jumped over the lazy dog");
873 CPPUNIT_ASSERT_EQUAL(ref,sng);
874 sng=literal;
875 CPPUNIT_ASSERT_EQUAL(0,sng.compare(ref,caseInsensitive));
876 // max-size comparison
877 CPPUNIT_ASSERT_EQUAL(0,ref.compare(SBuf("THE"),caseInsensitive,3));
878 CPPUNIT_ASSERT_EQUAL(1,ref.compare(SBuf("THE"),caseInsensitive,6));
879 CPPUNIT_ASSERT_EQUAL(0,SBuf("the").compare(SBuf("THE"),caseInsensitive,6));
880}
881
882void
884{
885 SBuf t;
886 t.assign("foo");
887 const char *ref=t.rawContent();
888 t.reserveCapacity(10240);
889 const char *match=t.rawContent();
890 CPPUNIT_ASSERT(match!=ref);
891 ref=match;
893 t.append(t).append(t).append(t).append(t).append(t);
894 CPPUNIT_ASSERT_EQUAL(ref,match);
895}
896
897void
899{
900 SBufReservationRequirements requirements;
901 // use unusual numbers to ensure we do not hit a lucky boundary situation
902 requirements.minSpace = 10;
903 requirements.idealSpace = 82;
904 requirements.maxCapacity = 259;
905 requirements.allowShared = true;
906
907 // for each possible starting buffer length within the capacity
908 for (SBuf::size_type startLength = 0; startLength <= requirements.maxCapacity; ++startLength) {
909 std::cerr << ".";
910 SBuf b;
911 b.reserveCapacity(startLength);
912 CPPUNIT_ASSERT_EQUAL(b.length(), static_cast<unsigned int>(0));
913 CPPUNIT_ASSERT_EQUAL(b.spaceSize(), startLength);
914
915 // check that it never grows outside capacity.
916 // do 5 excess cycles to check that.
917 for (SBuf::size_type filled = 0; filled < requirements.maxCapacity +5; ++filled) {
918 CPPUNIT_ASSERT_EQUAL(b.length(), min(filled, requirements.maxCapacity));
919 auto x = b.reserve(requirements);
920 // the amount of space advertized must not cause users to exceed capacity
921 CPPUNIT_ASSERT(x <= requirements.maxCapacity - filled);
922 CPPUNIT_ASSERT(b.spaceSize() <= requirements.maxCapacity - filled);
923 // the total size of buffer must not cause users to exceed capacity
924 CPPUNIT_ASSERT(b.length() + b.spaceSize() <= requirements.maxCapacity);
925 if (x > 0)
926 b.append('X');
927 }
928 }
929
930 // the minimal space requirement should overwrite idealSpace preferences
931 requirements.minSpace = 10;
932 for (const int delta: {-1,0,+1}) {
933 requirements.idealSpace = requirements.minSpace + delta;
934 SBuf buffer;
935 buffer.reserve(requirements);
936 CPPUNIT_ASSERT(buffer.spaceSize() >= requirements.minSpace);
937 }
938
939 // TODO: Decide whether to encapsulate the (nearly identical) code of the
940 // gap-related test cases below into a function, obscuring each case logic a
941 // little, but facilitating new test cases (and removing code duplication).
942
943 { // reserveSpace() uses the trailing space before the front gap
944 SBuf buffer(fox);
945
946 // assure there is some trailing space
947 buffer.reserveSpace(1);
948 CPPUNIT_ASSERT(buffer.spaceSize() > 0);
949
950 // create a leading gap and (weak-)check that it was created
951 const auto gap = 1U; // the smallest gap may be the most challenging
952 CPPUNIT_ASSERT(gap < buffer.length());
953 const void *gapEnd = buffer.rawContent() + gap;
954 buffer.consume(gap);
955 CPPUNIT_ASSERT_EQUAL(gapEnd, static_cast<const void*>(buffer.rawContent()));
956
957 const auto before = SBuf::GetStats();
958 const auto beforeSpaceSize = buffer.spaceSize();
959 const void * const beforePosition = buffer.rawContent();
960 buffer.reserveSpace(beforeSpaceSize);
961 const auto after = SBuf::GetStats();
962 const void * const afterPosition = buffer.rawContent();
963 CPPUNIT_ASSERT_EQUAL(before.cowAvoided + 1, after.cowAvoided);
964 CPPUNIT_ASSERT_EQUAL(before.cowShift, after.cowShift);
965 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
966 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
967 CPPUNIT_ASSERT_EQUAL(beforeSpaceSize, buffer.spaceSize());
968 CPPUNIT_ASSERT_EQUAL(beforePosition, afterPosition);
969 CPPUNIT_ASSERT(strcmp(fox + gap, buffer.c_str()) == 0);
970 }
971
972 { // reserveSpace() uses the front gap when the trailing space is not enough
973 SBuf buffer(fox);
974
975 // assure there is some trailing space to keep the test case challenging
976 buffer.reserveSpace(1);
977 CPPUNIT_ASSERT(buffer.spaceSize() > 0);
978 const void * const initialStorage = buffer.rawContent();
979
980 // create a leading gap and (weak-)check that it was created
981 const auto gap = 1U; // the smallest gap may be the most challenging
982 CPPUNIT_ASSERT(gap < buffer.length());
983 const void *gapEnd = buffer.rawContent() + gap;
984 buffer.consume(gap);
985 CPPUNIT_ASSERT_EQUAL(gapEnd, static_cast<const void*>(buffer.rawContent()));
986
987 const auto before = SBuf::GetStats();
988 const auto beforeSpaceSize = buffer.spaceSize();
989 buffer.reserveSpace(beforeSpaceSize + gap); // force (entire) gap use
990 const auto after = SBuf::GetStats();
991 const void * const afterStorage = buffer.rawContent();
992 CPPUNIT_ASSERT_EQUAL(before.cowAvoided, after.cowAvoided);
993 CPPUNIT_ASSERT_EQUAL(before.cowShift + 1, after.cowShift);
994 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
995 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
996 CPPUNIT_ASSERT_EQUAL(initialStorage, afterStorage);
997 CPPUNIT_ASSERT(beforeSpaceSize + gap <= buffer.spaceSize());
998 CPPUNIT_ASSERT(strcmp(fox + gap, buffer.c_str()) == 0);
999 }
1000
1001 { // reserveSpace() uses the entire front gap when using the front gap
1002 SBuf buffer(fox);
1003
1004 // assure there is some trailing space to keep the test case challenging
1005 buffer.reserveSpace(1);
1006 CPPUNIT_ASSERT(buffer.spaceSize() > 0);
1007 const void * const initialStorage = buffer.rawContent();
1008
1009 // create a leading gap and (weak-)check that it was created
1010 const auto gap = 2U; // the smallest extra gap may be the most challenging
1011 CPPUNIT_ASSERT(gap < buffer.length());
1012 const void *gapEnd = buffer.rawContent() + gap;
1013 buffer.consume(gap);
1014 CPPUNIT_ASSERT_EQUAL(gapEnd, static_cast<const void*>(buffer.rawContent()));
1015
1016 const auto before = SBuf::GetStats();
1017 const auto beforeSpaceSize = buffer.spaceSize();
1018 buffer.reserveSpace(beforeSpaceSize + 1); // force (minimal) gap use
1019 const auto after = SBuf::GetStats();
1020 const void * const afterStorage = buffer.rawContent();
1021 CPPUNIT_ASSERT_EQUAL(before.cowAvoided, after.cowAvoided);
1022 CPPUNIT_ASSERT_EQUAL(before.cowShift + 1, after.cowShift);
1023 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
1024 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
1025 CPPUNIT_ASSERT_EQUAL(initialStorage, afterStorage);
1026 CPPUNIT_ASSERT(beforeSpaceSize + gap <= buffer.spaceSize());
1027 CPPUNIT_ASSERT(strcmp(fox + gap, buffer.c_str()) == 0);
1028 }
1029}
1030
1031void
1033{
1034 static SBuf casebuf("THE QUICK");
1035 CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1)));
1036 CPPUNIT_ASSERT(!SBuf("The quick brown").startsWith(SBuf(fox1))); //too short
1037 CPPUNIT_ASSERT(!literal.startsWith(SBuf(fox2))); //different contents
1038
1039 // case-insensitive checks
1040 CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
1041 casebuf=ToUpper(SBuf(fox1));
1042 CPPUNIT_ASSERT(literal.startsWith(casebuf,caseInsensitive));
1043 CPPUNIT_ASSERT(literal.startsWith(SBuf(fox1),caseInsensitive));
1044 casebuf = "tha quick";
1045 CPPUNIT_ASSERT_EQUAL(false,literal.startsWith(casebuf,caseInsensitive));
1046}
1047
1048void
1050{
1051 SBuf b("const.string, int 10 and a float 10.5");
1052 SBufStream ss;
1053 ss << "const.string, int " << 10 << " and a float " << 10.5;
1054 SBuf o=ss.buf();
1055 CPPUNIT_ASSERT_EQUAL(b,o);
1056 ss.clearBuf();
1057 o=ss.buf();
1058 CPPUNIT_ASSERT_EQUAL(SBuf(),o);
1059 SBuf f1(fox1);
1060 SBufStream ss2(f1);
1061 ss2 << fox2;
1062 CPPUNIT_ASSERT_EQUAL(ss2.buf(),literal);
1063 CPPUNIT_ASSERT_EQUAL(f1,SBuf(fox1));
1064}
1065
1066void
1068{
1069 SBuf haystack(literal);
1070 SBuf::size_type idx;
1071
1072 // not found
1073 idx=haystack.findFirstOf(CharacterSet("t1","ADHRWYP"));
1074 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
1075
1076 // found at beginning
1077 idx=haystack.findFirstOf(CharacterSet("t2","THANDF"));
1078 CPPUNIT_ASSERT_EQUAL(0U,idx);
1079
1080 //found at end of haystack
1081 idx=haystack.findFirstOf(CharacterSet("t3","QWERYVg"));
1082 CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
1083
1084 //found in the middle of haystack
1085 idx=haystack.findFirstOf(CharacterSet("t4","QWERqYV"));
1086 CPPUNIT_ASSERT_EQUAL(4U,idx);
1087}
1088
1089void
1091{
1092 SBuf haystack(literal);
1093 SBuf::size_type idx;
1094
1095 // all chars from the set
1096 idx=haystack.findFirstNotOf(CharacterSet("t1",literal.c_str()));
1097 CPPUNIT_ASSERT_EQUAL(SBuf::npos,idx);
1098
1099 // found at beginning
1100 idx=haystack.findFirstNotOf(CharacterSet("t2","a"));
1101 CPPUNIT_ASSERT_EQUAL(0U,idx);
1102
1103 //found at end of haystack
1104 idx=haystack.findFirstNotOf(CharacterSet("t3",literal.substr(0,literal.length()-1).c_str()));
1105 CPPUNIT_ASSERT_EQUAL(haystack.length()-1,idx);
1106
1107 //found in the middle of haystack
1108 idx=haystack.findFirstNotOf(CharacterSet("t4","The"));
1109 CPPUNIT_ASSERT_EQUAL(3U,idx);
1110}
1111
1112void
1114{
1115 SBufFindTest test;
1116 test.run();
1117}
1118
1119void
1121{
1122 const char *alphabet="abcdefghijklmnopqrstuvwxyz";
1123 std::string astr(alphabet);
1124 SBuf sb(alphabet);
1125 CPPUNIT_ASSERT_EQUAL(astr,sb.toStdString());
1126}
1127
1128void
1130{
1131 SBuf text("foo"), text2("foo");
1132 CPPUNIT_ASSERT(text.begin() == text.begin());
1133 CPPUNIT_ASSERT(text.begin() != text.end());
1134 CPPUNIT_ASSERT(text.begin() != text2.begin());
1135 {
1136 auto i = text.begin();
1137 auto e = text.end();
1138 CPPUNIT_ASSERT_EQUAL('f', *i);
1139 CPPUNIT_ASSERT(i != e);
1140 ++i;
1141 CPPUNIT_ASSERT_EQUAL('o', *i);
1142 CPPUNIT_ASSERT(i != e);
1143 ++i;
1144 CPPUNIT_ASSERT_EQUAL('o', *i);
1145 CPPUNIT_ASSERT(i != e);
1146 ++i;
1147 CPPUNIT_ASSERT(i == e);
1148 }
1149 {
1150 auto i = text.rbegin();
1151 auto e = text.rend();
1152 CPPUNIT_ASSERT_EQUAL('o', *i);
1153 CPPUNIT_ASSERT(i != e);
1154 ++i;
1155 CPPUNIT_ASSERT_EQUAL('o', *i);
1156 CPPUNIT_ASSERT(i != e);
1157 ++i;
1158 CPPUNIT_ASSERT_EQUAL('f', *i);
1159 CPPUNIT_ASSERT(i != e);
1160 ++i;
1161 CPPUNIT_ASSERT(i == e);
1162 }
1163}
1164
1165void
1167{
1168 // same SBuf must have same hash
1169 auto hasher=std::hash<SBuf>();
1170 CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(literal));
1171
1172 // same content must have same hash
1173 CPPUNIT_ASSERT_EQUAL(hasher(literal),hasher(SBuf(fox)));
1174 CPPUNIT_ASSERT_EQUAL(hasher(SBuf(fox)),hasher(SBuf(fox)));
1175
1176 //different content should have different hash
1177 CPPUNIT_ASSERT(hasher(SBuf(fox)) != hasher(SBuf(fox1)));
1178
1179 {
1180 std::unordered_map<SBuf, int> um;
1181 um[SBuf("one")] = 1;
1182 um[SBuf("two")] = 2;
1183
1184 auto i = um.find(SBuf("one"));
1185 CPPUNIT_ASSERT(i != um.end());
1186 CPPUNIT_ASSERT(i->second == 1);
1187
1188 i = um.find(SBuf("eleventy"));
1189 CPPUNIT_ASSERT(i == um.end());
1190 }
1191}
1192
1193int
1194main(int argc, char *argv[])
1195{
1196 return TestProgram().run(argc, argv);
1197}
1198
IcmpPinger control
pinger helper contains one of these as a global object.
Definition: pinger.cc:90
SBuf ToUpper(SBuf buf)
Returns a lower-cased copy of its parameter.
Definition: SBuf.h:721
@ caseInsensitive
Definition: SBuf.h:38
SBuf ToLower(SBuf buf)
Returns an upper-cased copy of its parameter.
Definition: SBuf.h:729
@ s1
Definition: cf_gen.cc:55
optimized set of C chars, with quick membership test and merge support
Definition: CharacterSet.h:18
std::ostream & dump(std::ostream &os) const
dumps class-wide statistics
Definition: MemBlob.cc:37
static const MemBlobStats & GetStats()
obtain a const view of class-wide statistics
Definition: MemBlob.cc:149
int64_t endOffset() const
Definition: MemObject.cc:214
void run()
generates and executes cases using configuration params
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition: SBuf.h:697
bool allowShared
whether sharing our storage with others is OK
Definition: SBuf.h:709
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition: SBuf.h:707
size_type maxCapacity
do not allocate more than this
Definition: SBuf.h:708
size_type idealSpace
if allocating anyway, provide this much space
Definition: SBuf.h:706
std::ostream & dump(std::ostream &os) const
Dump statistics to an ostream.
Definition: Stats.cc:65
SBuf buf()
bytes written so far
Definition: Stream.h:41
SBufStream & clearBuf()
Clear the stream's backing store.
Definition: Stream.h:47
std::string str
Definition: testSBuf.cc:597
void performEqualityTest()
Definition: testSBuf.cc:599
std::string fullReference
Definition: testSBuf.cc:597
Definition: SBuf.h:94
char * rawAppendStart(size_type anticipatedSize)
Definition: SBuf.cc:136
int caseCmp(const SBuf &S, const size_type n) const
shorthand version for case-insensitive compare()
Definition: SBuf.h:283
const char * rawContent() const
Definition: SBuf.cc:509
static const size_type npos
Definition: SBuf.h:99
char at(size_type pos) const
Definition: SBuf.h:249
SBuf consume(size_type n=npos)
Definition: SBuf.cc:481
const char * c_str()
Definition: SBuf.cc:516
SBuf & chop(size_type pos, size_type n=npos)
Definition: SBuf.cc:530
void reserveCapacity(size_type minCapacity)
Definition: SBuf.cc:105
static const SBufStats & GetStats()
gets global statistic information
Definition: SBuf.cc:494
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:415
size_type rfind(char c, size_type endPos=npos) const
Definition: SBuf.cc:692
size_type reserve(const SBufReservationRequirements &requirements)
Definition: SBuf.cc:112
int cmp(const SBuf &S, const size_type n) const
shorthand version for compare()
Definition: SBuf.h:275
size_type findFirstNotOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:746
SBuf & trim(const SBuf &toRemove, bool atBeginning=true, bool atEnd=true)
Definition: SBuf.cc:551
size_type spaceSize() const
Definition: SBuf.h:393
size_type find(char c, size_type startPos=0) const
Definition: SBuf.cc:584
size_type findFirstOf(const CharacterSet &set, size_type startPos=0) const
Definition: SBuf.cc:723
const_iterator begin() const
Definition: SBuf.h:583
SBuf & append(const SBuf &S)
Definition: SBuf.cc:185
const_reverse_iterator rbegin() const
Definition: SBuf.h:591
void reserveSpace(size_type minSpace)
Definition: SBuf.h:440
const_iterator end() const
Definition: SBuf.h:587
bool startsWith(const SBuf &S, const SBufCaseSensitive isCaseSensitive=caseSensitive) const
Definition: SBuf.cc:442
void clear()
Definition: SBuf.cc:175
SBuf substr(size_type pos, size_type n=npos) const
Definition: SBuf.cc:576
MemBlob::size_type size_type
Definition: SBuf.h:96
void rawAppendFinish(const char *start, size_type actualSize)
Definition: SBuf.cc:144
SBuf & assign(const SBuf &S)
Definition: SBuf.cc:83
const_reverse_iterator rend() const
Definition: SBuf.h:595
void setAt(size_type pos, char toset)
Definition: SBuf.cc:328
int compare(const SBuf &S, const SBufCaseSensitive isCaseSensitive, const size_type n) const
Definition: SBuf.cc:352
implements test program's main() function while enabling customization
Definition: unitTestMain.h:26
int run(int argc, char *argv[])
Definition: unitTestMain.h:44
CPPUNIT_TEST(testAutoFind)
CPPUNIT_TEST(testRFindChar)
void testFindSBuf()
Definition: testSBuf.cc:684
void testSBufStream()
Definition: testSBuf.cc:1049
void testRawSpace()
Definition: testSBuf.cc:503
void testRFindSBuf()
Definition: testSBuf.cc:803
CPPUNIT_TEST(testFindFirstNotOf)
void testSubstr()
Definition: testSBuf.cc:615
void testStdStringOps()
Definition: testSBuf.cc:1120
void testSubscriptOpFail()
Definition: testSBuf.cc:331
CPPUNIT_TEST(testAppendCString)
CPPUNIT_TEST(testConsume)
CPPUNIT_TEST(testFindFirstOf)
void testAppendf()
Definition: testSBuf.cc:301
void testSBufConstructDestruct()
Definition: testSBuf.cc:133
void testGrow()
Definition: testSBuf.cc:883
CPPUNIT_TEST(testCopy)
void testFindChar()
Definition: testSBuf.cc:627
void testSubscriptOp()
Definition: testSBuf.cc:319
CPPUNIT_TEST(testSubscriptOp)
CPPUNIT_TEST(testAppendSBuf)
CPPUNIT_TEST_EXCEPTION(testSubscriptOpFail, TextException)
CPPUNIT_TEST(testGrow)
CPPUNIT_TEST(testChop)
void testAppendSBuf()
Definition: testSBuf.cc:238
CPPUNIT_TEST(testFindChar)
CPPUNIT_TEST(testChomp)
CPPUNIT_TEST(testSBufHash)
void testTailCopy()
void testIterators()
Definition: testSBuf.cc:1129
void testSearchFail()
CPPUNIT_TEST_SUITE_END()
CPPUNIT_TEST_SUITE(TestSBuf)
CPPUNIT_TEST(testSubstr)
CPPUNIT_TEST(testStartsWith)
void testAppendCString()
Definition: testSBuf.cc:268
CPPUNIT_TEST(testIterators)
void testPrintf()
Definition: testSBuf.cc:259
CPPUNIT_TEST(testReserve)
void testSBufConstructDestructAfterMemInit()
Definition: testSBuf.cc:213
void testAppendStdString()
Definition: testSBuf.cc:276
void testFindFirstNotOf()
Definition: testSBuf.cc:1090
void testCopy()
Definition: testSBuf.cc:855
void testConsume()
Definition: testSBuf.cc:477
CPPUNIT_TEST(testAppendf)
CPPUNIT_TEST(testStringOps)
void testComparisons()
Definition: testSBuf.cc:406
void testEqualityTest()
Definition: testSBuf.cc:220
CPPUNIT_TEST(testRFindSBuf)
CPPUNIT_TEST(testEqualityTest)
void commonInit()
CPPUNIT_TEST(testSBufConstructDestruct)
void testSBufHash()
Definition: testSBuf.cc:1166
CPPUNIT_TEST(testPrintf)
CPPUNIT_TEST(testSBufLength)
void testStringOps()
Definition: testSBuf.cc:869
void testChop()
Definition: testSBuf.cc:514
CPPUNIT_TEST(testFindSBuf)
CPPUNIT_TEST(testRawSpace)
CPPUNIT_TEST(testSBufConstructDestructAfterMemInit)
CPPUNIT_TEST(testRawContent)
void testRawContent()
Definition: testSBuf.cc:490
void testRFindChar()
Definition: testSBuf.cc:793
void testStartsWith()
Definition: testSBuf.cc:1032
CPPUNIT_TEST(testStdStringOps)
void testSBufLength()
Definition: testSBuf.cc:848
void testChomp()
Definition: testSBuf.cc:578
CPPUNIT_TEST(testSBufStream)
void testFindFirstOf()
Definition: testSBuf.cc:1067
CPPUNIT_TEST(testAppendStdString)
void testReserve()
Definition: testSBuf.cc:898
void testDumpStats()
Definition: testSBuf.cc:310
void testAutoFind()
Definition: testSBuf.cc:1113
CPPUNIT_TEST(testComparisons)
an std::runtime_error with thrower location info
Definition: TextException.h:21
A const & min(A const &lhs, A const &rhs)
void EVH(void *)
Definition: event.h:18
void Init()
Definition: old_api.cc:425
#define xfree
#define xstrdup
static bool match(const char *fn, const REList *list)
Definition: purge.cc:402
static struct stat sb
Definition: squidclient.cc:71
default hash functor to support std::unordered_map<SBuf,*>
Definition: Algorithms.h:110
int main(int argc, char *argv[])
Definition: testSBuf.cc:1194
void eventAdd(const char *, EVH *, void *, double, int, bool)
Definition: testSBuf.cc:114
static const char fox2[]
Definition: testSBuf.cc:124
static const char fox[]
Definition: testSBuf.cc:122
static int sign(int v)
Definition: testSBuf.cc:339
static void testComparisonStdFull(const char *left, const char *right)
Definition: testSBuf.cc:349
static const char fox1[]
Definition: testSBuf.cc:123
SBuf empty_sbuf
Definition: testSBuf.cc:129
CPPUNIT_TEST_SUITE_REGISTRATION(TestSBuf)
static void testComparisonStd(const char *s1, const char *s2)
Definition: testSBuf.cc:399
SBuf literal("The quick brown fox jumped over the lazy dog")
static void testComparisonStdN(const char *left, const char *right, const size_t n)
Definition: testSBuf.cc:369
static void testComparisonStdOneWay(const char *left, const char *right)
Definition: testSBuf.cc:389
SBuf text("GET http://resource.com/path HTTP/1.1\r\n" "Host: resource.com\r\n" "Cookie: laijkpk3422r j1noin \r\n" "\r\n")
const CharacterSet alpha("alpha","abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors