diff --git a/mozilla/string/public/nsAReadableString.h b/mozilla/string/public/nsAReadableString.h index 981c999aff1..56b695d4d9d 100644 --- a/mozilla/string/public/nsAReadableString.h +++ b/mozilla/string/public/nsAReadableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAReadableString_h___ @@ -117,6 +115,7 @@ class nsReadingIterator } public: + nsReadingIterator() { } // nsReadingIterator( const nsReadingIterator& ); // auto-generated copy-constructor OK // nsReadingIterator& operator=( const nsReadingIterator& ); // auto-generated copy-assignment operator OK @@ -197,43 +196,58 @@ class nsReadingIterator return mPosition - mFragment.mStart; } + nsReadingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsReadingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a readable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsReadingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a readable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } }; +template +nsReadingIterator& +nsReadingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + template inline PRBool @@ -271,8 +285,11 @@ class basic_nsAReadableString virtual ~basic_nsAReadableString() { } // ...yes, I expect to be sub-classed. - nsReadingIterator BeginReading() const; - nsReadingIterator EndReading() const; + nsReadingIterator& BeginReading( nsReadingIterator& ) const; + nsReadingIterator BeginReading() const; // deprecated + + nsReadingIterator& EndReading( nsReadingIterator& ) const; + nsReadingIterator EndReading() const; // deprecated virtual PRUint32 Length() const = 0; PRBool IsEmpty() const; @@ -408,8 +425,8 @@ inline void nsReadingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + while ( mPosition == mFragment.mEnd + && mOwningString->GetReadableFragment(mFragment, kNextFragment) ) mPosition = mFragment.mStart; } @@ -418,29 +435,56 @@ inline void nsReadingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + while ( mPosition == mFragment.mStart + && mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) mPosition = mFragment.mEnd; } + /** + * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? + */ +template +inline +nsReadingIterator& +basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + + // deprecated template inline nsReadingIterator basic_nsAReadableString::BeginReading() const { - nsReadableFragment fragment; - const CharT* startPos = GetReadableFragment(fragment, kFirstFragment); - return nsReadingIterator(fragment, startPos, *this); + nsReadingIterator result; + return BeginReading(result); // copies (since I return a value, not a reference) } template inline +nsReadingIterator& +basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated +template +inline nsReadingIterator basic_nsAReadableString::EndReading() const { - nsReadableFragment fragment; - GetReadableFragment(fragment, kLastFragment); - return nsReadingIterator(fragment, fragment.mEnd, *this); + nsReadingIterator result; + return EndReading(result); // copies (since I return a value, not a reference) } template @@ -545,7 +589,8 @@ basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { NS_ASSERTION(aIndex iter; + return *(BeginReading(iter).advance(PRInt32(aIndex))); } template @@ -562,7 +607,8 @@ basic_nsAReadableString::First() const { NS_ASSERTION(Length()>0, "|First()| on an empty string"); - return *BeginReading(); + nsReadingIterator iter; + return *BeginReading(iter); } template @@ -571,10 +617,11 @@ basic_nsAReadableString::Last() const { NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - // nsReadingIterator iter; EndReading(iter); - nsReadingIterator iter( EndReading() ); + nsReadingIterator iter; + EndReading(iter); + if ( !IsEmpty() ) - iter -= 1; + iter.advance(-1); return *iter; // Note: this has undefined results if |IsEmpty()| } @@ -584,19 +631,21 @@ PRUint32 basic_nsAReadableString::CountChar( CharT c ) const { #if 0 - return PRUint32(NS_COUNT(BeginReading(), EndReading(), c)); + nsReadingIterator countBegin, countEnd; + return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); #else PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - nsReadingIterator iter( BeginReading() ); - for (;;) + nsReadingIterator iter; + for ( BeginReading(iter); ; ) { PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - result += PRUint32(NS_COUNT(iter.get(), iter.get()+lengthToExamineInThisFragment, c)); + const CharT* fromBegin = iter.get(); + result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) return result; - iter += lengthToExamineInThisFragment; + iter.advance(lengthToExamineInThisFragment); } // never reached; quiets warnings return 0; @@ -638,21 +687,22 @@ template PRInt32 basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const { - nsReadingIterator start( BeginReading() ); - nsReadingIterator end( EndReading() ); + nsReadingIterator iter, done_searching; + BeginReading(iter).advance( PRInt32(aOffset) ); + EndReading(done_searching); - start += aOffset; + PRUint32 lengthSearched = 0; + while ( iter != done_searching ) + { + PRInt32 fragmentLength = iter.size_forward(); + const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); + if ( charFoundAt ) + return lengthSearched + (charFoundAt-iter.get()); - PRUint32 pos = 0; - while (start != end) { - PRUint32 fraglen = start.size_forward(); - const CharT* findPtr = nsCharTraits::find(start.get(), fraglen, aChar); - if (findPtr) { - return pos + (findPtr-start.get()); + lengthSearched += fragmentLength; + iter.advance(fragmentLength); } - pos += fraglen; - start += fraglen; - } + return -1; } @@ -1205,8 +1255,9 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - nsReadingIterator leftIter( lhs.BeginReading() ); - nsReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter, rightIter; + lhs.BeginReading(leftIter); + rhs.BeginReading(rightIter); int result; @@ -1224,8 +1275,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin if ( !(lengthToCompare -= lengthAvailable) ) break; - leftIter += PRInt32(lengthAvailable); - rightIter += PRInt32(lengthAvailable); + leftIter.advance( PRInt32(lengthAvailable) ); + rightIter.advance( PRInt32(lengthAvailable) ); } if ( lLength < rLength ) @@ -1370,7 +1421,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead else if ( mLength > kDefaultFlatStringSize-1 ) { CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - *copy_string(start, end, result) = CharT(0); + CharT* toBegin = result; + *copy_string(start, end, toBegin) = CharT(0); mBuffer = result; mOwnsBuffer = PR_TRUE; @@ -1378,7 +1430,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead // Otherwise copy into our internal buffer else { mBuffer = mInlineBuffer; - copy_string( start, end, NS_STATIC_CAST(CharT *, &mInlineBuffer[0])); + CharT* toBegin = &mInlineBuffer[0]; + copy_string( start, end, toBegin); mInlineBuffer[mLength] = 0; } } @@ -1405,26 +1458,26 @@ basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment } -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; +typedef basic_nsAReadableString nsAReadableString; +typedef basic_nsAReadableString nsAReadableCString; -typedef basic_nsLiteralString nsLiteralString; -typedef basic_nsLiteralString nsLiteralCString; +typedef basic_nsLiteralString nsLiteralString; +typedef basic_nsLiteralString nsLiteralCString; -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; +typedef basic_nsPromiseFlatString nsPromiseFlatString; +typedef basic_nsPromiseFlatString nsPromiseFlatCString; #ifdef HAVE_CPP_2BYTE_WCHAR_T - #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) + #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #define NS_NAMED_LITERAL_STRING(n,s) nsLiteralString n(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #else - #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) + #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) #define NS_NAMED_LITERAL_STRING(n,s) NS_ConvertASCIItoUCS2 n(s, sizeof(s)-1) #endif -#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) -#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) +#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) +#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) typedef basic_nsLiteralChar nsLiteralChar; typedef basic_nsLiteralChar nsLiteralPRUnichar; diff --git a/mozilla/string/public/nsAWritableString.h b/mozilla/string/public/nsAWritableString.h index 6954103f887..96be8c84ee3 100644 --- a/mozilla/string/public/nsAWritableString.h +++ b/mozilla/string/public/nsAWritableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAWritableString_h___ @@ -77,6 +75,7 @@ class nsWritingIterator } public: + nsWritingIterator() { } // nsWritingIterator( const nsWritingIterator& ); // auto-generated copy-constructor OK // nsWritingIterator& operator=( const nsWritingIterator& ); // auto-generated copy-assignment operator OK @@ -157,40 +156,24 @@ class nsWritingIterator return mPosition - mFragment.mStart; } + nsWritingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsWritingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsWritingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a writable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } PRUint32 @@ -200,11 +183,42 @@ class nsWritingIterator n = NS_MIN(n, PRUint32(size_forward())); nsCharTraits::move(mPosition, s, n); - operator+=( difference_type(n) ); + advance( difference_type(n) ); return n; } }; +template +nsWritingIterator& +nsWritingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + /* This file defines the abstract interfaces |nsAWritableString| and @@ -237,22 +251,44 @@ class basic_nsAWritableString virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + /** + * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? + */ + nsWritingIterator& + BeginWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + // deprecated nsWritingIterator BeginWriting() { - nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFirstFragment); - return nsWritingIterator(fragment, startPos, *this); + nsWritingIterator result; + return BeginWriting(result); // copies (since I return a value, not a reference) } + nsWritingIterator& + EndWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated nsWritingIterator EndWriting() { - nsWritableFragment fragment; - GetWritableFragment(fragment, kLastFragment); - return nsWritingIterator(fragment, fragment.mEnd, *this); + nsWritingIterator result; + return EndWriting(result); // copies (since I return a value, not a reference) } @@ -417,9 +453,9 @@ inline void nsWritingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; + while ( mPosition == mFragment.mEnd + && mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; } template @@ -427,9 +463,9 @@ inline void nsWritingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; + while ( mPosition == mFragment.mStart + && mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; } template @@ -497,7 +533,9 @@ basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString { // Note: not exception safe. We need something to manage temporary buffers like this - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AssignFromElementPtrLength(buffer, length); delete buffer; } @@ -514,7 +552,9 @@ basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableSt // first setting the length to |0| avoids copying characters only to be overwritten later // in the case where the implementation decides to re-allocate - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()); + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); } template @@ -566,7 +606,9 @@ basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AppendFromElementPtrLength(buffer, length); delete buffer; } @@ -580,7 +622,10 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); } template @@ -632,7 +677,9 @@ basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_InsertFromElementPtrLength(buffer, atPosition, length); delete buffer; } @@ -646,11 +693,14 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); } template @@ -687,8 +737,11 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) PRUint32 myLength = this->Length(); cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutEnd < myLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); SetLength(myLength-cutLength); } @@ -720,7 +773,9 @@ basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_ReplaceFromReadable(cutStart, cutLength, basic_nsLiteralString(buffer, length)); delete buffer; } @@ -743,13 +798,15 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutLength > replacementLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); + copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); } diff --git a/mozilla/string/public/nsAlgorithm.h b/mozilla/string/public/nsAlgorithm.h index 03c1c152f9f..2a3c68a7b89 100755 --- a/mozilla/string/public/nsAlgorithm.h +++ b/mozilla/string/public/nsAlgorithm.h @@ -17,10 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsAlgorithm_h___ @@ -50,7 +49,7 @@ NS_MAX( const T& a, const T& b ) template inline PRUint32 -NS_COUNT( InputIterator first, InputIterator last, const T& value ) +NS_COUNT( InputIterator& first, const InputIterator& last, const T& value ) { PRUint32 result = 0; for ( ; first != last; ++first ) @@ -61,8 +60,8 @@ NS_COUNT( InputIterator first, InputIterator last, const T& value ) template inline -OutputIterator -copy_string( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result ) { typedef nsCharSourceTraits source_traits; typedef nsCharSinkTraits sink_traits; @@ -71,15 +70,15 @@ copy_string( InputIterator first, InputIterator last, OutputIterator result ) { PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last))); NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate"); - first += count_copied; + source_traits::advance(first, count_copied); } return result; } template -OutputIterator -copy_string_backward( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result ) { while ( first != last ) { @@ -98,8 +97,8 @@ copy_string_backward( InputIterator first, InputIterator last, OutputIterator re nsCharTraits::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy); #endif - last -= PRInt32(lengthToCopy); - result -= PRInt32(lengthToCopy); + last.advance( -PRInt32(lengthToCopy) ); + result.advance( -PRInt32(lengthToCopy) ); } return result; diff --git a/mozilla/string/public/nsCharTraits.h b/mozilla/string/public/nsCharTraits.h index ec9c110688a..ca1c5c7f419 100644 --- a/mozilla/string/public/nsCharTraits.h +++ b/mozilla/string/public/nsCharTraits.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsCharTraits_h___ @@ -466,6 +464,8 @@ struct nsCharTraits template struct nsCharSourceTraits { + typedef typename InputIterator::difference_type difference_type; + #if 0 static PRUint32 @@ -495,6 +495,13 @@ struct nsCharSourceTraits { return iter.get(); } + + static + void + advance( InputIterator& s, difference_type n ) + { + s.advance(n); + } }; #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION @@ -502,6 +509,8 @@ struct nsCharSourceTraits template struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -532,6 +541,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; #else @@ -539,6 +555,8 @@ struct nsCharSourceTraits NS_SPECIALIZE_TEMPLATE struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -569,6 +587,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; // Add specialization for |PRUnichar| only if it is needed diff --git a/mozilla/string/public/nsFragmentedString.h b/mozilla/string/public/nsFragmentedString.h index e1e6fe383dd..2b0891d88cf 100644 --- a/mozilla/string/public/nsFragmentedString.h +++ b/mozilla/string/public/nsFragmentedString.h @@ -17,10 +17,9 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsFragmentedString_h___ @@ -89,7 +88,10 @@ nsChunkList::NewChunk( const CharT* aData, PRUint32 aDataLength, PRUint32 typedef CharT* CharT_ptr; CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) - copy_string(aData, aData+aDataLength, buffer_ptr); + { + CharT* toBegin = buffer_ptr; + copy_string(aData, aData+aDataLength, toBegin); + } return new (object_ptr) Chunk(buffer_ptr, buffer_length, aDataLength); } diff --git a/mozilla/string/public/nsSharedString.h b/mozilla/string/public/nsSharedString.h index 80f2c133356..b94fd4a02b0 100644 --- a/mozilla/string/public/nsSharedString.h +++ b/mozilla/string/public/nsSharedString.h @@ -182,7 +182,10 @@ new_nsSharedString( const basic_nsAReadableString& aReadable ) { typedef CharT* CharT_ptr; CharT* string_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), string_ptr); + + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = string_ptr; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); return new (object_ptr) basic_nsSharedString(string_ptr, string_length); } diff --git a/mozilla/string/src/nsReadableUtils.cpp b/mozilla/string/src/nsReadableUtils.cpp index 07bbaf8b8fa..405a011d6e0 100755 --- a/mozilla/string/src/nsReadableUtils.cpp +++ b/mozilla/string/src/nsReadableUtils.cpp @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #include "nsReadableUtils.h" @@ -72,7 +70,10 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } NS_COM @@ -81,7 +82,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } @@ -106,7 +110,10 @@ char* ToNewCString( const nsAReadableString& aSource ) { char* result = AllocateStringCopy(aSource, (char*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } @@ -141,7 +148,10 @@ ToNewCString( const nsAReadableCString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it char* result = AllocateStringCopy(aSource, (char*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = char(0); + + nsReadingIterator fromBegin, fromEnd; + char* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = char(0); return result; } @@ -152,7 +162,10 @@ ToNewUnicode( const nsAReadableString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = PRUnichar(0); + + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = PRUnichar(0); return result; } @@ -161,22 +174,20 @@ PRUnichar* ToNewUnicode( const nsAReadableCString& aSource ) { PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } NS_COM PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, - PRUnichar* aDest, - PRUint32 aLength ) +CopyUnicodeTo( const nsAReadableString& aSource, PRUnichar* aDest, PRUint32 aLength ) { - typedef nsAReadableString::const_iterator iterator; - - iterator done_reading = aSource.BeginReading(); - done_reading += aLength; - - copy_string(aSource.BeginReading(), done_reading, aDest); + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = aDest; + copy_string(aSource.BeginReading(fromBegin), aSource.BeginReading(fromEnd).advance( PRInt32(aLength) ), toBegin); return aDest; } @@ -189,23 +200,22 @@ IsASCII( const nsAReadableString& aString ) // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character - typedef nsAReadableString::const_iterator iterator; - iterator iter = aString.BeginReading(); - iterator done_reading = aString.EndReading(); + nsReadingIterator done_reading; + aString.EndReading(done_reading); // for each chunk of |aString|... - while ( iter != done_reading ) + PRUint32 fragmentLength = 0; + nsReadingIterator iter; + for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) ) { - iterator::difference_type chunk_size = iter.size_forward(); + fragmentLength = iter.size_forward(); const PRUnichar* c = iter.get(); - const PRUnichar* chunk_end = c + chunk_size; + const PRUnichar* fragmentEnd = c + fragmentLength; // for each character in this chunk... - while ( c < chunk_end ) + while ( c < fragmentEnd ) if ( *c++ & NOT_ASCII ) return PR_FALSE; - - iter += chunk_size; } return PR_TRUE; diff --git a/mozilla/xpcom/ds/nsAReadableString.h b/mozilla/xpcom/ds/nsAReadableString.h index 981c999aff1..56b695d4d9d 100644 --- a/mozilla/xpcom/ds/nsAReadableString.h +++ b/mozilla/xpcom/ds/nsAReadableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAReadableString_h___ @@ -117,6 +115,7 @@ class nsReadingIterator } public: + nsReadingIterator() { } // nsReadingIterator( const nsReadingIterator& ); // auto-generated copy-constructor OK // nsReadingIterator& operator=( const nsReadingIterator& ); // auto-generated copy-assignment operator OK @@ -197,43 +196,58 @@ class nsReadingIterator return mPosition - mFragment.mStart; } + nsReadingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsReadingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a readable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsReadingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a readable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } }; +template +nsReadingIterator& +nsReadingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + template inline PRBool @@ -271,8 +285,11 @@ class basic_nsAReadableString virtual ~basic_nsAReadableString() { } // ...yes, I expect to be sub-classed. - nsReadingIterator BeginReading() const; - nsReadingIterator EndReading() const; + nsReadingIterator& BeginReading( nsReadingIterator& ) const; + nsReadingIterator BeginReading() const; // deprecated + + nsReadingIterator& EndReading( nsReadingIterator& ) const; + nsReadingIterator EndReading() const; // deprecated virtual PRUint32 Length() const = 0; PRBool IsEmpty() const; @@ -408,8 +425,8 @@ inline void nsReadingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + while ( mPosition == mFragment.mEnd + && mOwningString->GetReadableFragment(mFragment, kNextFragment) ) mPosition = mFragment.mStart; } @@ -418,29 +435,56 @@ inline void nsReadingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + while ( mPosition == mFragment.mStart + && mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) mPosition = mFragment.mEnd; } + /** + * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? + */ +template +inline +nsReadingIterator& +basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + + // deprecated template inline nsReadingIterator basic_nsAReadableString::BeginReading() const { - nsReadableFragment fragment; - const CharT* startPos = GetReadableFragment(fragment, kFirstFragment); - return nsReadingIterator(fragment, startPos, *this); + nsReadingIterator result; + return BeginReading(result); // copies (since I return a value, not a reference) } template inline +nsReadingIterator& +basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated +template +inline nsReadingIterator basic_nsAReadableString::EndReading() const { - nsReadableFragment fragment; - GetReadableFragment(fragment, kLastFragment); - return nsReadingIterator(fragment, fragment.mEnd, *this); + nsReadingIterator result; + return EndReading(result); // copies (since I return a value, not a reference) } template @@ -545,7 +589,8 @@ basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { NS_ASSERTION(aIndex iter; + return *(BeginReading(iter).advance(PRInt32(aIndex))); } template @@ -562,7 +607,8 @@ basic_nsAReadableString::First() const { NS_ASSERTION(Length()>0, "|First()| on an empty string"); - return *BeginReading(); + nsReadingIterator iter; + return *BeginReading(iter); } template @@ -571,10 +617,11 @@ basic_nsAReadableString::Last() const { NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - // nsReadingIterator iter; EndReading(iter); - nsReadingIterator iter( EndReading() ); + nsReadingIterator iter; + EndReading(iter); + if ( !IsEmpty() ) - iter -= 1; + iter.advance(-1); return *iter; // Note: this has undefined results if |IsEmpty()| } @@ -584,19 +631,21 @@ PRUint32 basic_nsAReadableString::CountChar( CharT c ) const { #if 0 - return PRUint32(NS_COUNT(BeginReading(), EndReading(), c)); + nsReadingIterator countBegin, countEnd; + return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); #else PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - nsReadingIterator iter( BeginReading() ); - for (;;) + nsReadingIterator iter; + for ( BeginReading(iter); ; ) { PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - result += PRUint32(NS_COUNT(iter.get(), iter.get()+lengthToExamineInThisFragment, c)); + const CharT* fromBegin = iter.get(); + result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) return result; - iter += lengthToExamineInThisFragment; + iter.advance(lengthToExamineInThisFragment); } // never reached; quiets warnings return 0; @@ -638,21 +687,22 @@ template PRInt32 basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const { - nsReadingIterator start( BeginReading() ); - nsReadingIterator end( EndReading() ); + nsReadingIterator iter, done_searching; + BeginReading(iter).advance( PRInt32(aOffset) ); + EndReading(done_searching); - start += aOffset; + PRUint32 lengthSearched = 0; + while ( iter != done_searching ) + { + PRInt32 fragmentLength = iter.size_forward(); + const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); + if ( charFoundAt ) + return lengthSearched + (charFoundAt-iter.get()); - PRUint32 pos = 0; - while (start != end) { - PRUint32 fraglen = start.size_forward(); - const CharT* findPtr = nsCharTraits::find(start.get(), fraglen, aChar); - if (findPtr) { - return pos + (findPtr-start.get()); + lengthSearched += fragmentLength; + iter.advance(fragmentLength); } - pos += fraglen; - start += fraglen; - } + return -1; } @@ -1205,8 +1255,9 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - nsReadingIterator leftIter( lhs.BeginReading() ); - nsReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter, rightIter; + lhs.BeginReading(leftIter); + rhs.BeginReading(rightIter); int result; @@ -1224,8 +1275,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin if ( !(lengthToCompare -= lengthAvailable) ) break; - leftIter += PRInt32(lengthAvailable); - rightIter += PRInt32(lengthAvailable); + leftIter.advance( PRInt32(lengthAvailable) ); + rightIter.advance( PRInt32(lengthAvailable) ); } if ( lLength < rLength ) @@ -1370,7 +1421,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead else if ( mLength > kDefaultFlatStringSize-1 ) { CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - *copy_string(start, end, result) = CharT(0); + CharT* toBegin = result; + *copy_string(start, end, toBegin) = CharT(0); mBuffer = result; mOwnsBuffer = PR_TRUE; @@ -1378,7 +1430,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead // Otherwise copy into our internal buffer else { mBuffer = mInlineBuffer; - copy_string( start, end, NS_STATIC_CAST(CharT *, &mInlineBuffer[0])); + CharT* toBegin = &mInlineBuffer[0]; + copy_string( start, end, toBegin); mInlineBuffer[mLength] = 0; } } @@ -1405,26 +1458,26 @@ basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment } -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; +typedef basic_nsAReadableString nsAReadableString; +typedef basic_nsAReadableString nsAReadableCString; -typedef basic_nsLiteralString nsLiteralString; -typedef basic_nsLiteralString nsLiteralCString; +typedef basic_nsLiteralString nsLiteralString; +typedef basic_nsLiteralString nsLiteralCString; -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; +typedef basic_nsPromiseFlatString nsPromiseFlatString; +typedef basic_nsPromiseFlatString nsPromiseFlatCString; #ifdef HAVE_CPP_2BYTE_WCHAR_T - #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) + #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #define NS_NAMED_LITERAL_STRING(n,s) nsLiteralString n(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #else - #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) + #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) #define NS_NAMED_LITERAL_STRING(n,s) NS_ConvertASCIItoUCS2 n(s, sizeof(s)-1) #endif -#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) -#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) +#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) +#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) typedef basic_nsLiteralChar nsLiteralChar; typedef basic_nsLiteralChar nsLiteralPRUnichar; diff --git a/mozilla/xpcom/ds/nsAWritableString.h b/mozilla/xpcom/ds/nsAWritableString.h index 6954103f887..96be8c84ee3 100644 --- a/mozilla/xpcom/ds/nsAWritableString.h +++ b/mozilla/xpcom/ds/nsAWritableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAWritableString_h___ @@ -77,6 +75,7 @@ class nsWritingIterator } public: + nsWritingIterator() { } // nsWritingIterator( const nsWritingIterator& ); // auto-generated copy-constructor OK // nsWritingIterator& operator=( const nsWritingIterator& ); // auto-generated copy-assignment operator OK @@ -157,40 +156,24 @@ class nsWritingIterator return mPosition - mFragment.mStart; } + nsWritingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsWritingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsWritingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a writable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } PRUint32 @@ -200,11 +183,42 @@ class nsWritingIterator n = NS_MIN(n, PRUint32(size_forward())); nsCharTraits::move(mPosition, s, n); - operator+=( difference_type(n) ); + advance( difference_type(n) ); return n; } }; +template +nsWritingIterator& +nsWritingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + /* This file defines the abstract interfaces |nsAWritableString| and @@ -237,22 +251,44 @@ class basic_nsAWritableString virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + /** + * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? + */ + nsWritingIterator& + BeginWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + // deprecated nsWritingIterator BeginWriting() { - nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFirstFragment); - return nsWritingIterator(fragment, startPos, *this); + nsWritingIterator result; + return BeginWriting(result); // copies (since I return a value, not a reference) } + nsWritingIterator& + EndWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated nsWritingIterator EndWriting() { - nsWritableFragment fragment; - GetWritableFragment(fragment, kLastFragment); - return nsWritingIterator(fragment, fragment.mEnd, *this); + nsWritingIterator result; + return EndWriting(result); // copies (since I return a value, not a reference) } @@ -417,9 +453,9 @@ inline void nsWritingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; + while ( mPosition == mFragment.mEnd + && mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; } template @@ -427,9 +463,9 @@ inline void nsWritingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; + while ( mPosition == mFragment.mStart + && mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; } template @@ -497,7 +533,9 @@ basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString { // Note: not exception safe. We need something to manage temporary buffers like this - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AssignFromElementPtrLength(buffer, length); delete buffer; } @@ -514,7 +552,9 @@ basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableSt // first setting the length to |0| avoids copying characters only to be overwritten later // in the case where the implementation decides to re-allocate - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()); + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); } template @@ -566,7 +606,9 @@ basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AppendFromElementPtrLength(buffer, length); delete buffer; } @@ -580,7 +622,10 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); } template @@ -632,7 +677,9 @@ basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_InsertFromElementPtrLength(buffer, atPosition, length); delete buffer; } @@ -646,11 +693,14 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); } template @@ -687,8 +737,11 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) PRUint32 myLength = this->Length(); cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutEnd < myLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); SetLength(myLength-cutLength); } @@ -720,7 +773,9 @@ basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_ReplaceFromReadable(cutStart, cutLength, basic_nsLiteralString(buffer, length)); delete buffer; } @@ -743,13 +798,15 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutLength > replacementLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); + copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); } diff --git a/mozilla/xpcom/ds/nsAlgorithm.h b/mozilla/xpcom/ds/nsAlgorithm.h index 03c1c152f9f..2a3c68a7b89 100755 --- a/mozilla/xpcom/ds/nsAlgorithm.h +++ b/mozilla/xpcom/ds/nsAlgorithm.h @@ -17,10 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsAlgorithm_h___ @@ -50,7 +49,7 @@ NS_MAX( const T& a, const T& b ) template inline PRUint32 -NS_COUNT( InputIterator first, InputIterator last, const T& value ) +NS_COUNT( InputIterator& first, const InputIterator& last, const T& value ) { PRUint32 result = 0; for ( ; first != last; ++first ) @@ -61,8 +60,8 @@ NS_COUNT( InputIterator first, InputIterator last, const T& value ) template inline -OutputIterator -copy_string( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result ) { typedef nsCharSourceTraits source_traits; typedef nsCharSinkTraits sink_traits; @@ -71,15 +70,15 @@ copy_string( InputIterator first, InputIterator last, OutputIterator result ) { PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last))); NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate"); - first += count_copied; + source_traits::advance(first, count_copied); } return result; } template -OutputIterator -copy_string_backward( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result ) { while ( first != last ) { @@ -98,8 +97,8 @@ copy_string_backward( InputIterator first, InputIterator last, OutputIterator re nsCharTraits::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy); #endif - last -= PRInt32(lengthToCopy); - result -= PRInt32(lengthToCopy); + last.advance( -PRInt32(lengthToCopy) ); + result.advance( -PRInt32(lengthToCopy) ); } return result; diff --git a/mozilla/xpcom/ds/nsAtomTable.cpp b/mozilla/xpcom/ds/nsAtomTable.cpp index 12ad504a071..e160a465418 100644 --- a/mozilla/xpcom/ds/nsAtomTable.cpp +++ b/mozilla/xpcom/ds/nsAtomTable.cpp @@ -133,7 +133,10 @@ void* AtomImpl::operator new ( size_t size, const nsAReadableString& aString ) */ size += aString.Length() * sizeof(PRUnichar); AtomImpl* ii = (AtomImpl*) ::operator new(size); - *copy_string(aString.BeginReading(), aString.EndReading(), NS_STATIC_CAST(PRUnichar *, &ii->mString[0])) = PRUnichar(0); + + PRUnichar* toBegin = &ii->mString[0]; + nsReadingIterator fromBegin, fromEnd; + *copy_string(aString.BeginReading(fromBegin), aString.EndReading(fromEnd), toBegin) = PRUnichar(0); return ii; } @@ -166,8 +169,11 @@ AtomImpl::SizeOf(nsISizeOfHandler* aHandler, PRUint32* _retval) /*FIX: const */ static PLHashNumber HashKey(const nsAReadableString* k) { - return (PLHashNumber) copy_string(k->BeginReading(), k->EndReading(), - CalculateHash()).GetHash(); + CalculateHash hasher; + nsReadingIterator hashBegin, hashEnd; + copy_string(k->BeginReading(hashBegin), k->EndReading(hashEnd), hasher); + + return NS_STATIC_CAST(PLHashNumber, hasher.GetHash()); } static PRIntn CompareKeys( const nsAReadableString* k1, const PRUnichar* k2 ) @@ -187,8 +193,9 @@ NS_COM nsIAtom* NS_NewAtom( const nsAReadableString& aString ) (PLHashComparator)CompareKeys, (PLHashComparator)0, 0, 0); - CalculateHash hasher = copy_string(aString.BeginReading(), - aString.EndReading(), CalculateHash()); + CalculateHash hasher; + nsReadingIterator hashBegin, hashEnd; + copy_string(aString.BeginReading(hashBegin), aString.EndReading(hashEnd), hasher); PRUint32 hashCode = hasher.GetHash(); diff --git a/mozilla/xpcom/ds/nsCharTraits.h b/mozilla/xpcom/ds/nsCharTraits.h index ec9c110688a..ca1c5c7f419 100644 --- a/mozilla/xpcom/ds/nsCharTraits.h +++ b/mozilla/xpcom/ds/nsCharTraits.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsCharTraits_h___ @@ -466,6 +464,8 @@ struct nsCharTraits template struct nsCharSourceTraits { + typedef typename InputIterator::difference_type difference_type; + #if 0 static PRUint32 @@ -495,6 +495,13 @@ struct nsCharSourceTraits { return iter.get(); } + + static + void + advance( InputIterator& s, difference_type n ) + { + s.advance(n); + } }; #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION @@ -502,6 +509,8 @@ struct nsCharSourceTraits template struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -532,6 +541,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; #else @@ -539,6 +555,8 @@ struct nsCharSourceTraits NS_SPECIALIZE_TEMPLATE struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -569,6 +587,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; // Add specialization for |PRUnichar| only if it is needed diff --git a/mozilla/xpcom/ds/nsFragmentedString.h b/mozilla/xpcom/ds/nsFragmentedString.h index e1e6fe383dd..2b0891d88cf 100644 --- a/mozilla/xpcom/ds/nsFragmentedString.h +++ b/mozilla/xpcom/ds/nsFragmentedString.h @@ -17,10 +17,9 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsFragmentedString_h___ @@ -89,7 +88,10 @@ nsChunkList::NewChunk( const CharT* aData, PRUint32 aDataLength, PRUint32 typedef CharT* CharT_ptr; CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) - copy_string(aData, aData+aDataLength, buffer_ptr); + { + CharT* toBegin = buffer_ptr; + copy_string(aData, aData+aDataLength, toBegin); + } return new (object_ptr) Chunk(buffer_ptr, buffer_length, aDataLength); } diff --git a/mozilla/xpcom/ds/nsReadableUtils.cpp b/mozilla/xpcom/ds/nsReadableUtils.cpp index 07bbaf8b8fa..405a011d6e0 100755 --- a/mozilla/xpcom/ds/nsReadableUtils.cpp +++ b/mozilla/xpcom/ds/nsReadableUtils.cpp @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #include "nsReadableUtils.h" @@ -72,7 +70,10 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } NS_COM @@ -81,7 +82,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } @@ -106,7 +110,10 @@ char* ToNewCString( const nsAReadableString& aSource ) { char* result = AllocateStringCopy(aSource, (char*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } @@ -141,7 +148,10 @@ ToNewCString( const nsAReadableCString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it char* result = AllocateStringCopy(aSource, (char*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = char(0); + + nsReadingIterator fromBegin, fromEnd; + char* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = char(0); return result; } @@ -152,7 +162,10 @@ ToNewUnicode( const nsAReadableString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = PRUnichar(0); + + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = PRUnichar(0); return result; } @@ -161,22 +174,20 @@ PRUnichar* ToNewUnicode( const nsAReadableCString& aSource ) { PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } NS_COM PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, - PRUnichar* aDest, - PRUint32 aLength ) +CopyUnicodeTo( const nsAReadableString& aSource, PRUnichar* aDest, PRUint32 aLength ) { - typedef nsAReadableString::const_iterator iterator; - - iterator done_reading = aSource.BeginReading(); - done_reading += aLength; - - copy_string(aSource.BeginReading(), done_reading, aDest); + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = aDest; + copy_string(aSource.BeginReading(fromBegin), aSource.BeginReading(fromEnd).advance( PRInt32(aLength) ), toBegin); return aDest; } @@ -189,23 +200,22 @@ IsASCII( const nsAReadableString& aString ) // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character - typedef nsAReadableString::const_iterator iterator; - iterator iter = aString.BeginReading(); - iterator done_reading = aString.EndReading(); + nsReadingIterator done_reading; + aString.EndReading(done_reading); // for each chunk of |aString|... - while ( iter != done_reading ) + PRUint32 fragmentLength = 0; + nsReadingIterator iter; + for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) ) { - iterator::difference_type chunk_size = iter.size_forward(); + fragmentLength = iter.size_forward(); const PRUnichar* c = iter.get(); - const PRUnichar* chunk_end = c + chunk_size; + const PRUnichar* fragmentEnd = c + fragmentLength; // for each character in this chunk... - while ( c < chunk_end ) + while ( c < fragmentEnd ) if ( *c++ & NOT_ASCII ) return PR_FALSE; - - iter += chunk_size; } return PR_TRUE; diff --git a/mozilla/xpcom/ds/nsSharedString.h b/mozilla/xpcom/ds/nsSharedString.h index 80f2c133356..b94fd4a02b0 100644 --- a/mozilla/xpcom/ds/nsSharedString.h +++ b/mozilla/xpcom/ds/nsSharedString.h @@ -182,7 +182,10 @@ new_nsSharedString( const basic_nsAReadableString& aReadable ) { typedef CharT* CharT_ptr; CharT* string_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), string_ptr); + + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = string_ptr; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); return new (object_ptr) basic_nsSharedString(string_ptr, string_length); } diff --git a/mozilla/xpcom/io/nsStringIO.h b/mozilla/xpcom/io/nsStringIO.h index 119e6f8ac5f..b02c1f5dcdc 100644 --- a/mozilla/xpcom/io/nsStringIO.h +++ b/mozilla/xpcom/io/nsStringIO.h @@ -55,7 +55,9 @@ inline void fprint_string( FILE* aFile, const basic_nsAReadableString& aString ) { - copy_string(aString.BeginReading(), aString.EndReading(), nsFileCharSink(aFile)); + nsReadingIterator fromBegin, fromEnd; + nsFileCharSink toBegin(aFile); + copy_string(aString.BeginReading(fromBegin), aString.EndReading(fromEnd), toBegin); } diff --git a/mozilla/xpcom/string/public/nsAReadableString.h b/mozilla/xpcom/string/public/nsAReadableString.h index 981c999aff1..56b695d4d9d 100644 --- a/mozilla/xpcom/string/public/nsAReadableString.h +++ b/mozilla/xpcom/string/public/nsAReadableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAReadableString_h___ @@ -117,6 +115,7 @@ class nsReadingIterator } public: + nsReadingIterator() { } // nsReadingIterator( const nsReadingIterator& ); // auto-generated copy-constructor OK // nsReadingIterator& operator=( const nsReadingIterator& ); // auto-generated copy-assignment operator OK @@ -197,43 +196,58 @@ class nsReadingIterator return mPosition - mFragment.mStart; } + nsReadingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsReadingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a readable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsReadingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a readable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } }; +template +nsReadingIterator& +nsReadingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + template inline PRBool @@ -271,8 +285,11 @@ class basic_nsAReadableString virtual ~basic_nsAReadableString() { } // ...yes, I expect to be sub-classed. - nsReadingIterator BeginReading() const; - nsReadingIterator EndReading() const; + nsReadingIterator& BeginReading( nsReadingIterator& ) const; + nsReadingIterator BeginReading() const; // deprecated + + nsReadingIterator& EndReading( nsReadingIterator& ) const; + nsReadingIterator EndReading() const; // deprecated virtual PRUint32 Length() const = 0; PRBool IsEmpty() const; @@ -408,8 +425,8 @@ inline void nsReadingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) ) + while ( mPosition == mFragment.mEnd + && mOwningString->GetReadableFragment(mFragment, kNextFragment) ) mPosition = mFragment.mStart; } @@ -418,29 +435,56 @@ inline void nsReadingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) + while ( mPosition == mFragment.mStart + && mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) mPosition = mFragment.mEnd; } + /** + * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? + */ +template +inline +nsReadingIterator& +basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + + // deprecated template inline nsReadingIterator basic_nsAReadableString::BeginReading() const { - nsReadableFragment fragment; - const CharT* startPos = GetReadableFragment(fragment, kFirstFragment); - return nsReadingIterator(fragment, startPos, *this); + nsReadingIterator result; + return BeginReading(result); // copies (since I return a value, not a reference) } template inline +nsReadingIterator& +basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated +template +inline nsReadingIterator basic_nsAReadableString::EndReading() const { - nsReadableFragment fragment; - GetReadableFragment(fragment, kLastFragment); - return nsReadingIterator(fragment, fragment.mEnd, *this); + nsReadingIterator result; + return EndReading(result); // copies (since I return a value, not a reference) } template @@ -545,7 +589,8 @@ basic_nsAReadableString::CharAt( PRUint32 aIndex ) const { NS_ASSERTION(aIndex iter; + return *(BeginReading(iter).advance(PRInt32(aIndex))); } template @@ -562,7 +607,8 @@ basic_nsAReadableString::First() const { NS_ASSERTION(Length()>0, "|First()| on an empty string"); - return *BeginReading(); + nsReadingIterator iter; + return *BeginReading(iter); } template @@ -571,10 +617,11 @@ basic_nsAReadableString::Last() const { NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - // nsReadingIterator iter; EndReading(iter); - nsReadingIterator iter( EndReading() ); + nsReadingIterator iter; + EndReading(iter); + if ( !IsEmpty() ) - iter -= 1; + iter.advance(-1); return *iter; // Note: this has undefined results if |IsEmpty()| } @@ -584,19 +631,21 @@ PRUint32 basic_nsAReadableString::CountChar( CharT c ) const { #if 0 - return PRUint32(NS_COUNT(BeginReading(), EndReading(), c)); + nsReadingIterator countBegin, countEnd; + return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); #else PRUint32 result = 0; PRUint32 lengthToExamine = Length(); - nsReadingIterator iter( BeginReading() ); - for (;;) + nsReadingIterator iter; + for ( BeginReading(iter); ; ) { PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - result += PRUint32(NS_COUNT(iter.get(), iter.get()+lengthToExamineInThisFragment, c)); + const CharT* fromBegin = iter.get(); + result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) return result; - iter += lengthToExamineInThisFragment; + iter.advance(lengthToExamineInThisFragment); } // never reached; quiets warnings return 0; @@ -638,21 +687,22 @@ template PRInt32 basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const { - nsReadingIterator start( BeginReading() ); - nsReadingIterator end( EndReading() ); + nsReadingIterator iter, done_searching; + BeginReading(iter).advance( PRInt32(aOffset) ); + EndReading(done_searching); - start += aOffset; + PRUint32 lengthSearched = 0; + while ( iter != done_searching ) + { + PRInt32 fragmentLength = iter.size_forward(); + const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); + if ( charFoundAt ) + return lengthSearched + (charFoundAt-iter.get()); - PRUint32 pos = 0; - while (start != end) { - PRUint32 fraglen = start.size_forward(); - const CharT* findPtr = nsCharTraits::find(start.get(), fraglen, aChar); - if (findPtr) { - return pos + (findPtr-start.get()); + lengthSearched += fragmentLength; + iter.advance(fragmentLength); } - pos += fraglen; - start += fraglen; - } + return -1; } @@ -1205,8 +1255,9 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin PRUint32 rLength = rhs.Length(); PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - nsReadingIterator leftIter( lhs.BeginReading() ); - nsReadingIterator rightIter( rhs.BeginReading() ); + nsReadingIterator leftIter, rightIter; + lhs.BeginReading(leftIter); + rhs.BeginReading(rightIter); int result; @@ -1224,8 +1275,8 @@ Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableStrin if ( !(lengthToCompare -= lengthAvailable) ) break; - leftIter += PRInt32(lengthAvailable); - rightIter += PRInt32(lengthAvailable); + leftIter.advance( PRInt32(lengthAvailable) ); + rightIter.advance( PRInt32(lengthAvailable) ); } if ( lLength < rLength ) @@ -1370,7 +1421,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead else if ( mLength > kDefaultFlatStringSize-1 ) { CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - *copy_string(start, end, result) = CharT(0); + CharT* toBegin = result; + *copy_string(start, end, toBegin) = CharT(0); mBuffer = result; mOwnsBuffer = PR_TRUE; @@ -1378,7 +1430,8 @@ basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsARead // Otherwise copy into our internal buffer else { mBuffer = mInlineBuffer; - copy_string( start, end, NS_STATIC_CAST(CharT *, &mInlineBuffer[0])); + CharT* toBegin = &mInlineBuffer[0]; + copy_string( start, end, toBegin); mInlineBuffer[mLength] = 0; } } @@ -1405,26 +1458,26 @@ basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment } -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; +typedef basic_nsAReadableString nsAReadableString; +typedef basic_nsAReadableString nsAReadableCString; -typedef basic_nsLiteralString nsLiteralString; -typedef basic_nsLiteralString nsLiteralCString; +typedef basic_nsLiteralString nsLiteralString; +typedef basic_nsLiteralString nsLiteralCString; -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; +typedef basic_nsPromiseFlatString nsPromiseFlatString; +typedef basic_nsPromiseFlatString nsPromiseFlatCString; #ifdef HAVE_CPP_2BYTE_WCHAR_T - #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) + #define NS_LITERAL_STRING(s) nsLiteralString(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #define NS_NAMED_LITERAL_STRING(n,s) nsLiteralString n(L##s, (sizeof(L##s)/sizeof(wchar_t))-1) #else - #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) + #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) #define NS_NAMED_LITERAL_STRING(n,s) NS_ConvertASCIItoUCS2 n(s, sizeof(s)-1) #endif -#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) -#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) +#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) +#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) typedef basic_nsLiteralChar nsLiteralChar; typedef basic_nsLiteralChar nsLiteralPRUnichar; diff --git a/mozilla/xpcom/string/public/nsAWritableString.h b/mozilla/xpcom/string/public/nsAWritableString.h index 6954103f887..96be8c84ee3 100644 --- a/mozilla/xpcom/string/public/nsAWritableString.h +++ b/mozilla/xpcom/string/public/nsAWritableString.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsAWritableString_h___ @@ -77,6 +75,7 @@ class nsWritingIterator } public: + nsWritingIterator() { } // nsWritingIterator( const nsWritingIterator& ); // auto-generated copy-constructor OK // nsWritingIterator& operator=( const nsWritingIterator& ); // auto-generated copy-assignment operator OK @@ -157,40 +156,24 @@ class nsWritingIterator return mPosition - mFragment.mStart; } + nsWritingIterator& advance( difference_type ); + + /** + * Really don't want to call these two operations |+=| and |-=|. + * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. + * + * We'll get rid of these as soon as we can. + */ nsWritingIterator& - operator+=( difference_type n ) + operator+=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator-=(-n); - - while ( n ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writable iterator beyond the end of a string"); - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - return *this; + return advance(n); } nsWritingIterator& - operator-=( difference_type n ) + operator-=( difference_type n ) // deprecated { - if ( n < 0 ) - return operator+=(-n); - - while ( n ) - { - normalize_backward(); - difference_type one_hop = NS_MIN(n, size_backward()); - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance (backward) a writable iterator beyond the end of a string"); - mPosition -= one_hop; - n -= one_hop; - } - - return *this; + return advance(-n); } PRUint32 @@ -200,11 +183,42 @@ class nsWritingIterator n = NS_MIN(n, PRUint32(size_forward())); nsCharTraits::move(mPosition, s, n); - operator+=( difference_type(n) ); + advance( difference_type(n) ); return n; } }; +template +nsWritingIterator& +nsWritingIterator::advance( difference_type n ) + { + while ( n > 0 ) + { + difference_type one_hop = NS_MIN(n, size_forward()); + + NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + normalize_forward(); + n -= one_hop; + } + + while ( n < 0 ) + { + normalize_backward(); + difference_type one_hop = NS_MAX(n, -size_backward()); + + NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string"); + // perhaps I should |break| if |!one_hop|? + + mPosition += one_hop; + n -= one_hop; + } + + return *this; + } + /* This file defines the abstract interfaces |nsAWritableString| and @@ -237,22 +251,44 @@ class basic_nsAWritableString virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + /** + * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? + */ + nsWritingIterator& + BeginWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.normalize_forward(); + aResult.mPosition = aResult.mFragment.mStart; + return aResult; + } + // deprecated nsWritingIterator BeginWriting() { - nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFirstFragment); - return nsWritingIterator(fragment, startPos, *this); + nsWritingIterator result; + return BeginWriting(result); // copies (since I return a value, not a reference) } + nsWritingIterator& + EndWriting( nsWritingIterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + + // deprecated nsWritingIterator EndWriting() { - nsWritableFragment fragment; - GetWritableFragment(fragment, kLastFragment); - return nsWritingIterator(fragment, fragment.mEnd, *this); + nsWritingIterator result; + return EndWriting(result); // copies (since I return a value, not a reference) } @@ -417,9 +453,9 @@ inline void nsWritingIterator::normalize_forward() { - if ( mPosition == mFragment.mEnd ) - if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; + while ( mPosition == mFragment.mEnd + && mOwningString->GetWritableFragment(mFragment, kNextFragment) ) + mPosition = mFragment.mStart; } template @@ -427,9 +463,9 @@ inline void nsWritingIterator::normalize_backward() { - if ( mPosition == mFragment.mStart ) - if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; + while ( mPosition == mFragment.mStart + && mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) + mPosition = mFragment.mEnd; } template @@ -497,7 +533,9 @@ basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString { // Note: not exception safe. We need something to manage temporary buffers like this - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AssignFromElementPtrLength(buffer, length); delete buffer; } @@ -514,7 +552,9 @@ basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableSt // first setting the length to |0| avoids copying characters only to be overwritten later // in the case where the implementation decides to re-allocate - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()); + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); } template @@ -566,7 +606,9 @@ basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_AppendFromElementPtrLength(buffer, length); delete buffer; } @@ -580,7 +622,10 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); } template @@ -632,7 +677,9 @@ basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_InsertFromElementPtrLength(buffer, atPosition, length); delete buffer; } @@ -646,11 +693,14 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); } template @@ -687,8 +737,11 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) PRUint32 myLength = this->Length(); cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutEnd < myLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); SetLength(myLength-cutLength); } @@ -720,7 +773,9 @@ basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 CharT* buffer = new CharT[length]; if ( buffer ) { - copy_string(aReadable.BeginReading(), aReadable.EndReading(), buffer); + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = buffer; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); do_ReplaceFromReadable(cutStart, cutLength, basic_nsLiteralString(buffer, length)); delete buffer; } @@ -743,13 +798,15 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; if ( cutLength > replacementLength ) - copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); + copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); + copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); + copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); } diff --git a/mozilla/xpcom/string/public/nsAlgorithm.h b/mozilla/xpcom/string/public/nsAlgorithm.h index 03c1c152f9f..2a3c68a7b89 100755 --- a/mozilla/xpcom/string/public/nsAlgorithm.h +++ b/mozilla/xpcom/string/public/nsAlgorithm.h @@ -17,10 +17,9 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsAlgorithm_h___ @@ -50,7 +49,7 @@ NS_MAX( const T& a, const T& b ) template inline PRUint32 -NS_COUNT( InputIterator first, InputIterator last, const T& value ) +NS_COUNT( InputIterator& first, const InputIterator& last, const T& value ) { PRUint32 result = 0; for ( ; first != last; ++first ) @@ -61,8 +60,8 @@ NS_COUNT( InputIterator first, InputIterator last, const T& value ) template inline -OutputIterator -copy_string( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result ) { typedef nsCharSourceTraits source_traits; typedef nsCharSinkTraits sink_traits; @@ -71,15 +70,15 @@ copy_string( InputIterator first, InputIterator last, OutputIterator result ) { PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last))); NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate"); - first += count_copied; + source_traits::advance(first, count_copied); } return result; } template -OutputIterator -copy_string_backward( InputIterator first, InputIterator last, OutputIterator result ) +OutputIterator& +copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result ) { while ( first != last ) { @@ -98,8 +97,8 @@ copy_string_backward( InputIterator first, InputIterator last, OutputIterator re nsCharTraits::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy); #endif - last -= PRInt32(lengthToCopy); - result -= PRInt32(lengthToCopy); + last.advance( -PRInt32(lengthToCopy) ); + result.advance( -PRInt32(lengthToCopy) ); } return result; diff --git a/mozilla/xpcom/string/public/nsCharTraits.h b/mozilla/xpcom/string/public/nsCharTraits.h index ec9c110688a..ca1c5c7f419 100644 --- a/mozilla/xpcom/string/public/nsCharTraits.h +++ b/mozilla/xpcom/string/public/nsCharTraits.h @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #ifndef nsCharTraits_h___ @@ -466,6 +464,8 @@ struct nsCharTraits template struct nsCharSourceTraits { + typedef typename InputIterator::difference_type difference_type; + #if 0 static PRUint32 @@ -495,6 +495,13 @@ struct nsCharSourceTraits { return iter.get(); } + + static + void + advance( InputIterator& s, difference_type n ) + { + s.advance(n); + } }; #ifdef HAVE_CPP_PARTIAL_SPECIALIZATION @@ -502,6 +509,8 @@ struct nsCharSourceTraits template struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -532,6 +541,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; #else @@ -539,6 +555,8 @@ struct nsCharSourceTraits NS_SPECIALIZE_TEMPLATE struct nsCharSourceTraits { + typedef ptrdiff_t difference_type; + #if 0 static PRUint32 @@ -569,6 +587,13 @@ struct nsCharSourceTraits { return s; } + + static + void + advance( CharT*& s, difference_type n ) + { + s += n; + } }; // Add specialization for |PRUnichar| only if it is needed diff --git a/mozilla/xpcom/string/public/nsFragmentedString.h b/mozilla/xpcom/string/public/nsFragmentedString.h index e1e6fe383dd..2b0891d88cf 100644 --- a/mozilla/xpcom/string/public/nsFragmentedString.h +++ b/mozilla/xpcom/string/public/nsFragmentedString.h @@ -17,10 +17,9 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) + * */ #ifndef nsFragmentedString_h___ @@ -89,7 +88,10 @@ nsChunkList::NewChunk( const CharT* aData, PRUint32 aDataLength, PRUint32 typedef CharT* CharT_ptr; CharT* buffer_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); if ( aDataLength ) - copy_string(aData, aData+aDataLength, buffer_ptr); + { + CharT* toBegin = buffer_ptr; + copy_string(aData, aData+aDataLength, toBegin); + } return new (object_ptr) Chunk(buffer_ptr, buffer_length, aDataLength); } diff --git a/mozilla/xpcom/string/public/nsSharedString.h b/mozilla/xpcom/string/public/nsSharedString.h index 80f2c133356..b94fd4a02b0 100644 --- a/mozilla/xpcom/string/public/nsSharedString.h +++ b/mozilla/xpcom/string/public/nsSharedString.h @@ -182,7 +182,10 @@ new_nsSharedString( const basic_nsAReadableString& aReadable ) { typedef CharT* CharT_ptr; CharT* string_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), string_ptr); + + nsReadingIterator fromBegin, fromEnd; + CharT* toBegin = string_ptr; + copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); return new (object_ptr) basic_nsSharedString(string_ptr, string_length); } diff --git a/mozilla/xpcom/string/src/nsReadableUtils.cpp b/mozilla/xpcom/string/src/nsReadableUtils.cpp index 07bbaf8b8fa..405a011d6e0 100755 --- a/mozilla/xpcom/string/src/nsReadableUtils.cpp +++ b/mozilla/xpcom/string/src/nsReadableUtils.cpp @@ -17,10 +17,8 @@ * Copyright (C) 2000 Netscape Communications Corporation. All * Rights Reserved. * - * Original Author: - * Scott Collins - * * Contributor(s): + * Scott Collins (original author) */ #include "nsReadableUtils.h" @@ -72,7 +70,10 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } NS_COM @@ -81,7 +82,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(aDest.BeginWriting().get())); + + nsReadingIterator fromBegin, fromEnd; + nsWritingIterator toBegin; + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), LossyConvertEncoding(aDest.BeginWriting(toBegin).get())); } @@ -106,7 +110,10 @@ char* ToNewCString( const nsAReadableString& aSource ) { char* result = AllocateStringCopy(aSource, (char*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } @@ -141,7 +148,10 @@ ToNewCString( const nsAReadableCString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it char* result = AllocateStringCopy(aSource, (char*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = char(0); + + nsReadingIterator fromBegin, fromEnd; + char* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = char(0); return result; } @@ -152,7 +162,10 @@ ToNewUnicode( const nsAReadableString& aSource ) // no conversion needed, just allocate a buffer of the correct length and copy into it PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - *copy_string(aSource.BeginReading(), aSource.EndReading(), result) = PRUnichar(0); + + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = result; + *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = PRUnichar(0); return result; } @@ -161,22 +174,20 @@ PRUnichar* ToNewUnicode( const nsAReadableCString& aSource ) { PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - copy_string(aSource.BeginReading(), aSource.EndReading(), LossyConvertEncoding(result)).write_terminator(); + + nsReadingIterator fromBegin, fromEnd; + LossyConvertEncoding converter(result); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); return result; } NS_COM PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, - PRUnichar* aDest, - PRUint32 aLength ) +CopyUnicodeTo( const nsAReadableString& aSource, PRUnichar* aDest, PRUint32 aLength ) { - typedef nsAReadableString::const_iterator iterator; - - iterator done_reading = aSource.BeginReading(); - done_reading += aLength; - - copy_string(aSource.BeginReading(), done_reading, aDest); + nsReadingIterator fromBegin, fromEnd; + PRUnichar* toBegin = aDest; + copy_string(aSource.BeginReading(fromBegin), aSource.BeginReading(fromEnd).advance( PRInt32(aLength) ), toBegin); return aDest; } @@ -189,23 +200,22 @@ IsASCII( const nsAReadableString& aString ) // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character - typedef nsAReadableString::const_iterator iterator; - iterator iter = aString.BeginReading(); - iterator done_reading = aString.EndReading(); + nsReadingIterator done_reading; + aString.EndReading(done_reading); // for each chunk of |aString|... - while ( iter != done_reading ) + PRUint32 fragmentLength = 0; + nsReadingIterator iter; + for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) ) { - iterator::difference_type chunk_size = iter.size_forward(); + fragmentLength = iter.size_forward(); const PRUnichar* c = iter.get(); - const PRUnichar* chunk_end = c + chunk_size; + const PRUnichar* fragmentEnd = c + fragmentLength; // for each character in this chunk... - while ( c < chunk_end ) + while ( c < fragmentEnd ) if ( *c++ & NOT_ASCII ) return PR_FALSE; - - iter += chunk_size; } return PR_TRUE;