diff --git a/mozilla/xpcom/tests/StringFactoringTests/StringTest.Prefix b/mozilla/xpcom/tests/StringFactoringTests/StringTest.Prefix new file mode 100644 index 00000000000..4290c83c3de --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/StringTest.Prefix @@ -0,0 +1,4 @@ +// StringTest.Prefix + +#define SCC_TESTS +#define NEW_STRING_APIS diff --git a/mozilla/xpcom/tests/StringFactoringTests/StringTest.mcp b/mozilla/xpcom/tests/StringFactoringTests/StringTest.mcp new file mode 100644 index 00000000000..d57a61b829c Binary files /dev/null and b/mozilla/xpcom/tests/StringFactoringTests/StringTest.mcp differ diff --git a/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix new file mode 100644 index 00000000000..b6ca50d3e37 --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix @@ -0,0 +1,3 @@ +// StringTestProfileNew.Prefix + +#include "StringTest.Prefix" diff --git a/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix new file mode 100644 index 00000000000..ed7d2c0c4fe --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix @@ -0,0 +1,4 @@ +// StringTestProfileOld.Prefix + +#include "StringTest.Prefix" +#undef NEW_STRING_APIS diff --git a/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix new file mode 100644 index 00000000000..e24f036db88 --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix @@ -0,0 +1,5 @@ +// StringTestProfileOld.Prefix + +#include "StringTest.Prefix" +#undef NEW_STRING_APIS +#define TEST_STD_STRING diff --git a/mozilla/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h b/mozilla/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h new file mode 100644 index 00000000000..3e75e433639 --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Scott Collins + */ + +#ifndef _nsStdStringWrapper_h__ +#define _nsStdStringWrapper_h__ + +#include +#include "nsAWritableString.h" + + +template +class nsStringAllocator + : public std::allocator // temporarily + { + // ... + }; + + +template < class CharT, class TraitsT = char_traits, class AllocatorT = nsStringAllocator > +class basic_nsStdStringWrapper + : public basic_nsAWritableString + /* + ... + */ + { + protected: + std::basic_string mRawString; + + typedef typename basic_nsAWritableString::FragmentRequest FragmentRequest; + typedef typename basic_nsAWritableString::ConstFragment ConstFragment; + typedef typename basic_nsAWritableString::Fragment Fragment; + + typedef std::basic_string basic_string_t; + + using typename basic_string_t::traits_type; + using typename basic_string_t::value_type; + using typename basic_string_t::allocator_type; + using typename basic_string_t::size_type; + using typename basic_string_t::difference_type; + using typename basic_string_t::reference; + using typename basic_string_t::const_reference; + using typename basic_string_t::pointer; + using typename basic_string_t::const_pointer; + using typename basic_string_t::iterator; + using typename basic_string_t::const_iterator; + using typename basic_string_t::reverse_iterator; + using typename basic_string_t::const_reverse_iterator; + + static const size_type npos = size_type(-1); + + protected: + virtual const char* Implementation() const; + + virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const; + virtual CharT* GetFragment( Fragment&, FragmentRequest, PRUint32 ); + + public: + explicit + basic_nsStdStringWrapper( const AllocatorT& a = AllocatorT() ) + : mRawString(a) + { + } + + basic_nsStdStringWrapper( const basic_nsAReadableString& str ) + : mRawString(str.Begin(), str.End()) + { + } + + basic_nsStdStringWrapper( const basic_string_t& str, size_type pos = 0, size_type n = npos ) + : mRawString(str, pos, n) + { + } + + basic_nsStdStringWrapper( const basic_string_t& str, size_type pos, size_type n, const AllocatorT& a ) + : mRawString(str, pos, n, a) + { + } + + basic_nsStdStringWrapper( const CharT* s, size_type n, const AllocatorT& a = AllocatorT() ) + : mRawString(s, n, a) + { + } + + basic_nsStdStringWrapper( const CharT* s, const AllocatorT& a = AllocatorT() ) + : mRawString(s, a) + { + } + + basic_nsStdStringWrapper( size_type n, CharT c, const AllocatorT& a = AllocatorT() ) + : mRawString(n, c, a) + { + } + + + virtual + PRUint32 + Length() const + { + return mRawString.length(); + } + + virtual + void + SetCapacity( PRUint32 aNewCapacity ) + { + mRawString.reserve(aNewCapacity); + } + + virtual + void + SetLength( PRUint32 aNewLength ) + { + mRawString.resize(aNewLength); + } + + virtual void Assign( const basic_nsAReadableString& ); + virtual void Append( const basic_nsAReadableString& ); + virtual void AppendChar( CharT ); + virtual void Insert( const basic_nsAReadableString&, PRUint32 pos ); + virtual void Cut( PRUint32 pos, PRUint32 len ); + + // ... + }; + +NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) + + + +template +const char* +basic_nsStdStringWrapper::Implementation() const + { + static const char* implementation = "nsStdStringWrapper"; + return implementation; + } + + +template +const CharT* +basic_nsStdStringWrapper::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const + { + switch ( aRequest ) + { + case kFirstFragment: + case kLastFragment: + case kFragmentAt: + aFragment.mEnd = (aFragment.mStart = mRawString.data()) + mRawString.length(); + return aFragment.mStart + aOffset; + + case kPrevFragment: + case kNextFragment: + default: + return 0; + } + } + +template +CharT* +basic_nsStdStringWrapper::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) + { + switch ( aRequest ) + { + case kFirstFragment: + case kLastFragment: + case kFragmentAt: + aFragment.mEnd = (aFragment.mStart = NS_CONST_CAST(CharT*, mRawString.data())) + mRawString.length(); + return aFragment.mStart + aOffset; + + case kPrevFragment: + case kNextFragment: + default: + return 0; + } + } + +template +void +basic_nsStdStringWrapper::Assign( const basic_nsAReadableString& rhs ) + { + typedef basic_nsStdStringWrapper this_t; + + if ( rhs.Implementation() == Implementation() ) + mRawString = NS_STATIC_CAST(this_t, rhs).mRawString; + else + mRawString.assign(rhs.Begin(), rhs.End()); + } + +template +void +basic_nsStdStringWrapper::Append( const basic_nsAReadableString& rhs ) + { + mRawString.append(rhs.Begin(), rhs.End()); + } + +template +void +basic_nsStdStringWrapper::AppendChar( CharT c ) + { + mRawString.append(1, c); + } + +template +void +basic_nsStdStringWrapper::Insert( const basic_nsAReadableString& rhs, PRUint32 atPosition ) + { + mRawString.insert(mRawString.begin()+atPosition, rhs.Begin(), rhs.End()); + } + +template +void +basic_nsStdStringWrapper::Cut( PRUint32 cutStart, PRUint32 cutLength ) + { + mRawString.erase(cutStart, cutLength); + } + + + +typedef basic_nsStdStringWrapper nsStdString; +typedef basic_nsStdStringWrapper nsStdCString; + + +#endif // !defined(_basic_nsStdStringWrapper_h__) diff --git a/mozilla/xpcom/tests/StringFactoringTests/profile_main.cpp b/mozilla/xpcom/tests/StringFactoringTests/profile_main.cpp new file mode 100644 index 00000000000..bfc8dc37113 --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/profile_main.cpp @@ -0,0 +1,353 @@ +// profile_main.cpp + +#include "nscore.h" +#include "prlong.h" +#include +#include +#include + +#ifndef TEST_STD_STRING +#include "nsString.h" +#else +#include "nsStdStringWrapper.h" +typedef nsStdCString nsCString; +#endif + +#include + +static const int kTestSucceeded = 0; +static const int kTestFailed = 1; + + +template +inline +PRUint32 +TotalLength( const T& s ) + { + return s.Length(); + } + +template <> +inline +PRUint32 +TotalLength( const string& s ) + { + return s.length(); + } + +template +inline +PRUint32 +Find( const T& text, const T& pattern ) + { + return text.Find(pattern); + } + +template <> +inline +PRUint32 +Find( const string& text, const string& pattern ) + { + return text.find(pattern); + } + +inline +UnsignedWide +operator-( const UnsignedWide& lhs, const UnsignedWide& rhs ) + { + PRInt64 a = LL_INIT(lhs.hi, lhs.lo); + PRInt64 b = LL_INIT(rhs.hi, rhs.lo); + PRInt64 c; + LL_SUB(c, a, b); + + UnsignedWide result = {c.hi, c.lo}; + + return result; + } + +class TestTimer + { + public: + TestTimer() { Microseconds(&mStartTime); } + + ~TestTimer() + { + UnsignedWide stopTime; + Microseconds(&stopTime); + UnsignedWide totalTime = stopTime - mStartTime; + if ( totalTime.hi ) + cout << "*"; + cout << setw(10) << totalTime.lo << " µs : "; + } + + private: + UnsignedWide mStartTime; + }; + +static +int +test_concat() + { + //---------|---------|---------|---------|---------|---------|---------| + nsCString s1("This is a reasonable length string with some text in it and it is good."); + nsCString s2("This is another string that I will use in the concatenation test."); + nsCString s3("This is yet a third string that I will use in the concatenation test."); + + PRUint32 len = TotalLength( s1 + s2 + s3 + s1 + s2 + s3 ); + if ( len != (71 + 65 + 69 + 71 + 65 + 69) ) + { + cout << "|test_concat()| FAILED" << endl; + return kTestFailed; + } + + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + len += TotalLength( s1 + s2 + s3 + s1 + s2 + s3 ); + } + cout << "TotalLength( s1 + s2 + s3 + s1 + s2 + s3 )" << endl; + + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + len += TotalLength( s1 + s2 ); + } + cout << "TotalLength( s1 + s2 )" << endl; + + return kTestSucceeded; + } + +static +int +test_concat_and_assign() + { + //---------|---------|---------|---------|---------|---------|---------| + nsCString s1("This is a reasonable length string with some text in it and it is good."); + nsCString s2("This is another string that I will use in the concatenation test."); + nsCString s3("This is yet a third string that I will use in the concatenation test."); + + nsCString s4 = s1 + s2 + s3 + s1 + s2 + s3; + if ( TotalLength(s4) != (71 + 65 + 69 + 71 + 65 + 69) ) + { + cout << "|test_concat()| FAILED" << endl; + return kTestFailed; + } + + + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + s4 = s1 + s2 + s3 + s1 + s2 + s3; + } + cout << "s4 = s1 + s2 + s3 + s1 + s2 + s3" << endl; + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + s4 = s1 + s2; + } + cout << "s4 = s1 + s2" << endl; + + + return kTestSucceeded; + } + +static +int +test_compare() + { + nsCString s1("This is a reasonable length string with some text in it and it is good."); + nsCString s2("This is a reasonable length string with some text in it and it is bad."); + + int count = 0; + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + if ( s1 > s2 ) + ++count; + } + cout << "s1 > s2" << endl; + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + if ( s1 == s1 ) + ++count; + } + cout << "s1 == s1" << endl; + + return kTestSucceeded; + } + +static +int +test_countchar() + { + nsCString s1("This is a reasonable length string with some text in it and it is good."); + + if ( s1.CountChar('e') != 5 ) + { + cout << "|test_countchar()| FAILED: found a count of " << s1.CountChar('e') << endl; + return kTestFailed; + } + + PRUint32 total = 0; + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + total += s1.CountChar('e'); + } + cout << "s1.CountChar('e')" << endl; + + return kTestSucceeded; + } + +static +int +test_append_string() + { + nsCString s1("This is a reasonable length string with some text in it and it is good."); + nsCString s2("This is another string that I will use in the concatenation test."); + + PRUint32 len = 0; + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + { + nsCString s3; + s3.Append(s1); + s3.Append(s2); + len += TotalLength(s3); + } + } + cout << "s3.Append(s1); s3.Append(s2)" << endl; + + return kTestSucceeded; + } + +static +int +test_repeated_append_string() + { + nsCString s1("This is a reasonable length string with some text in it and it is good."); + nsCString s2("This is another string that I will use in the concatenation test."); + + PRUint32 len = 0; + + { + TestTimer timer; + for ( int i=0; i<1000; ++i ) + { + nsCString s3; + for ( int j=0; j<100; ++j ) + { + s3.Append(s1); + s3.Append(s2); + len += TotalLength(s3); + } + } + } + cout << "repeated s3.Append(s1); s3.Append(s2)" << endl; + + return kTestSucceeded; + } + +static +int +test_repeated_append_char() + { + PRUint32 len = 0; + + { + TestTimer timer; + for ( int i=0; i<1000; ++i ) + { + nsCString s1; + for ( int j=0; j<1000; ++j ) + { + s1.AppendChar('e'); + len += TotalLength(s1); + } + } + } + cout << "repeated s1.Append('e')" << endl; + + return kTestSucceeded; + } + +static +int +test_insert_string() + { + nsCString s1("This is a reasonable length string with some text in it and it is good."); + + PRUint32 len = 0; + + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + { + nsCString s2("This is another string that I will use in the concatenation test."); + s2.Insert(s1, 3); + len += TotalLength(s2); + } + } + cout << "s2.Insert(s1, 3)" << endl; + + return kTestSucceeded; + } + +#if 0 +static +int +test_find_string() + { + nsCString text("aaaaaaaaaab"); + nsCString pattern("aab"); + + PRUint32 position = 0; + { + TestTimer timer; + for ( int i=0; i<100000; ++i ) + position = Find(text, pattern); + } + cout << "text.Find(pattern)" << endl; + + return kTestSucceeded; + } +#endif + +int +main() + { + cout << "String performance profiling. Compiled " __DATE__ " " __TIME__ << endl; +#ifdef TEST_STD_STRING + cout << "Testing std::string." << endl; +#elif defined(NEW_STRING_APIS) + cout << "Testing factored nsString." << endl; +#else + cout << "Testing raw nsString." << endl; +#endif + + int tests_failed = 0; + + tests_failed += test_concat(); + tests_failed += test_concat_and_assign(); + tests_failed += test_compare(); + tests_failed += test_countchar(); + tests_failed += test_append_string(); + tests_failed += test_repeated_append_string(); + tests_failed += test_repeated_append_char(); + tests_failed += test_insert_string(); + // tests_failed += test_find_string(); + + if ( tests_failed ) + cout << "One or more tests FAILED. Measurements may be invalid." << endl; + + cout << "End of string performance profiling." << endl; + return 0; + } diff --git a/mozilla/xpcom/tests/StringFactoringTests/test_main.cc b/mozilla/xpcom/tests/StringFactoringTests/test_main.cc new file mode 100644 index 00000000000..8b6a7810a8d --- /dev/null +++ b/mozilla/xpcom/tests/StringFactoringTests/test_main.cc @@ -0,0 +1,391 @@ +#include +using namespace std; + +#include "nsString.h" +#include "nsStdStringWrapper.h" +#include "nsLiteralString.h" + + +#if 0 +static +void +Call_ToLowerCase( const nsAReadableCString& aSource, nsAWritableCString& aResult ) + { + aSource.ToLowerCase(aResult); + } + +static +void +Call_ToUpperCase( const nsAReadableCString& aSource, nsAWritableCString& aResult ) + { + aSource.ToUpperCase(aResult); + } +#endif + +static +ostream& +print_string( const nsAReadableString& s, ostream& os = std::cout ) + { + struct PRUnichar_to_char + { + char operator()( PRUnichar c ) { return char(c); } + }; + + transform(s.Begin(), s.End(), ostream_iterator(os), PRUnichar_to_char()); + return os; + } + + +template +basic_nsLiteralString +make_a_hello_string( CharT* ) + { + } + +NS_SPECIALIZE_TEMPLATE +basic_nsLiteralString +make_a_hello_string( char* ) + { + return basic_nsLiteralString("Hello"); + } + +NS_SPECIALIZE_TEMPLATE +basic_nsLiteralString +make_a_hello_string( PRUnichar* ) + { + static PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + return basic_nsLiteralString(constant_unicode); + } + +static +void +CallCMid( nsAWritableCString& aResult, const nsAReadableCString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy ) + { + aSource.Mid(aResult, aStartPos, aLengthToCopy); + } + + + +template +int +readable_hello_tests( const basic_nsAReadableString& str, ostream& os = std::cout ) + { + int tests_failed = 0; + + if ( str.Length() != 5 ) + { + os << "Length() FAILED" << endl; + ++tests_failed; + } + + if ( str.First() != CharT('H') ) + { + cout << "|First()| FAILED" << endl; + ++tests_failed; + } + + if ( str.Last() != CharT('o') ) + { + cout << "|Last()| FAILED" << endl; + ++tests_failed; + } + + if ( str[3] != CharT('l') ) + { + cout << "|operator[]()| FAILED" << endl; + ++tests_failed; + } + + if ( str.CountChar( CharT('l') ) != 2 ) + { + cout << "|CountChar()| FAILED" << endl; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter = str.Begin(); + if ( *iter != CharT('H') ) + { + cout << "iterator FAILED: didn't start out pointing at the right thign or couldn't be dereferenced." << endl; + ++tests_failed; + } + + ++iter; + + if ( *iter != CharT('e') ) + { + cout << "iterator FAILED: couldn't be incremented, or else couldn't be dereferenced." << endl; + ++tests_failed; + } + + iter = str.End(); + --iter; + if ( *iter != CharT('o') ) + { + cout << "iterator FAILED: couldn't be set to End(), or else couldn't be decremented, or else couldn't be dereferenced." << endl; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter1 = str.Begin(3); + if ( *iter1 != CharT('l') ) + { + cout << "iterator FAILED: couldn't be set to Begin(n), or else couldn't be dereferenced." << endl; + ++tests_failed; + } + + basic_nsAReadableString::ConstIterator iter2 = str.End(2); + if ( *iter2 != CharT('l') ) + { + cout << "iterator FAILED: couldn't be set to End(n), or else couldn't be dereferenced." << endl; + ++tests_failed; + } + + if ( iter1 != iter2 ) + { + cout << "iterator comparison with != FAILED" << endl; + ++tests_failed; + } + + if ( !(iter1 == iter2) ) + { + cout << "iterator comparison with == FAILED" << endl; + ++tests_failed; + } + + typedef CharT* CharT_ptr; + + if ( str != make_a_hello_string( CharT_ptr() ) ) + { + cout << "comparison with hello string FAILED" << endl; + ++tests_failed; + } + + return tests_failed; + } + +static +inline +bool +compare_equals( const nsAReadableCString& lhs, const nsAReadableCString& rhs ) + { + return bool(lhs == rhs); + } + +static +inline +bool +compare_equals( const nsLiteralCString& lhs, const nsAReadableCString& rhs ) + { + return bool(lhs == rhs); + } + +static +inline +bool +compare_equals( const nsAReadableCString& lhs, const nsLiteralCString& rhs ) + { + return bool(lhs == rhs); + } + + +template +int +test_goofy_iterators( const basic_nsAReadableString& aString ) + { + typedef typename basic_nsAReadableString::ConstIterator ConstIterator; + + int tests_failed = 0; + + ConstIterator iter1 = aString.Begin(); + ConstIterator iter2 = aString.Begin(); + ++iter2; ++iter2; + + ConstIterator iter3 = aString.End(); + --iter3; + ++iter1; ++iter1; + if ( iter1 != iter2 ) + { + cout << "goofy iterator test FAILED" << endl; + ++tests_failed; + } + + return tests_failed; + } + + + +typedef void* void_ptr; + +int +main() + { + int tests_failed = 0; + cout << "String unit tests. Compiled " __DATE__ " " __TIME__ << endl; + + + // + // |nsLiteralString| + // + + + PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() }; + nsLiteralString aLiteralString(constant_unicode); + tests_failed += readable_hello_tests(aLiteralString); + + cout << "\""; + print_string(aLiteralString) << "\"" << endl; + + { + const PRUnichar* buffer = aLiteralString.GetUnicode(); + if ( !buffer ) + { + cout << "|nsLiteralString::GetUnicode()| FAILED: should have returned non-|0|" << endl; + ++tests_failed; + } + + const char* cbuffer = aLiteralString.GetBuffer(); + if ( cbuffer ) + { + cout << "|nsLiteralString::GetBuffer()| FAILED: should have returned |0|" << endl; + ++tests_failed; + } + } + + { + nsCString aCString("Hello"); + tests_failed += readable_hello_tests(aCString); + } + + { + nsStdCString aCString("Hello"); + tests_failed += readable_hello_tests(aCString); + } + + { + nsLiteralCString aLiteralCString("Hello"); + tests_failed += readable_hello_tests(aLiteralCString); + } + + { + nsLiteralCString str1("Hello"); + nsStdCString str2("Hello"); + + nsLiteralCString str3("Hello there"); + + if ( str1 != str2 ) + { + cout << "string comparison using != failed" << endl; + ++tests_failed; + } + + if ( !(str3 > str2) ) + { + cout << "string comparison using > failed" << endl; + ++tests_failed; + } + + if ( !(str2 < str3) ) + { + cout << "string comparison using < failed" << endl; + ++tests_failed; + } + + if ( str1 != "Hello" ) + { + cout << "string comparison using == failed" << endl; + ++tests_failed; + } + } + + nsLiteralCString part1("He"), part2("llo"); + tests_failed += readable_hello_tests(part1+part2); + + nsLiteralCString part2a("l"), part2b("lo"); + tests_failed += readable_hello_tests(part1+part2a+part2b); + + cout << "The summed string is \"" << part1 + part2a + part2b << "\"" << endl; + + nsStdCString extracted_middle("XXXXXXXXXX"); + CallCMid(extracted_middle, part1+part2a+part2b, 1, 3); + + cout << "The result of mid was \"" << extracted_middle << "\"" << endl; + + nsLiteralCString middle_answer("ell"); + if ( middle_answer != extracted_middle ) + { + cout << "mid FAILED on nsConcatString" << endl; + ++tests_failed; + } + + // + // |nsLiteralCString| + // + + + nsLiteralCString aLiteralCString("Goodbye"); + cout << "\"" << aLiteralCString << "\"" << endl; + if ( aLiteralCString.Length() == 7 ) + cout << "|nsLiteralCString::Length()| OK" << endl; + else + cout << "|nsLiteralCString::Length()| FAILED" << endl; + cout << aLiteralCString << endl; + + const char* cbuffer = aLiteralCString.GetBuffer(); + cout << "GetBuffer()-->" << showbase << void_ptr(cbuffer) << endl; + cout << "GetUnicode()-->" << void_ptr( aLiteralCString.GetUnicode() ) << endl; + cout << "The length of the string \"" << aLiteralCString << "\" is " << aLiteralCString.Length() << endl; + + + // + // |nsStdStringWrapper|, i.e., |nsStdCString| + // + + + nsStdCString aCString("Hello"); + if ( aCString.Length() == 5 ) + cout << "|nsStdCString::Length()| OK" << endl; + else + cout << "|nsStdCString::Length()| FAILED" << endl; + + { + nsStdCString extracted_middle; + CallCMid(extracted_middle, part1+part2a+part2b, 1, 3); + + cout << "The result of mid was \"" << extracted_middle << "\"" << endl; + + nsLiteralCString middle_answer("ell"); + if ( middle_answer != extracted_middle ) + { + cout << "mid FAILED on nsStdCString" << endl; + ++tests_failed; + } + } + + cbuffer = aCString.GetBuffer(); + cout << "GetBuffer()-->" << showbase << void_ptr(cbuffer) << endl; + cout << "GetUnicode()-->" << void_ptr( aCString.GetUnicode() ) << endl; + + // cout << "The length of the string \"" << static_cast(aCString) << "\" is " << aCString.Length() << endl; + + + nsLiteralCString source("This is a string long enough to be interesting."); + cout << source << endl; + + nsStdCString leftString; + source.Left(leftString, 9); + // cout << static_cast(leftString) << endl; + + + + tests_failed += test_goofy_iterators(part1+part2a+part2b); + + + + + cout << "End of string unit tests. "; + if ( !tests_failed ) + cout << "All tests OK." << endl; + else + cout << "One or more tests FAILED." << endl; + + return 0; + }