Another patch from Oliver Tappe: BString behaves better when the user supplies out-of bounds values in Insert(), Remove(), etc.
Code is refactored, and it fully complies with our guidelines. Tests have been updated too (hint: try the replace tests with R5 and our implementation...) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5348 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2002, OpenBeOS
|
||||
// Copyright (c) 2001-2003, OpenBeOS
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
@@ -319,6 +319,14 @@ private:
|
||||
void _AssertNotUsingAsCString() const {}
|
||||
#endif
|
||||
|
||||
char *_Alloc( int32);
|
||||
|
||||
struct PosVect;
|
||||
void _ReplaceAtPositions( const PosVect* positions,
|
||||
int32 searchLen,
|
||||
const char* with,
|
||||
int32 withLen);
|
||||
|
||||
protected:
|
||||
char *_privateData;
|
||||
};
|
||||
|
||||
+556
-485
File diff suppressed because it is too large
Load Diff
@@ -99,7 +99,7 @@ StringAppendTest::PerformTest(void)
|
||||
str1 = new BString("Base");
|
||||
str1->Append("APPENDED", 40);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "BaseAPPENDED") == 0);
|
||||
CPPUNIT_ASSERT(str1->Length() == strlen("BaseAPPENDED"));
|
||||
CPPUNIT_ASSERT(str1->Length() == (int32)strlen("BaseAPPENDED"));
|
||||
delete str1;
|
||||
|
||||
//char ptr is NULL
|
||||
@@ -115,6 +115,25 @@ StringAppendTest::PerformTest(void)
|
||||
str1->Append('C', 5);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "BaseCCCCC") == 0);
|
||||
delete str1;
|
||||
|
||||
const int32 OUT_OF_MEM_VAL = 2*1000*1000*1000;
|
||||
#ifndef TEST_R5
|
||||
//Append(char, int32) with excessive length:
|
||||
NextSubTest();
|
||||
str1 = new BString("Base");
|
||||
str1->Append('C', OUT_OF_MEM_VAL);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "Base") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
#ifndef TEST_R5
|
||||
//Append(char*, int32) with excessive length:
|
||||
NextSubTest();
|
||||
str1 = new BString("Base");
|
||||
str1->Append("some more text", OUT_OF_MEM_VAL);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "Basesome more text") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,25 @@ StringAssignTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(str->Length() == 2);
|
||||
CPPUNIT_ASSERT(strcmp(newstring.String(), "") == 0);
|
||||
delete str;
|
||||
|
||||
const int32 OUT_OF_MEM_VAL = 2*1000*1000*1000;
|
||||
#ifndef TEST_R5
|
||||
//SetTo(char, int32) with excessive length:
|
||||
NextSubTest();
|
||||
str = new BString("dummy");
|
||||
str->SetTo('C', OUT_OF_MEM_VAL);
|
||||
CPPUNIT_ASSERT(strcmp(str->String(), "dummy") == 0);
|
||||
delete str;
|
||||
#endif
|
||||
|
||||
#ifndef TEST_R5
|
||||
//SetTo(char*, int32) with excessive length:
|
||||
NextSubTest();
|
||||
str = new BString("dummy");
|
||||
str->SetTo("some more text", OUT_OF_MEM_VAL);
|
||||
CPPUNIT_ASSERT(strcmp(str->String(), "some more text") == 0);
|
||||
delete str;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ StringEscapeTest::~StringEscapeTest()
|
||||
void
|
||||
StringEscapeTest::PerformTest(void)
|
||||
{
|
||||
BString *string1, *string2;
|
||||
BString *string1;
|
||||
|
||||
//CharacterEscape(char*, char)
|
||||
NextSubTest();
|
||||
|
||||
@@ -26,12 +26,15 @@ StringInsertTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "StrINSERTEDing") == 0);
|
||||
delete str1;
|
||||
|
||||
//This test crashes both implementations
|
||||
//NextSubTest();
|
||||
//str1 = new BString("String");
|
||||
//str1->Insert("INSERTED", 10);
|
||||
//CPPUNIT_ASSERT(strcmp(str1->String(), "string") == 0);
|
||||
//delete str1;
|
||||
#ifndef TEST_R5
|
||||
// This test crashes R5 and should drop into the debugger in OpenBeOS
|
||||
// (if compiled with DEBUG):
|
||||
NextSubTest();
|
||||
str1 = new BString("String");
|
||||
str1->Insert("INSERTED", 10);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "String") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
NextSubTest();
|
||||
str1 = new BString;
|
||||
@@ -39,6 +42,15 @@ StringInsertTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "NSERTED") == 0);
|
||||
delete str1;
|
||||
|
||||
#ifndef TEST_R5
|
||||
// check limitation of negative values (R5 doesn't):
|
||||
NextSubTest();
|
||||
str1 = new BString;
|
||||
str1->Insert("INSERTED", -142364253);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
//&Insert(const char *, int32 length, int32 pos);
|
||||
NextSubTest();
|
||||
str1 = new BString("string");
|
||||
@@ -46,12 +58,15 @@ StringInsertTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "stINring") == 0);
|
||||
delete str1;
|
||||
|
||||
//This test crashes both implementations
|
||||
//NextSubTest();
|
||||
//str1 = new BString("string");
|
||||
//str1->Insert("INSERTED", 2, 30);
|
||||
//CPPUNIT_ASSERT(strcmp(str1->String(), "stINring") == 0);
|
||||
//delete str1;
|
||||
#ifndef TEST_R5
|
||||
// This test crashes R5 and should drop into the debugger in OpenBeOS
|
||||
// (if compiled with DEBUG):
|
||||
NextSubTest();
|
||||
str1 = new BString("string");
|
||||
str1->Insert("INSERTED", 2, 30);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "string") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
NextSubTest();
|
||||
str1 = new BString("string");
|
||||
@@ -73,6 +88,13 @@ StringInsertTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "strPPPPPing") == 0);
|
||||
delete str1;
|
||||
|
||||
//Insert(char c, int32 count, int32 pos)
|
||||
NextSubTest();
|
||||
str1 = new BString("string");
|
||||
str1->Insert('P', 5, -2);
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "PPPstring") == 0);
|
||||
delete str1;
|
||||
|
||||
//Insert(BString&)
|
||||
NextSubTest();
|
||||
str1 = new BString("string");
|
||||
|
||||
@@ -86,11 +86,11 @@ StringRemoveTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "a String") == 0);
|
||||
delete string1;
|
||||
|
||||
//from + length is > Length()
|
||||
//from + length exceeds Length() (R5 fails)
|
||||
NextSubTest();
|
||||
string1 = new BString("a String");
|
||||
string1->Remove(4, 30);
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "a String") == 0);
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "a St") == 0);
|
||||
delete string1;
|
||||
|
||||
NextSubTest();
|
||||
@@ -223,7 +223,7 @@ StringRemoveTest::PerformTest(void)
|
||||
string2 = new BString("string");
|
||||
string2->MoveInto(*string1, 0, 200);
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "string") == 0);
|
||||
CPPUNIT_ASSERT(strcmp(string2->String(), "string") == 0);
|
||||
CPPUNIT_ASSERT(strcmp(string2->String(), "") == 0);
|
||||
delete string1;
|
||||
delete string2;
|
||||
|
||||
@@ -242,7 +242,7 @@ StringRemoveTest::PerformTest(void)
|
||||
memset(dest, 0, 100);
|
||||
string1->MoveInto(dest, 0, 50);
|
||||
CPPUNIT_ASSERT(strcmp(dest, "some text") == 0);
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "some text") == 0);
|
||||
CPPUNIT_ASSERT(strcmp(string1->String(), "") == 0);
|
||||
delete string1;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ StringReplaceTest::~StringReplaceTest()
|
||||
void
|
||||
StringReplaceTest::PerformTest(void)
|
||||
{
|
||||
BString *str1, *str2;
|
||||
BString *str1;
|
||||
const int32 sz = 1024*50;
|
||||
char* buf;
|
||||
|
||||
//&ReplaceFirst(char, char);
|
||||
NextSubTest();
|
||||
@@ -253,6 +255,15 @@ StringReplaceTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "ccccccccccccccc") == 0);
|
||||
delete str1;
|
||||
|
||||
#ifndef TEST_R5
|
||||
//ReplaceSet(const char*, const char*)
|
||||
NextSubTest();
|
||||
str1 = new BString("abcd abcd abcd");
|
||||
str1->ReplaceSet("abcd ", "");
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
#ifndef TEST_R5
|
||||
//ReplaceSet(const char*, const char*)
|
||||
NextSubTest();
|
||||
@@ -261,6 +272,66 @@ StringReplaceTest::PerformTest(void)
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "dabcda dabcda dabcda") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
#ifndef TEST_R5
|
||||
//ReplaceSet(const char*, const char*)
|
||||
NextSubTest();
|
||||
str1 = new BString("abcd abcd abcd");
|
||||
str1->ReplaceSet("ad", "");
|
||||
CPPUNIT_ASSERT(strcmp(str1->String(), "bc bc bc") == 0);
|
||||
delete str1;
|
||||
#endif
|
||||
|
||||
// we repeat some test, but this time with a bit of data
|
||||
// to test the performance:
|
||||
|
||||
// ReplaceSet(const char*, const char*)
|
||||
NextSubTest();
|
||||
str1 = new BString();
|
||||
buf = str1->LockBuffer(sz);
|
||||
memset( buf, 'x', sz);
|
||||
str1->UnlockBuffer( sz);
|
||||
str1->ReplaceSet("x", "y");
|
||||
CPPUNIT_ASSERT(str1->Length() == sz);
|
||||
delete str1;
|
||||
|
||||
NextSubTest();
|
||||
str1 = new BString();
|
||||
buf = str1->LockBuffer(sz);
|
||||
memset( buf, 'x', sz);
|
||||
str1->UnlockBuffer( sz);
|
||||
str1->ReplaceSet("x", "");
|
||||
CPPUNIT_ASSERT(str1->Length() == 0);
|
||||
delete str1;
|
||||
|
||||
// ReplaceAll(const char*, const char*)
|
||||
NextSubTest();
|
||||
str1 = new BString();
|
||||
buf = str1->LockBuffer(sz);
|
||||
memset( buf, 'x', sz);
|
||||
str1->UnlockBuffer( sz);
|
||||
str1->ReplaceAll("x", "y");
|
||||
CPPUNIT_ASSERT(str1->Length() == sz);
|
||||
delete str1;
|
||||
|
||||
NextSubTest();
|
||||
str1 = new BString();
|
||||
buf = str1->LockBuffer(sz);
|
||||
memset( buf, 'x', sz);
|
||||
str1->UnlockBuffer( sz);
|
||||
str1->ReplaceAll("xx", "y");
|
||||
CPPUNIT_ASSERT(str1->Length() == sz/2);
|
||||
delete str1;
|
||||
|
||||
NextSubTest();
|
||||
str1 = new BString();
|
||||
buf = str1->LockBuffer(sz);
|
||||
memset( buf, 'x', sz);
|
||||
str1->UnlockBuffer( sz);
|
||||
str1->ReplaceSet("xx", "");
|
||||
CPPUNIT_ASSERT(str1->Length() == 0);
|
||||
delete str1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user