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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors