diff --git a/mozilla/xpcom/tests/windows/nsStringTest.h b/mozilla/xpcom/tests/windows/nsStringTest.h new file mode 100644 index 00000000000..76925dc9535 --- /dev/null +++ b/mozilla/xpcom/tests/windows/nsStringTest.h @@ -0,0 +1,2246 @@ + +#ifndef _STRINGTEST +#define _STRINGTEST + +#include "nsString.h" +#include +#include + +using namespace std; + +#define USE_WIDE 1 +#ifdef USE_WIDE + #define stringtype nsString + #define astringtype nsAutoString + #define chartype PRUnichar + #define stlstringtype wstring +#else + #define stringtype nsCString + #define astringtype nsCAutoString + #define chartype char + #define stlstringtype string +#endif + + +#include "windows.h" +#include + +const double gTicks = 1.0e-7; + +/************************************************************************** + + We use this stopwatch class for timing purposes. I've placed this inline + to simplify the project creation process. + + This is effectively the same stopwatch as the one used by the gecko team + for performance measurement. + + **************************************************************************/ +class CStopwatch { + +private: + enum EState { kUndefined, kStopped, kRunning }; + + double fStartRealTime; //wall clock start time + double fStopRealTime; //wall clock stop time + double fStartCpuTime; //cpu start time + double fStopCpuTime; //cpu stop time + double fTotalCpuTime; //total cpu time + double fTotalRealTime; //total real time + EState fState; //stopwatch state + +public: + CStopwatch() { + // Create a stopwatch and start it. + fState = kUndefined; + fTotalCpuTime = 0; + fTotalRealTime = 0; + Start(); + } + + void Start(bool reset = true) { + + // Start the stopwatch. If reset is kTRUE reset the stopwatch before + // starting it. Use kFALSE to continue timing after a Stop() without + // resetting the stopwatch. + + if (reset) { + fTotalCpuTime = 0; + fTotalRealTime = 0; + } + if (fState != kRunning) { + fStartRealTime = GetRealTime(); + fStartCpuTime = GetCPUTime(); + } + fState = kRunning; + } + + void Stop() { + // Stop the stopwatch. + fStopRealTime = GetRealTime(); + fStopCpuTime = GetCPUTime(); + if (fState == kRunning) { + fTotalCpuTime += fStopCpuTime - fStartCpuTime; + fTotalRealTime += fStopRealTime - fStartRealTime; + } + fState = kStopped; + + } + + void Continue() { + // Resume a stopped stopwatch. The stopwatch continues counting from the last + // Start() onwards (this is like the laptimer function). + + if (fState == kUndefined) { + printf("%s\n","stopwatch not started"); + exit(1); + } + + if (fState == kStopped) { + fTotalCpuTime -= fStopCpuTime - fStartCpuTime; + fTotalRealTime -= fStopRealTime - fStartRealTime; + } + + fState = kRunning; + + } + + void Reset() { ResetCpuTime(); ResetRealTime(); } + void ResetCpuTime(double time = 0) { Stop(); fTotalCpuTime = time; } + void ResetRealTime(double time = 0) { Stop(); fTotalRealTime = time; } + + double CpuTime() { + // Return the cputime passed between the start and stop events. If the + // stopwatch was still running stop it first. + + if (fState == kUndefined) { + printf("%s\n","stopwatch not started"); + exit(1); + } + + if (fState == kRunning) + Stop(); + + return fTotalCpuTime; + } + + void Print() { + // Print the real and cpu time passed between the start and stop events. + + double realt = RealTime(); + + int hours = int(realt / 3600); + realt -= hours * 3600; + int min = int(realt / 60); + realt -= min * 60; + int sec = int(realt); + printf("Real time %d:%d:%d, CP time %.3f", hours, min, sec, CpuTime()); + + } + + double RealTime() + { + // Return the realtime passed between the start and stop events. If the + // stopwatch was still running stop it first. + + if (fState == kUndefined) { + printf("%s\n","stopwatch not started"); + exit(1); + } + + if (fState == kRunning) + Stop(); + + return fTotalRealTime; + } + + static double GetRealTime(){ + union { + FILETIME ftFileTime; + __int64 ftInt64; + } ftRealTime; // time the process has spent in kernel mode + SYSTEMTIME st; + GetSystemTime(&st); + SystemTimeToFileTime(&st,&ftRealTime.ftFileTime); + return (double)ftRealTime.ftInt64 * gTicks; + } + + static double GetCPUTime() { + OSVERSIONINFO OsVersionInfo; + + //*-* Value Platform + //*-* ---------------------------------------------------- + //*-* VER_PLATFORM_WIN32s Win32s on Windows 3.1 + //*-* VER_PLATFORM_WIN32_WINDOWS Win32 on Windows 95 + //*-* VER_PLATFORM_WIN32_NT Windows NT + //*-* + OsVersionInfo.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + GetVersionEx(&OsVersionInfo); + if (OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { + DWORD ret; + FILETIME ftCreate, // when the process was created + ftExit; // when the process exited + + union {FILETIME ftFileTime; + __int64 ftInt64; + } ftKernel; // time the process has spent in kernel mode + + union {FILETIME ftFileTime; + __int64 ftInt64; + } ftUser; // time the process has spent in user mode + + HANDLE hProcess = GetCurrentProcess(); + ret = GetProcessTimes (hProcess, &ftCreate, &ftExit, + &ftKernel.ftFileTime, + &ftUser.ftFileTime); + if (ret != TRUE){ + ret = GetLastError (); + printf("%s 0x%lx\n"," Error on GetProcessTimes", (int)ret); + } + + /* + * Process times are returned in a 64-bit structure, as the number of + * 100 nanosecond ticks since 1 January 1601. User mode and kernel mode + * times for this process are in separate 64-bit structures. + * To convert to floating point seconds, we will: + * + * Convert sum of high 32-bit quantities to 64-bit int + */ + + return (double) (ftKernel.ftInt64 + ftUser.ftInt64) * gTicks; + } + else + return GetRealTime(); + + } + +}; + + + +static const char* kConstructorError = "constructor error"; +static const char* kComparisonError = "Comparision error!"; +static const char* kEqualsError = "Equals error!"; + +static char* kNumbers[]={"0123456789","0\01\02\03\04\05\06\07\08\09\0\0\0"}; +static char* kLetters[]={"abcdefghij","a\0b\0c\0d\0e\0f\0g\0h\0i\0j\0\0\0"}; +static char* kAAA[]={"AAA","A\0A\0A\0\0\0"}; +static char* kBBB[]={"BBB","B\0B\0B\0\0\0"}; +static char* kHello[]={"hello","h\0e\0l\0l\0o\0\0\0"}; +static char* kWSHello[]={" hello "," \0 \0h\0e\0l\0l\0o\0 \0 \0\0\0"}; + + +void getNumbers(nsStr& aString,PRBool aMultiByte){ + aString.mLength=aString.mCapacity=10; + aString.mStr=( char*)kNumbers[aMultiByte]; +} + +void getAAA(nsStr& aString,PRBool aMultiByte){ + aString.mLength=aString.mCapacity=3; + aString.mStr=( char*)kAAA[aMultiByte]; +} + +void getBBB(nsStr& aString,PRBool aMultiByte){ + aString.mLength=aString.mCapacity=3; + aString.mStr=( char*)kBBB[aMultiByte]; +} + +void getHello(nsStr& aString,PRBool aMultiByte){ + aString.mLength=aString.mCapacity=5; + aString.mStr=( char*)kHello[aMultiByte]; +} + +void getWSHello(nsStr& aString,PRBool aMultiByte){ + aString.mLength=aString.mCapacity=9; + aString.mStr=(char*)kWSHello[aMultiByte]; +} + + +/******************************************************** + + This class's only purpose in life is to test the + netscape string library. We exercise the string + API's here, and do a bit of performance testing + against the standard c++ library string (from STL). + + ********************************************************/ +class CStringTester { +public: + CStringTester() { + TestConstructors(); + TestAutoStrings(); + TestAppend(); + TestAssignAndAdd(); + TestInsert(); + TestDelete(); + TestTruncate(); + TestLogical(); + TestLexomorphic(); + TestCreators(); + TestNumerics(); + TestNSStr(); + TestCharAccessors(); + TestSearching(); + TestSubsumables(); + TestRandomOps(); + TestReplace(); + TestStringPerformance(); + TestWideStringPerformance(); + TestRegressions(); + } +protected: + int TestConstructors(); + int TestLogical(); + int TestAutoStrings(); + int TestAppend(); + int TestAssignAndAdd(); + int TestInsert(); + int TestDelete(); + int TestTruncate(); + int TestLexomorphic(); + int TestCreators(); + int TestNumerics(); + int TestCharAccessors(); + int TestSearching(); + int TestNSStr(); + int TestSubsumables(); + int TestRandomOps(); + int TestReplace(); + int TestStringPerformance(); + int TestWideStringPerformance(); + int TestRegressions(); +}; + + + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestSearching(){ + int result=0; + + + + PRUnichar pbuf[10]={'e','f','g',0}; + PRUnichar pbuf2[10]={'a','b','c',0}; + + + //Since there is so much ground to cover with searching, we use a typedef to + //allow you to vary the string type being searched... + + + stringtype theDest("abcdefghijkabc"); + nsString s1("ijk"); + nsCString c1("ijk"); + + PRInt32 pos=theDest.Find(pbuf); + NS_ASSERTION(pos==4,"Error: Find routine"); + + pos=theDest.Find(pbuf2,PR_FALSE,-1); + NS_ASSERTION(pos==0,"Error: Find routine"); + + pos=theDest.Find(pbuf2,PR_FALSE,pos+1); + NS_ASSERTION(pos==11,"Error: Find routine"); + + pos=theDest.FindChar('a'); + NS_ASSERTION(pos==0,"Error: Find routine"); + + pos=theDest.FindChar('a',PR_FALSE,pos+1); + NS_ASSERTION(pos==11,"Error: Find routine"); + + pos=theDest.Find("efg"); + NS_ASSERTION(pos==4,"Error: Find routine"); + + pos=theDest.Find("EFG",PR_TRUE); + NS_ASSERTION(pos==4,"Error: Find routine"); + + pos=theDest.FindChar('d'); + NS_ASSERTION(pos==3,"Error: Find char routine"); + + pos=theDest.Find(s1); + NS_ASSERTION(pos==8,"Error: Find char routine"); + + pos=theDest.FindCharInSet("12k"); + NS_ASSERTION(pos==10,"Error: Findcharinset routine"); + + pos=theDest.FindCharInSet(pbuf); + NS_ASSERTION(pos==4,"Error: Findcharinset routine"); + + pos=theDest.FindCharInSet(s1); + NS_ASSERTION(pos==8,"Error: Findcharinset routine"); + + pos=theDest.Find("efg",PR_FALSE,2); + NS_ASSERTION(pos==4,"Error: Find routine"); + + pos=theDest.RFindCharInSet("12k"); + NS_ASSERTION(pos==10,"Error: RFindcharinset routine"); + + pos=theDest.RFindCharInSet("xyz"); + NS_ASSERTION(pos==-1,"Error: RFindcharinset routine"); + + pos=theDest.RFindCharInSet(pbuf); + NS_ASSERTION(pos==6,"Error: RFindcharinset routine"); + + pos=theDest.RFindCharInSet(s1); + NS_ASSERTION(pos==10,"Error: RFindcharinset routine"); + + pos=theDest.RFind("efg"); + NS_ASSERTION(pos==4,"Error: RFind routine"); + + pos=theDest.RFind("xxx"); + NS_ASSERTION(pos==-1,"Error: RFind routine"); //this should fail + + pos=theDest.RFind(""); + NS_ASSERTION(pos==-1,"Error: RFind routine"); //this too should fail. + + pos=theDest.RFindChar('a',PR_FALSE,4); + NS_ASSERTION(pos==0,"Error: RFind routine"); + + + //now try searching with FindChar using offset and count... + { + stringtype s1("hello there rick"); + + PRInt32 pos=s1.FindChar('r'); //this will search from the begining, and for the length of the string. + NS_ASSERTION(pos==9,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('r',PR_FALSE,0,5); //this will search from the front using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('r',PR_FALSE,0,10); //this will search from the front using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==9,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('i',PR_FALSE,5,5); //this will search from the middle using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('i',PR_FALSE,5,10); //this will search from the middle using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==13,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('k',PR_FALSE,10,2); //this will search from near the end using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('k',PR_FALSE,10,7); //this will search from near the end using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==15,"Error: FindChar() with offset and count"); + + //now let's try a few with bad data... + + pos=s1.FindChar('k',PR_FALSE,100,2); //this will search from a bad offset. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('k',PR_FALSE,10,0); //this will search for a bad count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('k',PR_FALSE,10,20); //this will search for a bad count. THIS WILL SUCCEED! + NS_ASSERTION(pos==15,"Error: FindChar() with offset and count"); + + pos=s1.FindChar('k',PR_FALSE,10,4); //this will search for a bad count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count"); + + pos=10; + } + + //now try searching with RFindChar using offset and count... + { + stringtype s1("hello there rick"); + + PRInt32 pos=s1.RFindChar('o'); //this will search from the end, and for the length of the string. + NS_ASSERTION(pos==4,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar(' ',PR_FALSE,-1,4); //this will search from the end, and for the length of the string. + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); //THIS WILL FAIL + + pos=s1.RFindChar(' ',PR_FALSE,12,1); //this will search from the middle, and for the length of 1. + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); //THIS WILL FAIL + + pos=s1.RFindChar(' ',PR_FALSE,12,2); //this will search from the middle, and for the length of 2. + NS_ASSERTION(pos==11,"Error: RFindChar() with offset and count"); //THIS WILL SUCCEED + + pos=s1.RFindChar('o',PR_FALSE,-1,5); //this will search from the end using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar('o',PR_FALSE,-1,12); //this will search from the front using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==4,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar('l',PR_FALSE,8,2); //this will search from the middle using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar('l',PR_FALSE,8,7); //this will search from the middle using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==3,"Error: RFindChar() with offset and count"); + +//*** + + pos=s1.RFindChar('h',PR_FALSE,3,2); //this will search from near the end using count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar('h',PR_FALSE,3,7); //this will search from near the end using count. THIS WILL SUCCEED! + NS_ASSERTION(pos==0,"Error: RFindChar() with offset and count"); + + //now let's try a few with bad data... + + pos=s1.RFindChar('k',PR_FALSE,100,2); //this will search from a bad offset. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); + + pos=s1.RFindChar('k',PR_FALSE,10,0); //this will search for a bad count. THIS WILL FAIL! + NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); + + pos=10; + } + + //now try searching with Find() using offset and count... + { + stringtype s1("hello there rick"); + + PRInt32 pos= s1.Find("there",PR_FALSE,0,4); //first search from front using offset + NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL + + pos= s1.Find("there",PR_FALSE,0,8); //first search from front using count + NS_ASSERTION(pos==6,"Error: Find) with offset and count"); //THIS WILL SUCCEED + + pos= s1.Find("there",PR_FALSE,4,1); //first search from front using count + NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL + + pos= s1.Find("there",PR_FALSE,5,2); //first search from front using count + NS_ASSERTION(pos==6,"Error: Find() with offset and count"); //THIS WILL SUCCEED + + pos= s1.Find("there",PR_FALSE,6,1); //first search from front using count + NS_ASSERTION(pos==6,"Error: Find() with offset and count"); //THIS WILL SUCCEED + + pos= s1.Find("there",PR_FALSE,6,0); //first search from front using a bogus count + NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL + + pos= s1.Find("k",PR_FALSE,15,1); //first search from end using a count + NS_ASSERTION(pos==15,"Error: Find() with offset and count"); //THIS WILL SUCCEED + + pos= s1.Find("k",PR_FALSE,15,10); //first search from end using a LARGE count + NS_ASSERTION(pos==15,"Error: Find() with offset and count"); //THIS WILL SUCCEED + + pos= s1.Find("k",PR_FALSE,25,10); //first search from bogus offset using a LARGE count + NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL + + pos=10; + } + + //now try substringsearching with RFind() using offset and count... + { + nsString2 s1("abcdefghijklmnopqrstuvwxyz"); + + PRInt32 pos= s1.RFind("ghi"); //first search from end using count + NS_ASSERTION(pos==6,"Error: RFind() with offset and count"); //THIS WILL SUCCEED! + + pos= s1.RFind("nop",PR_FALSE,-1,4); //first search from end using count + NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL + + pos= s1.RFind("nop",PR_FALSE,-1,15); //first search from end using count + NS_ASSERTION(pos==13,"Error: RFind() with offset and count"); //THIS WILL SUCCEED + + pos= s1.RFind("nop",PR_FALSE,16,3); //first search from middle using count + NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL + + pos= s1.RFind("nop",PR_FALSE,16,7); //first search from middle using count + NS_ASSERTION(pos==13,"Error: RFind() with offset and count"); //THIS WILL SUCCEED + + pos= s1.RFind("nop",PR_FALSE,0,1); //first search from front using count + NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL + + pos= s1.RFind("abc",PR_FALSE,0,1); //first search from middle using count + NS_ASSERTION(pos==0,"Error: RFind() with offset and count"); //THIS WILL SUCCEED + + pos= s1.RFind("foo",PR_FALSE,10,100); //first search from front using bogus count + NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL + + pos= s1.RFind("ghi",PR_FALSE,30,1); //first search from middle using bogus offset + NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL + + pos=10; + } + + //Various UNICODE tests... + { + //do some searching against chinese unicode chars... + + PRUnichar chinese[] = {0x4e41,0x4e42, 0x4e43, 0x0000}; // 3 chinese unicode + + nsString T2(chinese); + nsString T2copy(chinese); + + pos = T2.FindCharInSet("A"); + NS_ASSERTION(kNotFound==pos,"Error in FindCharInSet"); + + pos=T2.RFindCharInSet("A",2); + NS_ASSERTION(kNotFound==pos,"Error in RFindCharInSet"); + + pos=T2.Find("A", PR_FALSE, 0, 1); + NS_ASSERTION(kNotFound==pos,"Error in Find"); + + pos=T2.RFind("A", PR_FALSE, 2, 1); + NS_ASSERTION(kNotFound==pos,"Error in RFind"); + + T2.ReplaceChar("A",' '); + NS_ASSERTION(T2==T2copy,"Error in ReplaceChar"); + + //Here's the 3rd FTang unicode test... + + static char test4[]="ABCDEF"; + static char test4b[]=" BCDEF"; + static PRUnichar test5[]={0x4e41, 0x0000}; + static PRUnichar test6[]={0x0041, 0x0000}; + + static nsCAutoString T4(test4); + static nsCAutoString T4copy(test4); + static nsCAutoString T4copyb(test4b); + static nsAutoString T5(test5); + static nsAutoString T6(test6); + + pos = T4.FindCharInSet(T5.GetUnicode()); + if(kNotFound != pos) + printf("nsCString::FindCharInSet(const PRUnichar*) error- found when it should not\n"); + + if(0 != T4.FindCharInSet(T6.GetUnicode())) + printf("nsCString::FindCharInSet(const PRUnichar*) error- not found when it should\n"); + + + if(kNotFound != T4.RFindCharInSet(T5.GetUnicode(),2)) + printf("nsCString::RFindCharInSet(const PRUnichar*) error- found when it should not\n"); + + if(0 != T4.RFindCharInSet(T6.GetUnicode(),2)) + printf("nsCString::RFindCharInSet(const PRUnichar*) error- not found when it should\n"); + + if(kNotFound != T4.Find(T5.GetUnicode(), PR_FALSE, 0, 1)) + printf("nsCString::Find(const PRUnichar*) error- found when it should not\n"); + + if(0 != T4.Find(T6.GetUnicode(), PR_FALSE, 0, 1)) + printf("nsCString::Find(const PRUnichar*) error- not found when it should\n"); + + #if 0 // nsCString::Rfind(const PRUnichar* ...) is not available somehow + if(kNotFound != T4.RFind(T5.GetUnicode(), PR_FALSE, 2, 1)) + printf("nsCString::RFind(const PRUnichar*) error- found when it should not\n"); + else + printf("nsCString::RFind(const PRUnichar*) ok\n"); + if(0 != T4.RFind(T6.GetUnicode(), PR_FALSE, 2, 1)) + printf("nsCString::RFind(const PRUnichar*) error- not found when it should\n"); + else + printf("nsCString::RFind(const PRUnichar*) ok\n"); + #endif + + T4.ReplaceChar(PRUnichar(0x4E41),PRUnichar(' ')); + if(T4 != T4copy) + printf("nsCString::ReplaceChar(PRUnichar, PRUnichar) error- replace when it should not\n"); + + T4 = test4; + T4.ReplaceChar(PRUnichar(0x0041),PRUnichar(' ')); + if(T4 != T4copyb) + printf("nsCString::ReplaceChar(PRUnichar, PRUnichar) error- not replace when it should\n"); + } + + return result; +} + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestConstructors(){ + int result=0; + PRUnichar pbuf[10]={'f','o','o',0}; + PRUnichar* buf=pbuf; + + + nsString s1("hello world"); + nsCString c1("what's up"); + + stringtype temp0; + stringtype temp1(s1); + NS_ASSERTION(temp1==s1,"Constructor error"); + + stringtype temp2(c1); + NS_ASSERTION(temp2==c1,"Constructor error"); + + stringtype temp3("hello world"); + NS_ASSERTION(temp3=="hello world","Constructor error"); + + stringtype temp4(pbuf); + NS_ASSERTION(temp4==pbuf,"Constructor error"); + + stringtype temp5('a'); + NS_ASSERTION(temp5=="a","Constructor error"); + + stringtype temp6(PRUnichar('a')); + NS_ASSERTION(temp5=="a","Constructor error"); + + //now just for fun, let's construct 2byte from 1byte and back... + { + nsCString temp0("hello"); + nsString temp1(temp0); + nsCString temp2(temp1); + } + + return result; +} + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestLogical(){ + int result=0; + stringtype temp8("aaaa"); + stringtype temp8a("AAAA"); + stringtype temp9("bbbb"); + + const char* aaaa="aaaa"; + const char* bbbb="bbbb"; + + + //First, test a known error that got checked into the tree... + { + nsString mURL("file:///c|/test/foo.txt"); + PRBool result=mURL.Equals("file:/",PR_FALSE); + NS_ASSERTION(!result,kEqualsError); + result=mURL.Equals("file:/",PR_FALSE,5); + NS_ASSERTION(result,kEqualsError); + result=mURL.Equals("file:/",PR_FALSE,-1); + NS_ASSERTION(!result,kEqualsError); + + nsString s1("rick"); + result=s1.Equals("rick",PR_FALSE,6); + result++; + } + + + { + //this little piece of code tests to see whether the PL_strcmp series works + //correctly even when we have strings whose buffers contain nulls. + + char *buf1 = "what's up \0\0 doc?"; + char *buf2 = "what's up \0\0 dog?"; + + nsString s1(buf2,17); + + PRInt32 result=s1.Compare(buf1,PR_TRUE,17); + result=s1.FindChar('?'); + result++; + } + + //First test the string compare routines... + + NS_ASSERTION(0>temp8.Compare(bbbb),kComparisonError); + NS_ASSERTION(0>temp8.Compare(temp9),kComparisonError); + NS_ASSERTION(0=temp8)),kComparisonError); + + NS_ASSERTION(((temp9>temp8) && (temp8<=temp9)),kComparisonError); + NS_ASSERTION(temp9>aaaa,kComparisonError); + + NS_ASSERTION(temp8<=temp8,kComparisonError); + NS_ASSERTION(temp8<=temp9,kComparisonError); + NS_ASSERTION(temp8<=bbbb,kComparisonError); + + NS_ASSERTION(((temp9>=temp8) && (temp8=temp8,kComparisonError); + NS_ASSERTION(temp9>=aaaa,kComparisonError); + + NS_ASSERTION(temp8.Equals(temp8),kEqualsError); + NS_ASSERTION(temp8.Equals(aaaa),kEqualsError); + + stringtype temp10(temp8); + temp10.ToUpperCase(); + NS_ASSERTION(temp8.Equals(temp10,PR_TRUE),kEqualsError); + NS_ASSERTION(temp8.Equals("AAAA",PR_TRUE),kEqualsError); + + + //now test the new string Equals APIs.. + { + nsCString s1("hello there"); + NS_ASSERTION(s1.Equals("hello there"),kEqualsError); + NS_ASSERTION(s1.Equals("hello rick",PR_FALSE,5),kEqualsError); + NS_ASSERTION(!s1.Equals("hello rick",PR_FALSE-1),kEqualsError); + + nsCString s2(""); + NS_ASSERTION(s2.Equals(""),kEqualsError); + + nsCString s3("view-source:"); + NS_ASSERTION(s3.Equals("VIEW-SOURCE:",PR_TRUE,12),kEqualsError); + } + + //now test the count argument... + { + nsString s1("rickgessner"); + nsString s2("rickricardo"); + PRInt32 result=s1.Compare(s2); //assume no case conversion, and full-length comparison... + result=s1.Compare(s2,PR_FALSE,4); + result=s1.Compare(s2,PR_FALSE,5); + + PRBool b=s1.Equals(s2); + b=s1.Equals("rick",PR_FALSE,4); + b=s1.Equals("rickz",PR_FALSE,5); + + result=10; + + nsString s3("view"); + +#define kString "view-source" + + b=s3.Equals(kString); + result=10; + } + + return result; +} + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestAssignAndAdd(){ + int result=0; + + static const char* s1="hello"; + static const char* s2="world"; + static const PRUnichar pbuf[] = {' ','w','o','r','l','d',0}; + + nsString ns1("I'm an nsString"); + nsCString nc1("I'm an nsCString"); + + nsAutoString as1("nsAutoString source"); + nsCAutoString ac1("nsCAutoString source"); + + + { + //**** Test assignments to nsString + + stringtype theDest; + theDest.Assign(theDest); //assign nsString to itself + theDest.Assign(ns1); //assign an nsString to an nsString + NS_ASSERTION(theDest==ns1,"Assignment error"); + theDest.Assign(nc1); //assign an nsCString to an nsString + NS_ASSERTION(theDest==nc1,"Assignment error"); + theDest.Assign(as1); //assign an nsAutoString to an nsString + NS_ASSERTION(theDest==as1,"Assignment error"); + theDest.Assign(ac1); //assign an nsCAutoString to an nsString + NS_ASSERTION(theDest==ac1,"Assignment error"); + theDest.Assign("simple char*"); //assign a char* to an nsString + NS_ASSERTION(theDest=="simple char*","Assignment error"); + theDest.Assign(pbuf); //assign a PRUnichar* to an nsString + NS_ASSERTION(theDest==pbuf,"Assignment error"); + theDest.Assign('!'); //assign a char to an nsString + NS_ASSERTION(theDest=="!","Assignment error"); + theDest.Assign(PRUnichar('$')); //assign a char to an nsString + NS_ASSERTION(theDest=="$","Assignment error"); + + theDest=ns1; + NS_ASSERTION(theDest==ns1,"Assignment error"); + theDest=nc1; + NS_ASSERTION(theDest==nc1,"Assignment error"); + theDest='a'; + NS_ASSERTION(theDest=="a","Assignment error"); + theDest=PRUnichar('a'); + NS_ASSERTION(theDest=="a","Assignment error"); + theDest=s1; + NS_ASSERTION(theDest==s1,"Assignment error"); + theDest=pbuf; + NS_ASSERTION(theDest==pbuf,"Assignment error"); + + } + + //test operator+()... + { + nsString s1("hello"); + nsString s2(" world"); + nsCString c1(" world"); + + stringtype theDest; + + theDest=s1+s2; + NS_ASSERTION(theDest=="hello world","Assignment error"); + + theDest=s1+c1; + NS_ASSERTION(theDest=="hello world","Assignment error"); + + theDest=s1+" world"; + NS_ASSERTION(theDest=="hello world","Assignment error"); + + theDest=s1+pbuf; + NS_ASSERTION(theDest=="hello world","Assignment error"); + + theDest=s1+'!'; + NS_ASSERTION(theDest=="hello!","Assignment error"); + + theDest=s1+PRUnichar('!'); + NS_ASSERTION(theDest=="hello!","Assignment error"); + + } + + return result; +} + + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestAppend(){ + int result=0; + + + static const char* s1="hello"; + static const char* s2="world"; + static const PRUnichar pbuf[] = {' ','w','o','r','l','d',0}; + static const PRUnichar pbuf1[] = {'a','b','c','d','l','d'}; + + + stringtype theDest; + theDest.Append((float)100.100); + NS_ASSERTION(theDest=="100.1","Append(float) error"); + + theDest.Truncate(); + theDest.Append(12345); + NS_ASSERTION(theDest=="12345","Append(int) error"); + + theDest.Truncate(); + theDest.Append(pbuf1,1); + NS_ASSERTION(theDest=="a","Append(PRUnichar*,count) error"); + + theDest.Truncate(); + theDest.Append('a'); + NS_ASSERTION(theDest=="a","Append(char) error"); + + + static const PRUnichar pbuf2[] = {'w','h','a','t','s',' ','u','p',' ','d','o','c','?',0}; + + theDest.Truncate(); + theDest.Append(pbuf,20); //try appending more chars than actual length of pbuf + NS_ASSERTION(theDest!=pbuf,"Append(PRUnichar*) error"); + //(NOTE: if you tell me to append X chars, I'll assume you really have X chars, and the length + // get's set accordingly. This test really is correct; it just seems odd. + + theDest.Truncate(0); + theDest.Append(pbuf,5); //try appending fewer chars than actual length of pbuf + NS_ASSERTION(theDest==" worl","Append(PRUnichar*) error"); + + theDest.Truncate(0); + theDest.Append(pbuf); //try appending all of pbuf + NS_ASSERTION(theDest==pbuf,"Append(PRUnichar*) error"); + + char* ss=0; + theDest.Truncate(); + theDest.Append(ss); //try appending NULL + NS_ASSERTION(theDest=="","Append(nullstr) error"); + + theDest.Append(pbuf,0); //try appending nothing + NS_ASSERTION(theDest=="","Append(nullstr) error"); + + + { + //test improvement to unichar appends... + stringtype s1("hello"); + char c='!'; + s1+=c; + NS_ASSERTION(s1=="hello!","operator+=() error"); + + c=0xfa; + s1+=c; + s1.Append(c); + + PRUnichar theChar='f'; + s1+=theChar; + + char theChar2='g'; + s1+=theChar2; + + long theLong= 1234; + s1+=theLong; + + } + + { + //this just proves we can append nulls in our buffers... + stringtype c("hello"); + stringtype s(" there"); + c.Append(s); + char buf[]={'a','b',0,'d','e'}; + s.Append(buf,5); + } + + { + nsString foo; + char c='a'; + for(int i=0;i<10;i++){ + foo+=c; + } + foo=(foo+'x'); + } + + + stringtype temp2("there"); + + theDest.Append(temp2); + theDest.Append(" xxx "); + theDest.Append(pbuf); + theDest.Append('4'); + theDest.Append(PRUnichar('Z')); + + stringtype a(s1); + stringtype b(s2); + + theDest.Truncate(); + temp2.Truncate(); + theDest=a+b; + temp2=a+"world!"; + temp2=a+pbuf; + stringtype temp3; + temp3=temp2+'!'; + + return result; +} + + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestCharAccessors(){ + int result=0; + + //first test the 2 byte version... + + + { + stringtype temp1("hello there rick"); + stringtype temp2; + + temp1.Left(temp2,10); + temp1.Mid(temp2,6,5); + temp1.Right(temp2,4); + + //Now test the character accessor methods... + stringtype theString("hello"); + PRUint32 len=theString.Length(); + PRUnichar theChar; + for(PRUint32 i=0;i2) { + int pos=theString.mLength/2; + theSTLString.insert(pos,str[index],4); + theString.Insert(str[index],pos); + } + break; + case 6: + case 7: + case 8: + case 9: + if(theString.mLength>10) { + int len=theString.mLength/2; + int pos=theString.mLength/4; + theSTLString.erase(pos,len); + theString.Cut(pos,len); + } + break; + + } //for + if(!theString.Equals(theSTLString.c_str())) { + printf("oops!\n"); + exit(1); + } + + if(theString.mLength>300) { + theString.Truncate(); + theSTLString.erase(); + } + } + + return result; +} + + +/** + * + * @update gess10/30/98 + * @param + * @return + */ +int CStringTester::TestReplace(){ + int result=0; + + const char* find=".."; + const char* rep= "+"; + + nsCString s("hello..there..rick..gessner."); + s.ReplaceSubstring(find,rep); + s.ReplaceSubstring(rep,find); + + return result; +} + +/** + * This method tests the performance of various methods. + * + * + * @return + */ +int CStringTester::TestWideStringPerformance() { + + cout << endl << endl << "Widestring Performance Tests..." << endl; + + char* libname[] = {"STL","nsString",0}; + + //************************************************** + //Test append("abcde") against STL::wstring... + //************************************************** + { + + PRUnichar pbuf[10]={'a','b','c','d','e',0}; + + CStopwatch theSW1; + theSW1.Start(); + for(int i=0;i<1000;i++){ + nsString s; + for(int j=0;j<200;j++){ + s.Append("abcde"); + } + } + theSW1.Stop(); + + wchar_t wbuf[10] = {'a','b','c','d','e',0}; + + CStopwatch theSW2; + theSW2.Start(); + for(i=0;i<1000;i++){ + wstring s; + for(int j=0;j<200;j++){ + s.append(wbuf); + } + } + theSW2.Stop(); + + cout << " Append(\"abcde\"); nsString: " << theSW1.CpuTime() << " STL::wstring: " << theSW2.CpuTime() << endl; + int x=0; + } + + //************************************************** + //Test append(char) against STL::wstring + //************************************************** + { + + CStopwatch theSW1; + theSW1.Start(); + for(int i=0;i<500;i++){ + nsString s; + for(int j=0;j<200;j++){ + s.Append('a'); + } + } + theSW1.Stop(); + + + CStopwatch theSW2; + theSW2.Start(); + for(i=0;i<500;i++){ + wstring s; + wchar_t theChar('a'); + for(int j=0;j<200;j++){ + s.append('a',1); + } + } + theSW2.Stop(); + + cout << " Append('a'); nsString: " << theSW1.CpuTime() << " STL::wstring: " << theSW2.CpuTime() << endl; + int x=0; + } + + //************************************************** + //Test insert("123") against STL::wstring + //************************************************** + { + + PRUnichar pbuf1[10]={'a','b','c','d','e','f',0}; + PRUnichar pbuf2[10]={'1','2','3',0}; + + CStopwatch theSW1; + theSW1.Start(); + for(int i=0;i<1000;i++){ + nsString s("abcdef"); + int inspos=3; + for(int j=0;j<100;j++){ + s.Insert(pbuf2,inspos); + inspos+=3; + } + } + theSW1.Stop(); + + + CStopwatch theSW2; + theSW2.Start(); + + wchar_t wbuf1[10] = {'a','b','c','d','e','f',0}; + wchar_t wbuf2[10] = {'1','2','3',0}; + + for(i=0;i<1000;i++){ + wstring s(wbuf1); + int inspos=3; + for(int j=0;j<100;j++){ + s.insert(inspos,wbuf2); + } + } + theSW2.Stop(); + + cout << " Insert(\"123\"); nsString: " << theSW1.CpuTime() << " STL::wstring: " << theSW2.CpuTime() << endl; + int x=0; + } + + //************************************************** + //Let's test substring searching performance... + //************************************************** + { + PRUnichar pbuf1[] = {'a','a','a','a','a','a','a','a','a','a','b',0}; + PRUnichar pbuf2[] = {'a','a','b',0}; + + nsString s(pbuf1); + nsString target(pbuf2); + + CStopwatch theSW1; + theSW1.Start(); + for(int i=-1;i<1000000;i++) { + PRInt32 result=s.Find(target,PR_FALSE,i); + } + theSW1.Stop(); + + wchar_t wbuf1[] = {'a','a','a','a','a','a','a','a','a','a','b',0}; + wchar_t wbuf2[] = {'a','a','b',0}; + wstring ws(wbuf1); + wstring wtarget(wbuf2); + + CStopwatch theSW2; + theSW2.Start(); + for(i=-1;i<1000000;i++) { + PRInt32 result=ws.find(wtarget,0); + } + theSW2.Stop(); + + cout << " Find(\"aab\"); nsString: " << theSW1.CpuTime() << " STL::wstring: " << theSW2.CpuTime() << endl; + } + + //************************************************** + //Now let's test comparisons... + //************************************************** + { + nsString s("aaaaaaaaaaaaaaaaaaab"); + PRUnichar target[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','b',0}; + size_t theLen=(sizeof(target)-1)/2; + + CStopwatch theSW1; + theSW1.Start(); + int result=0; + for(int i=-1;i<1000000;i++) { + result=s.Compare(target,PR_FALSE,theLen); + result++; + } + theSW1.Stop(); + + wchar_t buf[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','b',0}; + wstring ws(buf); + wchar_t wtarget[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','b',0}; + + CStopwatch theSW2; + theSW2.Start(); + for(i=-1;i<1000000;i++) { + result=ws.compare(0,theLen,wtarget); + result++; + } + theSW2.Stop(); + + cout << " Compare(\"aaaaaaaaaaaaaab\"); nsString: " << theSW1.CpuTime() << " STL:wstring: " << theSW2.CpuTime() << endl; + + } + + //************************************************** + //Now lets test string deletions... + //************************************************** + { + + int strcount=6000; + int outerIter=200; + int innerIter=1000; + + PRUnichar pbuf[] = {'1','2','3','4','5','6','7','8','9','0',0}; + nsString source1; //build up our target string... + for(int i=0;i"); + PRInt32 result=s.Find("",PR_TRUE); + + //this was a known bug... + { + nsString s0(""); + PRInt32 pos=s0.RFind("-->"); + nsString s1("debug"); + pos=s1.RFind("b"); + pos=s1.RFind("de",PR_FALSE,1); + pos=10; + } + + //this was a known bug... + { + nsString s0("RDF:RDF"); + PRInt32 pos=s0.Find(":"); + pos=10; + } + + return result; +} + +#endif +