diff --git a/mozilla/string/obsolete/nsString.cpp b/mozilla/string/obsolete/nsString.cpp index cab23e7acd5..ddd13d487a6 100644 --- a/mozilla/string/obsolete/nsString.cpp +++ b/mozilla/string/obsolete/nsString.cpp @@ -126,7 +126,7 @@ nsCString::~nsCString() { } #ifdef NEW_STRING_APIS -const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const char* nsCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen } } -char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +char* nsCString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) { Accessor methods... *********************************************************************/ -#ifndef NEW_STRING_APIS /** * Retrieves internal (1-byte) buffer ptr; * @update gess1/4/99 @@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const { return mStr; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/string/obsolete/nsString.h b/mozilla/string/obsolete/nsString.h index d2b8b3bae17..9200d0fded4 100644 --- a/mozilla/string/obsolete/nsString.h +++ b/mozilla/string/obsolete/nsString.h @@ -60,12 +60,8 @@ class NS_COM nsCString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableCString::FragmentRequest FragmentRequest; - typedef nsAReadableCString::ReadableFragment ReadableFragment; - typedef nsAWritableCString::WritableFragment WritableFragment; - - virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsCString( const nsAReadableCString& ); @@ -184,6 +180,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Accessor methods... @@ -196,6 +193,7 @@ public: const char* GetBuffer(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ @@ -745,13 +743,11 @@ public: }; -#if 0 #ifdef NEW_STRING_APIS NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&); NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*) NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&) #endif -#endif extern NS_COM int fputs(const nsCString& aString, FILE* out); //ostream& operator<<(ostream& aStream,const nsCString& aString); @@ -800,6 +796,11 @@ public: char mBuffer[kDefaultStringSize]; }; +#ifdef NEW_STRING_APIS +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*) +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&) +#endif + /*************************************************************** The subsumestr class is very unusual. diff --git a/mozilla/string/obsolete/nsString2.cpp b/mozilla/string/obsolete/nsString2.cpp index e41fc3330a2..d532ab4c024 100644 --- a/mozilla/string/obsolete/nsString2.cpp +++ b/mozilla/string/obsolete/nsString2.cpp @@ -137,7 +137,7 @@ nsString::~nsString() { } #ifdef NEW_STRING_APIS -const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const PRUnichar* nsString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra } } -PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +PRUnichar* nsString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) { //static char gChar=0; -#ifndef NEW_STRING_APIS /** * * @update gess1/4/99 @@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const { return result; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/string/obsolete/nsString2.h b/mozilla/string/obsolete/nsString2.h index 76e3a14f35f..3179acb08e8 100644 --- a/mozilla/string/obsolete/nsString2.h +++ b/mozilla/string/obsolete/nsString2.h @@ -67,12 +67,8 @@ class NS_COM nsString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableString::FragmentRequest FragmentRequest; - typedef nsAReadableString::ReadableFragment ReadableFragment; - typedef nsAWritableString::WritableFragment WritableFragment; - - virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsString( const nsAReadableString& ); @@ -189,7 +185,6 @@ public: } -#ifndef NEW_STRING_APIS /** * Determine whether or not the characters in this * string are in store as 1 or 2 byte (unicode) strings. @@ -201,6 +196,7 @@ public: return result; } +#ifndef NEW_STRING_APIS /** * Determine whether or not this string has a length of 0 * @@ -209,6 +205,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Getters/Setters... @@ -221,6 +218,7 @@ public: const PRUnichar* GetUnicode(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/string/public/nsAReadableString.h b/mozilla/string/public/nsAReadableString.h index f915e77645e..da1c1d4a4d7 100644 --- a/mozilla/string/public/nsAReadableString.h +++ b/mozilla/string/public/nsAReadableString.h @@ -63,6 +63,7 @@ using namespace std; 'C') is a string of |char|s. */ +template class basic_nsAReadableString; template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -71,8 +72,171 @@ template class basic_nsLiteralString; // ...because we sometimes use them as in params to force the conversion of |CharT*|s +enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; + +template +struct nsReadableFragment + { + const CharT* mStart; + const CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsReadableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template +class nsReadingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef const CharT* pointer; + typedef const CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAReadableString; + + nsReadableFragment mFragment; + const CharT* mPosition; + const basic_nsAReadableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsReadingIterator( const nsReadableFragment& aFragment, + const CharT* aStartingPosition, + const basic_nsAReadableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsReadingIterator( const nsReadingIterator& ); ...use default copy-constructor + // nsReadingIterator& operator=( const nsReadingIterator& ); ...use default copy-assignment operator + + + CharT + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsReadingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsReadingIterator + operator++( int ) + { + nsReadingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsReadingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsReadingIterator + operator--( int ) + { + nsReadingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsReadableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsReadingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsReadingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + // Damn again! Problems with templates made me implement comparisons as members. + + PRBool + operator==( const nsReadingIterator& rhs ) const + { + return mPosition == rhs.mPosition; + } + + PRBool + operator!=( const nsReadingIterator& rhs ) const + { + return mPosition != rhs.mPosition; + } + }; // @@ -85,213 +249,34 @@ class basic_nsAReadableString ... */ { - public: - - struct ReadableFragment - { - const CharT* mStart; - const CharT* mEnd; - PRUint32 mFragmentIdentifier; - - ReadableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; - + // friend class nsReadingIterator; public: + + typedef nsReadingIterator ConstIterator; + + public: + virtual const void* Implementation() const; - enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; - // Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected. - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0; - - friend class ReadingIterator; - class ReadingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef const CharT* pointer; - typedef const CharT& reference; - typedef bidirectional_iterator_tag iterator_category; - - private: - friend class basic_nsAReadableString; - - ReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - ReadingIterator( const ReadableFragment& aFragment, - const CharT* aStartingPosition, - const basic_nsAReadableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // ReadingIterator( const ReadingIterator& ); ...use default copy-constructor - // ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator - - - CharT - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - ReadingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - ReadingIterator - operator++( int ) - { - ReadingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - ReadingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - ReadingIterator - operator--( int ) - { - ReadingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const ReadableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - ReadingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - ReadingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - - // Damn again! Problems with templates made me implement comparisons as members. - - PRBool - operator==( const ReadingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const ReadingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef ReadingIterator ConstIterator; - - - public: - - basic_nsAReadableString::ReadingIterator + nsReadingIterator BeginReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } - basic_nsAReadableString::ReadingIterator + nsReadingIterator EndReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } public: @@ -308,22 +293,6 @@ class basic_nsAReadableString - /* - RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()| - shouldn't be implemented because they're wrong access. I agree. Callers who really need - this access should use the iterators instead. We'll use these to ease the transition to - |nsAReadable...|, and then remove them as soon as possible. - */ - - PRBool IsUnicode() const { return PR_FALSE; } - // ...but note specialization for |PRUnichar|, below - - const char* GetBuffer() const { return 0; } - const PRUnichar* GetUnicode() const { return 0; } - // ...but note specializations for |char| and |PRUnichar|, below - - - CharT CharAt( PRUint32 ) const; CharT operator[]( PRUint32 ) const; CharT First() const; @@ -411,6 +380,26 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; +template +inline +void +nsReadingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } + +template +inline +void +nsReadingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + #define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \ inline \ PRBool \ @@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) -NS_SPECIALIZE_TEMPLATE -inline -PRBool -basic_nsAReadableString::IsUnicode() const - { - return PR_TRUE; - } - -NS_SPECIALIZE_TEMPLATE -inline -const char* -basic_nsAReadableString::GetBuffer() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - -NS_SPECIALIZE_TEMPLATE -inline -const PRUnichar* -basic_nsAReadableString::GetUnicode() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - template const void* basic_nsAReadableString::Implementation() const @@ -501,7 +460,7 @@ CharT basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { // ??? Is |CharAt()| supposed to be the 'safe' version? - ReadableFragment fragment; + nsReadableFragment fragment; return *GetReadableFragment(fragment, kFragmentAt, aIndex); } @@ -539,7 +498,7 @@ basic_nsAReadableString::CountChar( CharT c ) const PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - ReadingIterator iter( BeginReading() ); + nsReadingIterator iter( BeginReading() ); for (;;) { PRUint32 lengthToExamineInThisFragment = iter.size_forward(); @@ -633,11 +592,8 @@ class basic_nsLiteralString allows the automatic conversion of a |CharT*|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: @@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template const CharT* -basic_nsLiteralString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const +basic_nsLiteralString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { @@ -724,29 +680,26 @@ class nsPromiseConcatenation |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; enum { kLeftString, kRightString }; int - GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const + GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const { return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; } int - SetLeftStringInFragment( ReadableFragment& aFragment ) const + SetLeftStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; return kLeftString; } int - SetRightStringInFragment( ReadableFragment& aFragment ) const + SetRightStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; return kRightString; @@ -785,7 +738,7 @@ nsPromiseConcatenation::Length() const template const CharT* -nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { int whichString; @@ -848,6 +801,7 @@ nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, } template +inline nsPromiseConcatenation nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const { @@ -875,11 +829,8 @@ class nsPromiseSubstring calls to |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) @@ -909,7 +860,7 @@ nsPromiseSubstring::Length() const template const CharT* -nsPromiseSubstring::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { // Offset any request for a specific position (First, Last, At) by our // substrings startpos within the owning string @@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - basic_nsAReadableString::ReadingIterator leftIter( lhs.BeginReading() ); - basic_nsAReadableString::ReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter( lhs.BeginReading() ); + nsReadingIterator rightIter( rhs.BeginReading() ); for (;;) { @@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) */ template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { @@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableStr } template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { @@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { @@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { diff --git a/mozilla/string/public/nsAWritableString.h b/mozilla/string/public/nsAWritableString.h index 0a2c36d1cb2..455eab25497 100644 --- a/mozilla/string/public/nsAWritableString.h +++ b/mozilla/string/public/nsAWritableString.h @@ -30,6 +30,158 @@ #include "nsAReadableString.h" +template +struct nsWritableFragment + { + CharT* mStart; + CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsWritableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template class basic_nsAWritableString; + +template +class nsWritingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef CharT* pointer; + typedef CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAWritableString; + + nsWritableFragment mFragment; + CharT* mPosition; + basic_nsAWritableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsWritingIterator( nsWritableFragment& aFragment, + CharT* aStartingPosition, + basic_nsAWritableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsWritingIterator( const nsWritingIterator& ); ...use default copy-constructor + // nsWritingIterator& operator=( const nsWritingIterator& ); ...use default copy-assignment operator + + + reference + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsWritingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsWritingIterator + operator++( int ) + { + nsWritingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsWritingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsWritingIterator + operator--( int ) + { + nsWritingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsWritableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsWritingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsWritingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + }; + + /* This file defines the abstract interfaces |nsAWritableString| and |nsAWritableCString|. @@ -45,204 +197,29 @@ class basic_nsAWritableString ... */ { - protected: - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - - struct WritableFragment - { - CharT* mStart; - CharT* mEnd; - PRUint32 mFragmentIdentifier; - - WritableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; + // friend class nsWritingIterator; public: - virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0; + typedef nsWritingIterator Iterator; - friend class WritingIterator; - class WritingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef CharT* pointer; - typedef CharT& reference; - typedef bidirectional_iterator_tag iterator_category; + virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - private: - friend class basic_nsAWritableString; - WritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; - - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - WritingIterator( WritableFragment& aFragment, - CharT* aStartingPosition, - basic_nsAWritableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // WritingIterator( const WritingIterator& ); ...use default copy-constructor - // WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator - - - reference - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - WritingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - WritingIterator - operator++( int ) - { - WritingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - WritingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - WritingIterator - operator--( int ) - { - WritingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const WritableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - WritingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - WritingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - PRBool - operator==( const WritingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const WritingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef WritingIterator Iterator; - - public: - - basic_nsAWritableString::WritingIterator + nsWritingIterator BeginWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } - basic_nsAWritableString::WritingIterator + nsWritingIterator EndWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } @@ -321,12 +298,45 @@ class basic_nsAWritableString } }; +template +inline +void +nsWritingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } template -typename basic_nsAWritableString::WritingIterator -copy_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +inline +void +nsWritingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + +template +inline +PRBool +operator==( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition == rhs.mPosition; + } + +template +inline +PRBool +operator!=( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition != rhs.mPosition; + } + +template +nsWritingIterator +copy_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { @@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString::ReadingIterator first, } template -typename basic_nsAWritableString::WritingIterator -copy_backward_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +nsWritingIterator +copy_backward_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { diff --git a/mozilla/string/public/nsSharedString.h b/mozilla/string/public/nsSharedString.h index 5d10c29ca3f..e3891b19ab9 100644 --- a/mozilla/string/public/nsSharedString.h +++ b/mozilla/string/public/nsSharedString.h @@ -35,8 +35,29 @@ class basic_nsSharedString ... */ { + private: + ~basic_nsSharedString() { } + // You can't sub-class me, or make an instance of me on the stack + + // operator delete + public: + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + + virtual + PRUint32 + Length() const + { + return mLength; + } + + basic_nsSharedString( const basic_nsAReadableString& aReadable ) + { + mLength = aReadable.Length(); + copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0); + } + nsrefcnt AddRef() const { @@ -53,10 +74,31 @@ class basic_nsSharedString } private: - mutable nsrefcnt mRefCount; + mutable nsrefcnt mRefCount; + size_t mLength; + CharT mData[1]; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsSharedString) + +template +const CharT* +basic_nsSharedString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const + { + switch ( aRequest ) + { + case kFirstFragment: + case kLastFragment: + case kFragmentAt: + aFragment.mEnd = (aFragment.mStart = mData) + mLength; + return aFragment.mStart + anOffset; + + case kPrevFragment: + case kNextFragment: + default: + return 0; + } + } @@ -71,12 +113,17 @@ class nsSharedStringPtr }; +template +basic_nsSharedString* +new_nsSharedString( const basic_nsAReadableString& aReadable ) + { + void* in_buffer = operator new( sizeof(basic_nsSharedString) + aReadable.Length()*sizeof(CharT) ); + return new (in_buffer) basic_nsSharedString(aReadable); + } + typedef basic_nsSharedString nsSharedString; -typedef basic_nsSharedStringPtr nsSharedStringPtr; - typedef basic_nsSharedString nsSharedCString; -typedef basic_nsSharedStringPtr nsSharedCStringPtr; #endif // !defined(_nsSharedString_h__) diff --git a/mozilla/xpcom/ds/nsAReadableString.h b/mozilla/xpcom/ds/nsAReadableString.h index f915e77645e..da1c1d4a4d7 100644 --- a/mozilla/xpcom/ds/nsAReadableString.h +++ b/mozilla/xpcom/ds/nsAReadableString.h @@ -63,6 +63,7 @@ using namespace std; 'C') is a string of |char|s. */ +template class basic_nsAReadableString; template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -71,8 +72,171 @@ template class basic_nsLiteralString; // ...because we sometimes use them as in params to force the conversion of |CharT*|s +enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; + +template +struct nsReadableFragment + { + const CharT* mStart; + const CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsReadableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template +class nsReadingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef const CharT* pointer; + typedef const CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAReadableString; + + nsReadableFragment mFragment; + const CharT* mPosition; + const basic_nsAReadableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsReadingIterator( const nsReadableFragment& aFragment, + const CharT* aStartingPosition, + const basic_nsAReadableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsReadingIterator( const nsReadingIterator& ); ...use default copy-constructor + // nsReadingIterator& operator=( const nsReadingIterator& ); ...use default copy-assignment operator + + + CharT + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsReadingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsReadingIterator + operator++( int ) + { + nsReadingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsReadingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsReadingIterator + operator--( int ) + { + nsReadingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsReadableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsReadingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsReadingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + // Damn again! Problems with templates made me implement comparisons as members. + + PRBool + operator==( const nsReadingIterator& rhs ) const + { + return mPosition == rhs.mPosition; + } + + PRBool + operator!=( const nsReadingIterator& rhs ) const + { + return mPosition != rhs.mPosition; + } + }; // @@ -85,213 +249,34 @@ class basic_nsAReadableString ... */ { - public: - - struct ReadableFragment - { - const CharT* mStart; - const CharT* mEnd; - PRUint32 mFragmentIdentifier; - - ReadableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; - + // friend class nsReadingIterator; public: + + typedef nsReadingIterator ConstIterator; + + public: + virtual const void* Implementation() const; - enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; - // Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected. - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0; - - friend class ReadingIterator; - class ReadingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef const CharT* pointer; - typedef const CharT& reference; - typedef bidirectional_iterator_tag iterator_category; - - private: - friend class basic_nsAReadableString; - - ReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - ReadingIterator( const ReadableFragment& aFragment, - const CharT* aStartingPosition, - const basic_nsAReadableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // ReadingIterator( const ReadingIterator& ); ...use default copy-constructor - // ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator - - - CharT - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - ReadingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - ReadingIterator - operator++( int ) - { - ReadingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - ReadingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - ReadingIterator - operator--( int ) - { - ReadingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const ReadableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - ReadingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - ReadingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - - // Damn again! Problems with templates made me implement comparisons as members. - - PRBool - operator==( const ReadingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const ReadingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef ReadingIterator ConstIterator; - - - public: - - basic_nsAReadableString::ReadingIterator + nsReadingIterator BeginReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } - basic_nsAReadableString::ReadingIterator + nsReadingIterator EndReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } public: @@ -308,22 +293,6 @@ class basic_nsAReadableString - /* - RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()| - shouldn't be implemented because they're wrong access. I agree. Callers who really need - this access should use the iterators instead. We'll use these to ease the transition to - |nsAReadable...|, and then remove them as soon as possible. - */ - - PRBool IsUnicode() const { return PR_FALSE; } - // ...but note specialization for |PRUnichar|, below - - const char* GetBuffer() const { return 0; } - const PRUnichar* GetUnicode() const { return 0; } - // ...but note specializations for |char| and |PRUnichar|, below - - - CharT CharAt( PRUint32 ) const; CharT operator[]( PRUint32 ) const; CharT First() const; @@ -411,6 +380,26 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; +template +inline +void +nsReadingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } + +template +inline +void +nsReadingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + #define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \ inline \ PRBool \ @@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) -NS_SPECIALIZE_TEMPLATE -inline -PRBool -basic_nsAReadableString::IsUnicode() const - { - return PR_TRUE; - } - -NS_SPECIALIZE_TEMPLATE -inline -const char* -basic_nsAReadableString::GetBuffer() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - -NS_SPECIALIZE_TEMPLATE -inline -const PRUnichar* -basic_nsAReadableString::GetUnicode() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - template const void* basic_nsAReadableString::Implementation() const @@ -501,7 +460,7 @@ CharT basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { // ??? Is |CharAt()| supposed to be the 'safe' version? - ReadableFragment fragment; + nsReadableFragment fragment; return *GetReadableFragment(fragment, kFragmentAt, aIndex); } @@ -539,7 +498,7 @@ basic_nsAReadableString::CountChar( CharT c ) const PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - ReadingIterator iter( BeginReading() ); + nsReadingIterator iter( BeginReading() ); for (;;) { PRUint32 lengthToExamineInThisFragment = iter.size_forward(); @@ -633,11 +592,8 @@ class basic_nsLiteralString allows the automatic conversion of a |CharT*|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: @@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template const CharT* -basic_nsLiteralString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const +basic_nsLiteralString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { @@ -724,29 +680,26 @@ class nsPromiseConcatenation |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; enum { kLeftString, kRightString }; int - GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const + GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const { return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; } int - SetLeftStringInFragment( ReadableFragment& aFragment ) const + SetLeftStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; return kLeftString; } int - SetRightStringInFragment( ReadableFragment& aFragment ) const + SetRightStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; return kRightString; @@ -785,7 +738,7 @@ nsPromiseConcatenation::Length() const template const CharT* -nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { int whichString; @@ -848,6 +801,7 @@ nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, } template +inline nsPromiseConcatenation nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const { @@ -875,11 +829,8 @@ class nsPromiseSubstring calls to |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) @@ -909,7 +860,7 @@ nsPromiseSubstring::Length() const template const CharT* -nsPromiseSubstring::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { // Offset any request for a specific position (First, Last, At) by our // substrings startpos within the owning string @@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - basic_nsAReadableString::ReadingIterator leftIter( lhs.BeginReading() ); - basic_nsAReadableString::ReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter( lhs.BeginReading() ); + nsReadingIterator rightIter( rhs.BeginReading() ); for (;;) { @@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) */ template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { @@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableStr } template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { @@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { @@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { diff --git a/mozilla/xpcom/ds/nsAWritableString.h b/mozilla/xpcom/ds/nsAWritableString.h index 0a2c36d1cb2..455eab25497 100644 --- a/mozilla/xpcom/ds/nsAWritableString.h +++ b/mozilla/xpcom/ds/nsAWritableString.h @@ -30,6 +30,158 @@ #include "nsAReadableString.h" +template +struct nsWritableFragment + { + CharT* mStart; + CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsWritableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template class basic_nsAWritableString; + +template +class nsWritingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef CharT* pointer; + typedef CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAWritableString; + + nsWritableFragment mFragment; + CharT* mPosition; + basic_nsAWritableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsWritingIterator( nsWritableFragment& aFragment, + CharT* aStartingPosition, + basic_nsAWritableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsWritingIterator( const nsWritingIterator& ); ...use default copy-constructor + // nsWritingIterator& operator=( const nsWritingIterator& ); ...use default copy-assignment operator + + + reference + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsWritingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsWritingIterator + operator++( int ) + { + nsWritingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsWritingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsWritingIterator + operator--( int ) + { + nsWritingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsWritableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsWritingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsWritingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + }; + + /* This file defines the abstract interfaces |nsAWritableString| and |nsAWritableCString|. @@ -45,204 +197,29 @@ class basic_nsAWritableString ... */ { - protected: - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - - struct WritableFragment - { - CharT* mStart; - CharT* mEnd; - PRUint32 mFragmentIdentifier; - - WritableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; + // friend class nsWritingIterator; public: - virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0; + typedef nsWritingIterator Iterator; - friend class WritingIterator; - class WritingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef CharT* pointer; - typedef CharT& reference; - typedef bidirectional_iterator_tag iterator_category; + virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - private: - friend class basic_nsAWritableString; - WritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; - - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - WritingIterator( WritableFragment& aFragment, - CharT* aStartingPosition, - basic_nsAWritableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // WritingIterator( const WritingIterator& ); ...use default copy-constructor - // WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator - - - reference - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - WritingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - WritingIterator - operator++( int ) - { - WritingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - WritingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - WritingIterator - operator--( int ) - { - WritingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const WritableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - WritingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - WritingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - PRBool - operator==( const WritingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const WritingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef WritingIterator Iterator; - - public: - - basic_nsAWritableString::WritingIterator + nsWritingIterator BeginWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } - basic_nsAWritableString::WritingIterator + nsWritingIterator EndWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } @@ -321,12 +298,45 @@ class basic_nsAWritableString } }; +template +inline +void +nsWritingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } template -typename basic_nsAWritableString::WritingIterator -copy_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +inline +void +nsWritingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + +template +inline +PRBool +operator==( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition == rhs.mPosition; + } + +template +inline +PRBool +operator!=( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition != rhs.mPosition; + } + +template +nsWritingIterator +copy_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { @@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString::ReadingIterator first, } template -typename basic_nsAWritableString::WritingIterator -copy_backward_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +nsWritingIterator +copy_backward_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { diff --git a/mozilla/xpcom/ds/nsSharedString.h b/mozilla/xpcom/ds/nsSharedString.h index 5d10c29ca3f..e3891b19ab9 100644 --- a/mozilla/xpcom/ds/nsSharedString.h +++ b/mozilla/xpcom/ds/nsSharedString.h @@ -35,8 +35,29 @@ class basic_nsSharedString ... */ { + private: + ~basic_nsSharedString() { } + // You can't sub-class me, or make an instance of me on the stack + + // operator delete + public: + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + + virtual + PRUint32 + Length() const + { + return mLength; + } + + basic_nsSharedString( const basic_nsAReadableString& aReadable ) + { + mLength = aReadable.Length(); + copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0); + } + nsrefcnt AddRef() const { @@ -53,10 +74,31 @@ class basic_nsSharedString } private: - mutable nsrefcnt mRefCount; + mutable nsrefcnt mRefCount; + size_t mLength; + CharT mData[1]; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsSharedString) + +template +const CharT* +basic_nsSharedString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const + { + switch ( aRequest ) + { + case kFirstFragment: + case kLastFragment: + case kFragmentAt: + aFragment.mEnd = (aFragment.mStart = mData) + mLength; + return aFragment.mStart + anOffset; + + case kPrevFragment: + case kNextFragment: + default: + return 0; + } + } @@ -71,12 +113,17 @@ class nsSharedStringPtr }; +template +basic_nsSharedString* +new_nsSharedString( const basic_nsAReadableString& aReadable ) + { + void* in_buffer = operator new( sizeof(basic_nsSharedString) + aReadable.Length()*sizeof(CharT) ); + return new (in_buffer) basic_nsSharedString(aReadable); + } + typedef basic_nsSharedString nsSharedString; -typedef basic_nsSharedStringPtr nsSharedStringPtr; - typedef basic_nsSharedString nsSharedCString; -typedef basic_nsSharedStringPtr nsSharedCStringPtr; #endif // !defined(_nsSharedString_h__) diff --git a/mozilla/xpcom/ds/nsString.cpp b/mozilla/xpcom/ds/nsString.cpp index cab23e7acd5..ddd13d487a6 100644 --- a/mozilla/xpcom/ds/nsString.cpp +++ b/mozilla/xpcom/ds/nsString.cpp @@ -126,7 +126,7 @@ nsCString::~nsCString() { } #ifdef NEW_STRING_APIS -const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const char* nsCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen } } -char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +char* nsCString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) { Accessor methods... *********************************************************************/ -#ifndef NEW_STRING_APIS /** * Retrieves internal (1-byte) buffer ptr; * @update gess1/4/99 @@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const { return mStr; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/ds/nsString.h b/mozilla/xpcom/ds/nsString.h index d2b8b3bae17..9200d0fded4 100644 --- a/mozilla/xpcom/ds/nsString.h +++ b/mozilla/xpcom/ds/nsString.h @@ -60,12 +60,8 @@ class NS_COM nsCString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableCString::FragmentRequest FragmentRequest; - typedef nsAReadableCString::ReadableFragment ReadableFragment; - typedef nsAWritableCString::WritableFragment WritableFragment; - - virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsCString( const nsAReadableCString& ); @@ -184,6 +180,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Accessor methods... @@ -196,6 +193,7 @@ public: const char* GetBuffer(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ @@ -745,13 +743,11 @@ public: }; -#if 0 #ifdef NEW_STRING_APIS NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&); NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*) NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&) #endif -#endif extern NS_COM int fputs(const nsCString& aString, FILE* out); //ostream& operator<<(ostream& aStream,const nsCString& aString); @@ -800,6 +796,11 @@ public: char mBuffer[kDefaultStringSize]; }; +#ifdef NEW_STRING_APIS +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*) +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&) +#endif + /*************************************************************** The subsumestr class is very unusual. diff --git a/mozilla/xpcom/ds/nsString2.cpp b/mozilla/xpcom/ds/nsString2.cpp index e41fc3330a2..d532ab4c024 100644 --- a/mozilla/xpcom/ds/nsString2.cpp +++ b/mozilla/xpcom/ds/nsString2.cpp @@ -137,7 +137,7 @@ nsString::~nsString() { } #ifdef NEW_STRING_APIS -const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const PRUnichar* nsString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra } } -PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +PRUnichar* nsString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) { //static char gChar=0; -#ifndef NEW_STRING_APIS /** * * @update gess1/4/99 @@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const { return result; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/ds/nsString2.h b/mozilla/xpcom/ds/nsString2.h index 76e3a14f35f..3179acb08e8 100644 --- a/mozilla/xpcom/ds/nsString2.h +++ b/mozilla/xpcom/ds/nsString2.h @@ -67,12 +67,8 @@ class NS_COM nsString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableString::FragmentRequest FragmentRequest; - typedef nsAReadableString::ReadableFragment ReadableFragment; - typedef nsAWritableString::WritableFragment WritableFragment; - - virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsString( const nsAReadableString& ); @@ -189,7 +185,6 @@ public: } -#ifndef NEW_STRING_APIS /** * Determine whether or not the characters in this * string are in store as 1 or 2 byte (unicode) strings. @@ -201,6 +196,7 @@ public: return result; } +#ifndef NEW_STRING_APIS /** * Determine whether or not this string has a length of 0 * @@ -209,6 +205,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Getters/Setters... @@ -221,6 +218,7 @@ public: const PRUnichar* GetUnicode(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/string/obsolete/nsString.cpp b/mozilla/xpcom/string/obsolete/nsString.cpp index cab23e7acd5..ddd13d487a6 100644 --- a/mozilla/xpcom/string/obsolete/nsString.cpp +++ b/mozilla/xpcom/string/obsolete/nsString.cpp @@ -126,7 +126,7 @@ nsCString::~nsCString() { } #ifdef NEW_STRING_APIS -const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const char* nsCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen } } -char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +char* nsCString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) { Accessor methods... *********************************************************************/ -#ifndef NEW_STRING_APIS /** * Retrieves internal (1-byte) buffer ptr; * @update gess1/4/99 @@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const { return mStr; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/string/obsolete/nsString.h b/mozilla/xpcom/string/obsolete/nsString.h index d2b8b3bae17..9200d0fded4 100644 --- a/mozilla/xpcom/string/obsolete/nsString.h +++ b/mozilla/xpcom/string/obsolete/nsString.h @@ -60,12 +60,8 @@ class NS_COM nsCString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableCString::FragmentRequest FragmentRequest; - typedef nsAReadableCString::ReadableFragment ReadableFragment; - typedef nsAWritableCString::WritableFragment WritableFragment; - - virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsCString( const nsAReadableCString& ); @@ -184,6 +180,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Accessor methods... @@ -196,6 +193,7 @@ public: const char* GetBuffer(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ @@ -745,13 +743,11 @@ public: }; -#if 0 #ifdef NEW_STRING_APIS NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&); NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*) NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&) #endif -#endif extern NS_COM int fputs(const nsCString& aString, FILE* out); //ostream& operator<<(ostream& aStream,const nsCString& aString); @@ -800,6 +796,11 @@ public: char mBuffer[kDefaultStringSize]; }; +#ifdef NEW_STRING_APIS +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*) +NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&) +#endif + /*************************************************************** The subsumestr class is very unusual. diff --git a/mozilla/xpcom/string/obsolete/nsString2.cpp b/mozilla/xpcom/string/obsolete/nsString2.cpp index e41fc3330a2..d532ab4c024 100644 --- a/mozilla/xpcom/string/obsolete/nsString2.cpp +++ b/mozilla/xpcom/string/obsolete/nsString2.cpp @@ -137,7 +137,7 @@ nsString::~nsString() { } #ifdef NEW_STRING_APIS -const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const { +const PRUnichar* nsString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra } } -PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) { +PRUnichar* nsString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { switch ( aRequest ) { case kFirstFragment: case kLastFragment: @@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) { //static char gChar=0; -#ifndef NEW_STRING_APIS /** * * @update gess1/4/99 @@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const { return result; } +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/string/obsolete/nsString2.h b/mozilla/xpcom/string/obsolete/nsString2.h index 76e3a14f35f..3179acb08e8 100644 --- a/mozilla/xpcom/string/obsolete/nsString2.h +++ b/mozilla/xpcom/string/obsolete/nsString2.h @@ -67,12 +67,8 @@ class NS_COM nsString : #ifdef NEW_STRING_APIS protected: - typedef nsAReadableString::FragmentRequest FragmentRequest; - typedef nsAReadableString::ReadableFragment ReadableFragment; - typedef nsAWritableString::WritableFragment WritableFragment; - - virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; - virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 ); + virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); public: nsString( const nsAReadableString& ); @@ -189,7 +185,6 @@ public: } -#ifndef NEW_STRING_APIS /** * Determine whether or not the characters in this * string are in store as 1 or 2 byte (unicode) strings. @@ -201,6 +196,7 @@ public: return result; } +#ifndef NEW_STRING_APIS /** * Determine whether or not this string has a length of 0 * @@ -209,6 +205,7 @@ public: PRBool IsEmpty(void) const { return PRBool(0==mLength); } +#endif /********************************************************************** Getters/Setters... @@ -221,6 +218,7 @@ public: const PRUnichar* GetUnicode(void) const; +#ifndef NEW_STRING_APIS /** * Get nth character. */ diff --git a/mozilla/xpcom/string/public/nsAReadableString.h b/mozilla/xpcom/string/public/nsAReadableString.h index f915e77645e..da1c1d4a4d7 100644 --- a/mozilla/xpcom/string/public/nsAReadableString.h +++ b/mozilla/xpcom/string/public/nsAReadableString.h @@ -63,6 +63,7 @@ using namespace std; 'C') is a string of |char|s. */ +template class basic_nsAReadableString; template class basic_nsAWritableString; // ...because we sometimes use them as `out' params @@ -71,8 +72,171 @@ template class basic_nsLiteralString; // ...because we sometimes use them as in params to force the conversion of |CharT*|s +enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; + +template +struct nsReadableFragment + { + const CharT* mStart; + const CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsReadableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template +class nsReadingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef const CharT* pointer; + typedef const CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAReadableString; + + nsReadableFragment mFragment; + const CharT* mPosition; + const basic_nsAReadableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsReadingIterator( const nsReadableFragment& aFragment, + const CharT* aStartingPosition, + const basic_nsAReadableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsReadingIterator( const nsReadingIterator& ); ...use default copy-constructor + // nsReadingIterator& operator=( const nsReadingIterator& ); ...use default copy-assignment operator + + + CharT + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsReadingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsReadingIterator + operator++( int ) + { + nsReadingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsReadingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsReadingIterator + operator--( int ) + { + nsReadingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsReadableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsReadingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsReadingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + // Damn again! Problems with templates made me implement comparisons as members. + + PRBool + operator==( const nsReadingIterator& rhs ) const + { + return mPosition == rhs.mPosition; + } + + PRBool + operator!=( const nsReadingIterator& rhs ) const + { + return mPosition != rhs.mPosition; + } + }; // @@ -85,213 +249,34 @@ class basic_nsAReadableString ... */ { - public: - - struct ReadableFragment - { - const CharT* mStart; - const CharT* mEnd; - PRUint32 mFragmentIdentifier; - - ReadableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; - + // friend class nsReadingIterator; public: + + typedef nsReadingIterator ConstIterator; + + public: + virtual const void* Implementation() const; - enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; - // Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected. - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0; - - friend class ReadingIterator; - class ReadingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef const CharT* pointer; - typedef const CharT& reference; - typedef bidirectional_iterator_tag iterator_category; - - private: - friend class basic_nsAReadableString; - - ReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - ReadingIterator( const ReadableFragment& aFragment, - const CharT* aStartingPosition, - const basic_nsAReadableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // ReadingIterator( const ReadingIterator& ); ...use default copy-constructor - // ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator - - - CharT - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - ReadingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - ReadingIterator - operator++( int ) - { - ReadingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - ReadingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - ReadingIterator - operator--( int ) - { - ReadingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const ReadableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - ReadingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - ReadingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - - // Damn again! Problems with templates made me implement comparisons as members. - - PRBool - operator==( const ReadingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const ReadingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef ReadingIterator ConstIterator; - - - public: - - basic_nsAReadableString::ReadingIterator + nsReadingIterator BeginReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } - basic_nsAReadableString::ReadingIterator + nsReadingIterator EndReading( PRUint32 aOffset = 0 ) const { - ReadableFragment fragment; + nsReadableFragment fragment; const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAReadableString::ReadingIterator(fragment, startPos, *this); + return nsReadingIterator(fragment, startPos, *this); } public: @@ -308,22 +293,6 @@ class basic_nsAReadableString - /* - RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()| - shouldn't be implemented because they're wrong access. I agree. Callers who really need - this access should use the iterators instead. We'll use these to ease the transition to - |nsAReadable...|, and then remove them as soon as possible. - */ - - PRBool IsUnicode() const { return PR_FALSE; } - // ...but note specialization for |PRUnichar|, below - - const char* GetBuffer() const { return 0; } - const PRUnichar* GetUnicode() const { return 0; } - // ...but note specializations for |char| and |PRUnichar|, below - - - CharT CharAt( PRUint32 ) const; CharT operator[]( PRUint32 ) const; CharT First() const; @@ -411,6 +380,26 @@ class basic_nsAReadableString PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } }; +template +inline +void +nsReadingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } + +template +inline +void +nsReadingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + #define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \ inline \ PRBool \ @@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString) -NS_SPECIALIZE_TEMPLATE -inline -PRBool -basic_nsAReadableString::IsUnicode() const - { - return PR_TRUE; - } - -NS_SPECIALIZE_TEMPLATE -inline -const char* -basic_nsAReadableString::GetBuffer() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - -NS_SPECIALIZE_TEMPLATE -inline -const PRUnichar* -basic_nsAReadableString::GetUnicode() const - // DEPRECATED: use the iterators instead - { - ReadableFragment fragment; - GetReadableFragment(fragment, kFirstFragment); - return fragment.mStart; - } - template const void* basic_nsAReadableString::Implementation() const @@ -501,7 +460,7 @@ CharT basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { // ??? Is |CharAt()| supposed to be the 'safe' version? - ReadableFragment fragment; + nsReadableFragment fragment; return *GetReadableFragment(fragment, kFragmentAt, aIndex); } @@ -539,7 +498,7 @@ basic_nsAReadableString::CountChar( CharT c ) const PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - ReadingIterator iter( BeginReading() ); + nsReadingIterator iter( BeginReading() ); for (;;) { PRUint32 lengthToExamineInThisFragment = iter.size_forward(); @@ -633,11 +592,8 @@ class basic_nsLiteralString allows the automatic conversion of a |CharT*|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: @@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString) template const CharT* -basic_nsLiteralString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const +basic_nsLiteralString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { switch ( aRequest ) { @@ -724,29 +680,26 @@ class nsPromiseConcatenation |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; enum { kLeftString, kRightString }; int - GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const + GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const { return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; } int - SetLeftStringInFragment( ReadableFragment& aFragment ) const + SetLeftStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; return kLeftString; } int - SetRightStringInFragment( ReadableFragment& aFragment ) const + SetRightStringInFragment( nsReadableFragment& aFragment ) const { aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; return kRightString; @@ -785,7 +738,7 @@ nsPromiseConcatenation::Length() const template const CharT* -nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { int whichString; @@ -848,6 +801,7 @@ nsPromiseConcatenation::GetReadableFragment( ReadableFragment& aFragment, } template +inline nsPromiseConcatenation nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const { @@ -875,11 +829,8 @@ class nsPromiseSubstring calls to |GetReadableFragment()|. */ { - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - typedef typename basic_nsAWritableString::ReadableFragment ReadableFragment; - protected: - virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const; + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; public: nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) @@ -909,7 +860,7 @@ nsPromiseSubstring::Length() const template const CharT* -nsPromiseSubstring::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const +nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const { // Offset any request for a specific position (First, Last, At) by our // substrings startpos within the owning string @@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - basic_nsAReadableString::ReadingIterator leftIter( lhs.BeginReading() ); - basic_nsAReadableString::ReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter( lhs.BeginReading() ); + nsReadingIterator rightIter( rhs.BeginReading() ); for (;;) { @@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) */ template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) { @@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableStr } template +inline nsPromiseConcatenation operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralString& rhs ) { @@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString& lhs, const basic_nsLiteralStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableString& rhs ) { @@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsAReadableStrin } template +inline nsPromiseConcatenation operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString& rhs ) { diff --git a/mozilla/xpcom/string/public/nsAWritableString.h b/mozilla/xpcom/string/public/nsAWritableString.h index 0a2c36d1cb2..455eab25497 100644 --- a/mozilla/xpcom/string/public/nsAWritableString.h +++ b/mozilla/xpcom/string/public/nsAWritableString.h @@ -30,6 +30,158 @@ #include "nsAReadableString.h" +template +struct nsWritableFragment + { + CharT* mStart; + CharT* mEnd; + PRUint32 mFragmentIdentifier; + + nsWritableFragment() + : mStart(0), mEnd(0), mFragmentIdentifier(0) + { + // nothing else to do here + } + }; + +template class basic_nsAWritableString; + +template +class nsWritingIterator + : public bidirectional_iterator_tag + { + public: + typedef ptrdiff_t difference_type; + typedef CharT value_type; + typedef CharT* pointer; + typedef CharT& reference; + typedef bidirectional_iterator_tag iterator_category; + + private: + friend class basic_nsAWritableString; + + nsWritableFragment mFragment; + CharT* mPosition; + basic_nsAWritableString* mOwningString; + + inline void normalize_forward(); + inline void normalize_backward(); + + nsWritingIterator( nsWritableFragment& aFragment, + CharT* aStartingPosition, + basic_nsAWritableString& aOwningString ) + : mFragment(aFragment), + mPosition(aStartingPosition), + mOwningString(&aOwningString) + { + // nothing else to do here + } + + public: + // nsWritingIterator( const nsWritingIterator& ); ...use default copy-constructor + // nsWritingIterator& operator=( const nsWritingIterator& ); ...use default copy-assignment operator + + + reference + operator*() const + { + return *mPosition; + } + + pointer + operator->() const + { + return mPosition; + } + + nsWritingIterator& + operator++() + { + ++mPosition; + normalize_forward(); + return *this; + } + + nsWritingIterator + operator++( int ) + { + nsWritingIterator result(*this); + ++mPosition; + normalize_forward(); + return result; + } + + nsWritingIterator& + operator--() + { + normalize_backward(); + --mPosition; + return *this; + } + + nsWritingIterator + operator--( int ) + { + nsWritingIterator result(*this); + normalize_backward(); + --mPosition; + return result; + } + + const nsWritableFragment& + fragment() const + { + return mFragment; + } + + difference_type + size_forward() const + { + return mFragment.mEnd - mPosition; + } + + difference_type + size_backward() const + { + return mPosition - mFragment.mStart; + } + + nsWritingIterator& + operator+=( difference_type n ) + { + if ( n < 0 ) + return operator-=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + return *this; + } + + nsWritingIterator& + operator-=( difference_type n ) + { + if ( n < 0 ) + return operator+=(-n); + + while ( n ) + { + difference_type one_hop = NS_MIN(n, size_backward()); + mPosition -= one_hop; + normalize_backward(); + n -= one_hop; + } + + return *this; + } + }; + + /* This file defines the abstract interfaces |nsAWritableString| and |nsAWritableCString|. @@ -45,204 +197,29 @@ class basic_nsAWritableString ... */ { - protected: - typedef typename basic_nsAReadableString::FragmentRequest FragmentRequest; - - struct WritableFragment - { - CharT* mStart; - CharT* mEnd; - PRUint32 mFragmentIdentifier; - - WritableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; + // friend class nsWritingIterator; public: - virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0; + typedef nsWritingIterator Iterator; - friend class WritingIterator; - class WritingIterator - : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef CharT* pointer; - typedef CharT& reference; - typedef bidirectional_iterator_tag iterator_category; + virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - private: - friend class basic_nsAWritableString; - WritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; - - void - normalize_forward() - { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - - void - normalize_backward() - { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - WritingIterator( WritableFragment& aFragment, - CharT* aStartingPosition, - basic_nsAWritableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - // WritingIterator( const WritingIterator& ); ...use default copy-constructor - // WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator - - - reference - operator*() const - { - return *mPosition; - } - - pointer - operator->() const - { - return mPosition; - } - - WritingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - WritingIterator - operator++( int ) - { - WritingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - WritingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - WritingIterator - operator--( int ) - { - WritingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const WritableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - WritingIterator& - operator+=( difference_type n ) - { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; - } - - WritingIterator& - operator-=( difference_type n ) - { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_backward()); - mPosition -= one_hop; - normalize_backward(); - n -= one_hop; - } - - return *this; - } - - PRBool - operator==( const WritingIterator& rhs ) const - { - return mPosition == rhs.mPosition; - } - - PRBool - operator!=( const WritingIterator& rhs ) const - { - return mPosition != rhs.mPosition; - } - }; - - typedef WritingIterator Iterator; - - public: - - basic_nsAWritableString::WritingIterator + nsWritingIterator BeginWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } - basic_nsAWritableString::WritingIterator + nsWritingIterator EndWriting( PRUint32 aOffset = 0 ) { - WritableFragment fragment; + nsWritableFragment fragment; CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset)); - return basic_nsAWritableString::WritingIterator(fragment, startPos, *this); + return nsWritingIterator(fragment, startPos, *this); } @@ -321,12 +298,45 @@ class basic_nsAWritableString } }; +template +inline +void +nsWritingIterator::normalize_forward() + { + if ( mPosition == mFragment.mEnd ) + if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; + } template -typename basic_nsAWritableString::WritingIterator -copy_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +inline +void +nsWritingIterator::normalize_backward() + { + if ( mPosition == mFragment.mStart ) + if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; + } + +template +inline +PRBool +operator==( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition == rhs.mPosition; + } + +template +inline +PRBool +operator!=( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) + { + return lhs.mPosition != rhs.mPosition; + } + +template +nsWritingIterator +copy_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { @@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString::ReadingIterator first, } template -typename basic_nsAWritableString::WritingIterator -copy_backward_chunky( typename basic_nsAReadableString::ReadingIterator first, - typename basic_nsAReadableString::ReadingIterator last, - typename basic_nsAWritableString::WritingIterator result ) +nsWritingIterator +copy_backward_chunky( nsReadingIterator first, nsReadingIterator last, nsWritingIterator result ) { while ( first != last ) { diff --git a/mozilla/xpcom/string/public/nsSharedString.h b/mozilla/xpcom/string/public/nsSharedString.h index 5d10c29ca3f..e3891b19ab9 100644 --- a/mozilla/xpcom/string/public/nsSharedString.h +++ b/mozilla/xpcom/string/public/nsSharedString.h @@ -35,8 +35,29 @@ class basic_nsSharedString ... */ { + private: + ~basic_nsSharedString() { } + // You can't sub-class me, or make an instance of me on the stack + + // operator delete + public: + virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + + virtual + PRUint32 + Length() const + { + return mLength; + } + + basic_nsSharedString( const basic_nsAReadableString& aReadable ) + { + mLength = aReadable.Length(); + copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0); + } + nsrefcnt AddRef() const { @@ -53,10 +74,31 @@ class basic_nsSharedString } private: - mutable nsrefcnt mRefCount; + mutable nsrefcnt mRefCount; + size_t mLength; + CharT mData[1]; }; -NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper) +NS_DEF_STRING_COMPARISONS(basic_nsSharedString) + +template +const CharT* +basic_nsSharedString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const + { + switch ( aRequest ) + { + case kFirstFragment: + case kLastFragment: + case kFragmentAt: + aFragment.mEnd = (aFragment.mStart = mData) + mLength; + return aFragment.mStart + anOffset; + + case kPrevFragment: + case kNextFragment: + default: + return 0; + } + } @@ -71,12 +113,17 @@ class nsSharedStringPtr }; +template +basic_nsSharedString* +new_nsSharedString( const basic_nsAReadableString& aReadable ) + { + void* in_buffer = operator new( sizeof(basic_nsSharedString) + aReadable.Length()*sizeof(CharT) ); + return new (in_buffer) basic_nsSharedString(aReadable); + } + typedef basic_nsSharedString nsSharedString; -typedef basic_nsSharedStringPtr nsSharedStringPtr; - typedef basic_nsSharedString nsSharedCString; -typedef basic_nsSharedStringPtr nsSharedCStringPtr; #endif // !defined(_nsSharedString_h__)