25 #include <unordered_map>
31 class TestSBuf :
public CPPUNIT_NS::TestFixture
125 static const char fox[] =
"The quick brown fox jumped over the lazy dog";
126 static const char fox1[] =
"The quick brown fox ";
127 static const char fox2[] =
"jumped over the lazy dog";
133 SBuf literal(
"The quick brown fox jumped over the lazy dog");
150 CPPUNIT_ASSERT_EQUAL(0U,
s1.length());
151 CPPUNIT_ASSERT_EQUAL(
SBuf(
""),
s1);
153 CPPUNIT_ASSERT_EQUAL(0,strcmp(
"",
s1.c_str()));
159 CPPUNIT_ASSERT_EQUAL(0U,
s1.length());
160 CPPUNIT_ASSERT_EQUAL(
SBuf(
""),
s1);
162 CPPUNIT_ASSERT_EQUAL(0,strcmp(
"",
s1.c_str()));
168 CPPUNIT_ASSERT_EQUAL(0U,
s1.length());
169 CPPUNIT_ASSERT_EQUAL(
SBuf(
""),
s1);
171 CPPUNIT_ASSERT_EQUAL(0,strcmp(
"",
s1.c_str()));
177 CPPUNIT_ASSERT_EQUAL(0U,
s1.length());
178 CPPUNIT_ASSERT_EQUAL(
SBuf(
""),
s1);
180 CPPUNIT_ASSERT_EQUAL(0,strcmp(
"",
s1.c_str()));
183 CPPUNIT_ASSERT_EQUAL(
literal,s5);
185 CPPUNIT_ASSERT_EQUAL(
literal,s6);
194 CPPUNIT_ASSERT_EQUAL(s3.rawContent(), s4.
rawContent());
201 CPPUNIT_ASSERT_EQUAL(
s1,s3);
204 CPPUNIT_ASSERT_EQUAL(s4,s3);
209 std::string str(
fox);
226 CPPUNIT_ASSERT_EQUAL(
s1,
s1);
227 CPPUNIT_ASSERT_EQUAL(
s1,s2);
228 s2.
assign(
"The quick brown fox jumped over the lazy doe");
229 CPPUNIT_ASSERT(!(
s1 == s2));
231 CPPUNIT_ASSERT(!(
s1 == s2));
232 CPPUNIT_ASSERT(
s1 != s2);
234 CPPUNIT_ASSERT(!(
s1 == s2));
235 CPPUNIT_ASSERT(
s1 != s2);
237 CPPUNIT_ASSERT_EQUAL(
s1,s2);
244 const char *
const rawAppendix = appendix.
rawContent();
251 CPPUNIT_ASSERT_EQUAL(s0, appendix);
256 CPPUNIT_ASSERT(
s1.rawContent() != appendix.
rawContent());
257 CPPUNIT_ASSERT(
s1 != appendix);
258 CPPUNIT_ASSERT_EQUAL(rawAppendix, appendix.
rawContent());
265 s1.Printf(
"%s:%d:%03.3f",
"fox",10,12345.67);
266 s2.
assign(
"fox:10:12345.670");
267 CPPUNIT_ASSERT_EQUAL(
s1,s2);
281 const char *alphabet=
"abcdefghijklmnopqrstuvwxyz";
285 CPPUNIT_ASSERT_EQUAL(
alpha,s);
291 control.append(alphabet,5).append(1,
'\0').append(alphabet,6,std::string::npos);
293 CPPUNIT_ASSERT_EQUAL(scontrol,s);
296 const char *alphazero=
"abcdefghijk\0mnopqrstuvwxyz";
297 SBuf s(alphazero,26);
298 std::string str(alphazero,26);
299 CPPUNIT_ASSERT_EQUAL(0,memcmp(str.data(),s.
rawContent(),26));
307 s1.appendf(
"%s:%d:%03.2f",
fox,1234,1234.56);
308 s2.
assign(
"The quick brown fox jumped over the lazy dog:1234:1234.56");
309 CPPUNIT_ASSERT_EQUAL(s2,
s1);
317 std::cout <<
"sizeof(SBuf): " <<
sizeof(
SBuf) << std::endl;
318 std::cout <<
"sizeof(MemBlob): " <<
sizeof(
MemBlob) << std::endl;
325 CPPUNIT_ASSERT_EQUAL(chg[5],
'u');
327 CPPUNIT_ASSERT_EQUAL(
literal[5],
'u');
328 CPPUNIT_ASSERT_EQUAL(chg[5],
'e');
339 std::cout << c << std::endl;
355 std::cerr << std::endl <<
" cmp(SBuf) npos " << left <<
" ?= " << right << std::endl;
356 CPPUNIT_ASSERT_EQUAL(
sign(strcmp(left, right)),
sign(
SBuf(left).cmp(
SBuf(right))));
358 if (
sign(strcmp(left, right)) !=
sign(
SBuf(left).cmp(right)))
359 std::cerr << std::endl <<
" cmp(char*) npos " << left <<
" ?= " << right << std::endl;
360 CPPUNIT_ASSERT_EQUAL(
sign(strcmp(left, right)),
sign(
SBuf(left).cmp(right)));
363 std::cerr << std::endl <<
" caseCmp(SBuf) npos " << left <<
" ?= " << right << std::endl;
364 CPPUNIT_ASSERT_EQUAL(
sign(strcasecmp(left, right)),
sign(
SBuf(left).caseCmp(
SBuf(right))));
366 if (
sign(strcasecmp(left, right)) !=
sign(
SBuf(left).caseCmp(right)))
367 std::cerr << std::endl <<
" caseCmp(char*) npos " << left <<
" ?= " << right << std::endl;
368 CPPUNIT_ASSERT_EQUAL(
sign(strcasecmp(left, right)),
sign(
SBuf(left).caseCmp(right)));
375 std::cerr << std::endl <<
" cmp(SBuf) " << n <<
' ' << left <<
" ?= " << right << std::endl;
376 CPPUNIT_ASSERT_EQUAL(
sign(strncmp(left, right, n)),
sign(
SBuf(left).cmp(
SBuf(right), n)));
378 if (
sign(strncmp(left, right, n)) !=
sign(
SBuf(left).cmp(right, n)))
379 std::cerr << std::endl <<
" cmp(char*) " << n <<
' ' <<
SBuf(left) <<
" ?= " << right << std::endl;
380 CPPUNIT_ASSERT_EQUAL(
sign(strncmp(left, right, n)),
sign(
SBuf(left).cmp(right, n)));
382 if (
sign(strncasecmp(left, right, n)) !=
sign(
SBuf(left).caseCmp(
SBuf(right), n)))
383 std::cerr << std::endl <<
" caseCmp(SBuf) " << n <<
' ' << left <<
" ?= " << right << std::endl;
384 CPPUNIT_ASSERT_EQUAL(
sign(strncasecmp(left, right, n)),
sign(
SBuf(left).caseCmp(
SBuf(right), n)));
386 if (
sign(strncasecmp(left, right, n)) !=
sign(
SBuf(left).caseCmp(right, n)))
387 std::cerr << std::endl <<
" caseCmp(char*) " << n <<
' ' <<
SBuf(left) <<
" ?= " << right << std::endl;
388 CPPUNIT_ASSERT_EQUAL(
sign(strncasecmp(left, right, n)),
sign(
SBuf(left).caseCmp(right, n)));
395 const size_t maxN = 2 +
min(strlen(left), strlen(right));
396 for (
size_t n = 0; n <= maxN; ++n) {
413 CPPUNIT_ASSERT(
s1.cmp(s2)>0);
414 CPPUNIT_ASSERT(
s1.caseCmp(s2)>0);
415 CPPUNIT_ASSERT(s2.
cmp(
s1)<0);
416 CPPUNIT_ASSERT_EQUAL(0,
s1.cmp(s2,2));
417 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2,2));
418 CPPUNIT_ASSERT(
s1 > s2);
419 CPPUNIT_ASSERT(s2 <
s1);
424 CPPUNIT_ASSERT(
s1.cmp(s2)<0);
426 CPPUNIT_ASSERT(
s1 < s2);
428 CPPUNIT_ASSERT_EQUAL(1,
SBuf(
"foolong").caseCmp(
SBuf(
"foo"), 5));
432 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2));
433 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2,2));
435 s1.assign(
"f\0oo",4);
437 CPPUNIT_ASSERT(
s1.cmp(s2) > 0);
438 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2));
439 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2,3));
440 CPPUNIT_ASSERT_EQUAL(0,
s1.caseCmp(s2,2));
441 CPPUNIT_ASSERT_EQUAL(0,
s1.cmp(s2,2));
456 char *right =
xstrdup(
"foo34567890123456789012345678");
457 SBuf left(
"fooZYXWVUTSRQPONMLKJIHGFEDCBA");
464 left.
setAt(14,
'\0');
469 std::cerr << std::endl <<
" cmp(char*) " << n <<
' ' << left <<
" ?= " << right;
472 std::cerr << std::endl <<
" caseCmp(char*) " << n <<
' ' << left <<
" ?= " << right;
485 CPPUNIT_ASSERT_EQUAL(s2,s3);
486 s3.
assign(
"quick brown fox jumped over the lazy dog");
487 CPPUNIT_ASSERT_EQUAL(
s1,s3);
489 CPPUNIT_ASSERT_EQUAL(
s1,
SBuf());
499 foo =
s1.rawContent();
500 CPPUNIT_ASSERT_EQUAL(0,strncmp(
fox,foo,
s1.length()));
502 CPPUNIT_ASSERT(!strcmp(
fox,foo));
513 CPPUNIT_ASSERT_EQUAL(
s1,s2);
522 CPPUNIT_ASSERT_EQUAL(
s1,s2);
526 CPPUNIT_ASSERT_EQUAL(
s1,s2);
527 const char *alphabet=
"abcdefghijklmnopqrstuvwxyz";
529 std::string s(alphabet);
534 CPPUNIT_ASSERT_EQUAL(ref,b);
540 CPPUNIT_ASSERT_EQUAL(ref,b);
546 CPPUNIT_ASSERT_EQUAL(ref,b);
552 CPPUNIT_ASSERT_EQUAL(ref,b);
558 CPPUNIT_ASSERT_EQUAL(ref,b);
564 CPPUNIT_ASSERT_EQUAL(ref,b);
570 CPPUNIT_ASSERT_EQUAL(ref,b);
576 CPPUNIT_ASSERT_EQUAL(ref,b);
583 SBuf s1(
"complete string");
586 CPPUNIT_ASSERT_EQUAL(
s1,s2);
587 s2.
assign(
" complete string ,");
589 CPPUNIT_ASSERT_EQUAL(
s1,s2);
590 s1.assign(
", complete string ,");
593 CPPUNIT_ASSERT_EQUAL(
s1,s2);
604 CPPUNIT_ASSERT_EQUAL(ref,
sb);
623 CPPUNIT_ASSERT_EQUAL(s2,s3);
625 CPPUNIT_ASSERT_EQUAL(
s1,s2);
632 const char *alphabet=
"abcdefghijklmnopqrstuvwxyz";
640 CPPUNIT_ASSERT_EQUAL(3U,idx);
641 CPPUNIT_ASSERT_EQUAL(
'd',
s1[idx]);
645 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
649 CPPUNIT_ASSERT_EQUAL(4U,idx);
653 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
657 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
660 idx=
s1.find(
'd',
s1.length()+1);
661 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
666 CPPUNIT_ASSERT_EQUAL(3U, idx);
667 CPPUNIT_ASSERT_EQUAL(
'd',
s1[idx]);
671 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
675 CPPUNIT_ASSERT_EQUAL(4U,idx);
679 CPPUNIT_ASSERT_EQUAL(nposResult,idx);
682 idx=
s1.rfind(
'd',
s1.length()+1);
683 CPPUNIT_ASSERT_EQUAL(3U,idx);
689 const char *alphabet=
"abcdefghijklmnopqrstuvwxyz";
690 SBuf haystack(alphabet);
697 CPPUNIT_ASSERT_EQUAL(3U,idx);
700 CPPUNIT_ASSERT_EQUAL(23U,idx);
704 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
708 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
712 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
716 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
720 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
724 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
728 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
736 CPPUNIT_ASSERT_EQUAL(3U,idx);
739 CPPUNIT_ASSERT_EQUAL(23U,idx);
745 CPPUNIT_ASSERT_EQUAL(3U,idx);
748 CPPUNIT_ASSERT_EQUAL(23U,idx);
752 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
756 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
760 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
764 CPPUNIT_ASSERT_EQUAL(3U, idx);
768 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
772 CPPUNIT_ASSERT_EQUAL(3U, idx);
776 CPPUNIT_ASSERT_EQUAL(3U, idx);
780 CPPUNIT_ASSERT_EQUAL(nposResult, idx);
788 CPPUNIT_ASSERT_EQUAL(29U,idx);
791 CPPUNIT_ASSERT_EQUAL(23U,idx);
801 CPPUNIT_ASSERT_EQUAL(40U,idx);
802 CPPUNIT_ASSERT_EQUAL(
' ',
s1[idx]);
809 SBuf goobar(
"goobar");
813 idx=haystack.rfind(
SBuf(
""));
814 CPPUNIT_ASSERT_EQUAL(haystack.length(),idx);
820 idx=haystack.rfind(
SBuf(
"fox"));
821 CPPUNIT_ASSERT_EQUAL(16U,idx);
828 idx=haystack.rfind(
SBuf(
"foe"));
832 idx=haystack.rfind(g);
833 CPPUNIT_ASSERT_EQUAL(43U,idx);
834 CPPUNIT_ASSERT_EQUAL(
'g',haystack[idx]);
836 idx=haystack.rfind(
SBuf(
"The"));
837 CPPUNIT_ASSERT_EQUAL(0U,idx);
839 haystack.append(
"The");
840 idx=haystack.rfind(
SBuf(
"The"));
841 CPPUNIT_ASSERT_EQUAL(44U,idx);
844 haystack=
"The quick brown fox";
845 SBuf needle(
"foxy lady");
846 idx=haystack.rfind(needle);
854 CPPUNIT_ASSERT_EQUAL(strlen(
fox),(
size_t)s.
length());
862 CPPUNIT_ASSERT_EQUAL(s.length(),s.copy(buf,40));
863 CPPUNIT_ASSERT_EQUAL(0,strncmp(s.rawContent(),buf,s.length()));
865 CPPUNIT_ASSERT_EQUAL(40U,s.copy(buf,40));
868 CPPUNIT_ASSERT_EQUAL(s2,s);
875 ref(
"the quick brown fox jumped over the lazy dog");
876 CPPUNIT_ASSERT_EQUAL(ref,sng);
893 CPPUNIT_ASSERT(match!=ref);
897 CPPUNIT_ASSERT_EQUAL(ref,match);
915 CPPUNIT_ASSERT_EQUAL(b.
length(),
static_cast<unsigned int>(0));
916 CPPUNIT_ASSERT_EQUAL(b.
spaceSize(), startLength);
922 auto x = b.
reserve(requirements);
924 CPPUNIT_ASSERT(x <= requirements.
maxCapacity - filled);
935 for (
const int delta: {-1,0,+1}) {
955 CPPUNIT_ASSERT(gap < buffer.
length());
956 const void *gapEnd = buffer.
rawContent() + gap;
958 CPPUNIT_ASSERT_EQUAL(gapEnd,
static_cast<const void*
>(buffer.
rawContent()));
961 const auto beforeSpaceSize = buffer.
spaceSize();
962 const void *
const beforePosition = buffer.
rawContent();
965 const void *
const afterPosition = buffer.
rawContent();
966 CPPUNIT_ASSERT_EQUAL(before.cowAvoided + 1, after.cowAvoided);
967 CPPUNIT_ASSERT_EQUAL(before.cowShift, after.cowShift);
968 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
969 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
970 CPPUNIT_ASSERT_EQUAL(beforeSpaceSize, buffer.
spaceSize());
971 CPPUNIT_ASSERT_EQUAL(beforePosition, afterPosition);
972 CPPUNIT_ASSERT(strcmp(
fox + gap, buffer.
c_str()) == 0);
981 const void *
const initialStorage = buffer.
rawContent();
985 CPPUNIT_ASSERT(gap < buffer.
length());
986 const void *gapEnd = buffer.
rawContent() + gap;
988 CPPUNIT_ASSERT_EQUAL(gapEnd,
static_cast<const void*
>(buffer.
rawContent()));
991 const auto beforeSpaceSize = buffer.
spaceSize();
994 const void *
const afterStorage = buffer.
rawContent();
995 CPPUNIT_ASSERT_EQUAL(before.cowAvoided, after.cowAvoided);
996 CPPUNIT_ASSERT_EQUAL(before.cowShift + 1, after.cowShift);
997 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
998 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
999 CPPUNIT_ASSERT_EQUAL(initialStorage, afterStorage);
1000 CPPUNIT_ASSERT(beforeSpaceSize + gap <= buffer.
spaceSize());
1001 CPPUNIT_ASSERT(strcmp(
fox + gap, buffer.
c_str()) == 0);
1010 const void *
const initialStorage = buffer.
rawContent();
1013 const auto gap = 2U;
1014 CPPUNIT_ASSERT(gap < buffer.
length());
1015 const void *gapEnd = buffer.
rawContent() + gap;
1017 CPPUNIT_ASSERT_EQUAL(gapEnd,
static_cast<const void*
>(buffer.
rawContent()));
1020 const auto beforeSpaceSize = buffer.
spaceSize();
1023 const void *
const afterStorage = buffer.
rawContent();
1024 CPPUNIT_ASSERT_EQUAL(before.cowAvoided, after.cowAvoided);
1025 CPPUNIT_ASSERT_EQUAL(before.cowShift + 1, after.cowShift);
1026 CPPUNIT_ASSERT_EQUAL(before.cowJustAlloc, after.cowJustAlloc);
1027 CPPUNIT_ASSERT_EQUAL(before.cowAllocCopy, after.cowAllocCopy);
1028 CPPUNIT_ASSERT_EQUAL(initialStorage, afterStorage);
1029 CPPUNIT_ASSERT(beforeSpaceSize + gap <= buffer.
spaceSize());
1030 CPPUNIT_ASSERT(strcmp(
fox + gap, buffer.
c_str()) == 0);
1037 static SBuf casebuf(
"THE QUICK");
1039 CPPUNIT_ASSERT(!
SBuf(
"The quick brown").startsWith(
SBuf(
fox1)));
1047 casebuf =
"tha quick";
1054 SBuf b(
"const.string, int 10 and a float 10.5");
1056 ss <<
"const.string, int " << 10 <<
" and a float " << 10.5;
1058 CPPUNIT_ASSERT_EQUAL(b,o);
1061 CPPUNIT_ASSERT_EQUAL(
SBuf(),o);
1066 CPPUNIT_ASSERT_EQUAL(f1,
SBuf(
fox1));
1081 CPPUNIT_ASSERT_EQUAL(0U,idx);
1085 CPPUNIT_ASSERT_EQUAL(haystack.
length()-1,idx);
1089 CPPUNIT_ASSERT_EQUAL(4U,idx);
1104 CPPUNIT_ASSERT_EQUAL(0U,idx);
1108 CPPUNIT_ASSERT_EQUAL(haystack.
length()-1,idx);
1112 CPPUNIT_ASSERT_EQUAL(3U,idx);
1125 const char *alphabet=
"abcdefghijklmnopqrstuvwxyz";
1126 std::string astr(alphabet);
1141 CPPUNIT_ASSERT_EQUAL(
'f', *i);
1142 CPPUNIT_ASSERT(i != e);
1144 CPPUNIT_ASSERT_EQUAL(
'o', *i);
1145 CPPUNIT_ASSERT(i != e);
1147 CPPUNIT_ASSERT_EQUAL(
'o', *i);
1148 CPPUNIT_ASSERT(i != e);
1150 CPPUNIT_ASSERT(i == e);
1155 CPPUNIT_ASSERT_EQUAL(
'o', *i);
1156 CPPUNIT_ASSERT(i != e);
1158 CPPUNIT_ASSERT_EQUAL(
'o', *i);
1159 CPPUNIT_ASSERT(i != e);
1161 CPPUNIT_ASSERT_EQUAL(
'f', *i);
1162 CPPUNIT_ASSERT(i != e);
1164 CPPUNIT_ASSERT(i == e);
1183 std::unordered_map<SBuf, int> um;
1184 um[
SBuf(
"one")] = 1;
1185 um[
SBuf(
"two")] = 2;
1187 auto i = um.find(
SBuf(
"one"));
1188 CPPUNIT_ASSERT(i != um.end());
1189 CPPUNIT_ASSERT(i->second == 1);
1191 i = um.find(
SBuf(
"eleventy"));
1192 CPPUNIT_ASSERT(i == um.end());
1201 std::copy(src.begin(), src.end(), std::back_inserter(dst));
1202 CPPUNIT_ASSERT_EQUAL(src, dst);
1207 std::copy_if(src.begin(), src.end(), std::back_inserter(dst),
1208 [](
char c) { return c !=
'o'; });
1209 CPPUNIT_ASSERT_EQUAL(
SBuf(
"The quick brwn fx jumped ver the lazy dg"), dst);