From 7a4bbc26883ea84a3b9af9551fe024aa41e2b33d Mon Sep 17 00:00:00 2001 From: "scc%mozilla.org" Date: Wed, 9 Aug 2000 08:26:08 +0000 Subject: [PATCH] fixed |BeginWriting| and |EndWriting| to no longer take an offset, fallout from the new multi-fragment string implementation; fixed a bug in |operator-=| exposed by the change to |EndWriting|; fixed |nsWritingIterator::write| as per bug #46462; fixed comments galore, significantly better specifying |SetLength| and |SetCapacity|; since |SetCapacity| is just a hint, give it a default implementation rather than making it pure virtual; fixed a couple of the |do_...| routines to unify the code path minimizing overides; r|a=waterson --- string/public/nsAWritableString.h | 58 +++++++++++++++++-------- xpcom/ds/nsAWritableString.h | 58 +++++++++++++++++-------- xpcom/string/public/nsAWritableString.h | 58 +++++++++++++++++-------- 3 files changed, 117 insertions(+), 57 deletions(-) diff --git a/string/public/nsAWritableString.h b/string/public/nsAWritableString.h index 73252a9bc3e1..caa12751a5fb 100644 --- a/string/public/nsAWritableString.h +++ b/string/public/nsAWritableString.h @@ -183,10 +183,10 @@ class nsWritingIterator 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; - normalize_backward(); n -= one_hop; } @@ -199,7 +199,7 @@ class nsWritingIterator NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!"); n = NS_MIN(n, PRUint32(size_forward())); - nsCharTraits::copy(mPosition, s, n); + nsCharTraits::move(mPosition, s, n); operator+=( difference_type(n) ); return n; } @@ -233,24 +233,43 @@ class basic_nsAWritableString nsWritingIterator - BeginWriting( PRUint32 aOffset = 0 ) + BeginWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); + CharT* startPos = GetWritableFragment(fragment, kFirstFragment); return nsWritingIterator(fragment, startPos, *this); } nsWritingIterator - EndWriting( PRUint32 aOffset = 0 ) + EndWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, this->Length()-aOffset)); - return nsWritingIterator(fragment, startPos, *this); + GetWritableFragment(fragment, kLastFragment); + return nsWritingIterator(fragment, fragment.mEnd, *this); } - virtual void SetCapacity( PRUint32 ) = 0; + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( PRUint32 ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ virtual void SetLength( PRUint32 ) = 0; @@ -316,6 +335,10 @@ class basic_nsAWritableString + /** + * The following index based routines need to be recast with iterators. + */ + // // |Insert()| // Note: I would really like to move the |atPosition| parameter to the front of the argument list @@ -548,7 +571,7 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(oldLength)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); } template @@ -569,10 +592,7 @@ template void basic_nsAWritableString::do_AppendFromElement( CharT aChar ) { - PRUint32 oldLength = this->Length(); - SetLength(oldLength+1); - nsWritableFragment fragment; - *GetWritableFragment(fragment, kFragmentAt, oldLength) = aChar; + do_AppendFromReadable(basic_nsLiteralChar(aChar)); } @@ -618,10 +638,10 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(atPosition), this->BeginReading(oldLength), EndWriting()); + copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(atPosition)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); } template @@ -659,7 +679,7 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; if ( cutEnd < myLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(cutStart)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); SetLength(myLength-cutLength); } @@ -715,12 +735,12 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; if ( cutLength > replacementLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(replacementEnd)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(cutEnd), this->BeginReading(oldLength), BeginWriting(replacementEnd)); + copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart)); + copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); } diff --git a/xpcom/ds/nsAWritableString.h b/xpcom/ds/nsAWritableString.h index 73252a9bc3e1..caa12751a5fb 100644 --- a/xpcom/ds/nsAWritableString.h +++ b/xpcom/ds/nsAWritableString.h @@ -183,10 +183,10 @@ class nsWritingIterator 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; - normalize_backward(); n -= one_hop; } @@ -199,7 +199,7 @@ class nsWritingIterator NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!"); n = NS_MIN(n, PRUint32(size_forward())); - nsCharTraits::copy(mPosition, s, n); + nsCharTraits::move(mPosition, s, n); operator+=( difference_type(n) ); return n; } @@ -233,24 +233,43 @@ class basic_nsAWritableString nsWritingIterator - BeginWriting( PRUint32 aOffset = 0 ) + BeginWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); + CharT* startPos = GetWritableFragment(fragment, kFirstFragment); return nsWritingIterator(fragment, startPos, *this); } nsWritingIterator - EndWriting( PRUint32 aOffset = 0 ) + EndWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, this->Length()-aOffset)); - return nsWritingIterator(fragment, startPos, *this); + GetWritableFragment(fragment, kLastFragment); + return nsWritingIterator(fragment, fragment.mEnd, *this); } - virtual void SetCapacity( PRUint32 ) = 0; + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( PRUint32 ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ virtual void SetLength( PRUint32 ) = 0; @@ -316,6 +335,10 @@ class basic_nsAWritableString + /** + * The following index based routines need to be recast with iterators. + */ + // // |Insert()| // Note: I would really like to move the |atPosition| parameter to the front of the argument list @@ -548,7 +571,7 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(oldLength)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); } template @@ -569,10 +592,7 @@ template void basic_nsAWritableString::do_AppendFromElement( CharT aChar ) { - PRUint32 oldLength = this->Length(); - SetLength(oldLength+1); - nsWritableFragment fragment; - *GetWritableFragment(fragment, kFragmentAt, oldLength) = aChar; + do_AppendFromReadable(basic_nsLiteralChar(aChar)); } @@ -618,10 +638,10 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(atPosition), this->BeginReading(oldLength), EndWriting()); + copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(atPosition)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); } template @@ -659,7 +679,7 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; if ( cutEnd < myLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(cutStart)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); SetLength(myLength-cutLength); } @@ -715,12 +735,12 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; if ( cutLength > replacementLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(replacementEnd)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(cutEnd), this->BeginReading(oldLength), BeginWriting(replacementEnd)); + copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart)); + copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); } diff --git a/xpcom/string/public/nsAWritableString.h b/xpcom/string/public/nsAWritableString.h index 73252a9bc3e1..caa12751a5fb 100644 --- a/xpcom/string/public/nsAWritableString.h +++ b/xpcom/string/public/nsAWritableString.h @@ -183,10 +183,10 @@ class nsWritingIterator 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; - normalize_backward(); n -= one_hop; } @@ -199,7 +199,7 @@ class nsWritingIterator NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!"); n = NS_MIN(n, PRUint32(size_forward())); - nsCharTraits::copy(mPosition, s, n); + nsCharTraits::move(mPosition, s, n); operator+=( difference_type(n) ); return n; } @@ -233,24 +233,43 @@ class basic_nsAWritableString nsWritingIterator - BeginWriting( PRUint32 aOffset = 0 ) + BeginWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset); + CharT* startPos = GetWritableFragment(fragment, kFirstFragment); return nsWritingIterator(fragment, startPos, *this); } nsWritingIterator - EndWriting( PRUint32 aOffset = 0 ) + EndWriting() { nsWritableFragment fragment; - CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, this->Length()-aOffset)); - return nsWritingIterator(fragment, startPos, *this); + GetWritableFragment(fragment, kLastFragment); + return nsWritingIterator(fragment, fragment.mEnd, *this); } - virtual void SetCapacity( PRUint32 ) = 0; + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( PRUint32 ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ virtual void SetLength( PRUint32 ) = 0; @@ -316,6 +335,10 @@ class basic_nsAWritableString + /** + * The following index based routines need to be recast with iterators. + */ + // // |Insert()| // Note: I would really like to move the |atPosition| parameter to the front of the argument list @@ -548,7 +571,7 @@ basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableSt { PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(oldLength)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=oldLength); } template @@ -569,10 +592,7 @@ template void basic_nsAWritableString::do_AppendFromElement( CharT aChar ) { - PRUint32 oldLength = this->Length(); - SetLength(oldLength+1); - nsWritableFragment fragment; - *GetWritableFragment(fragment, kFragmentAt, oldLength) = aChar; + do_AppendFromReadable(basic_nsLiteralChar(aChar)); } @@ -618,10 +638,10 @@ basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableSt PRUint32 oldLength = this->Length(); SetLength(oldLength + aReadable.Length()); if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(atPosition), this->BeginReading(oldLength), EndWriting()); + copy_string_backward(this->BeginReading()+=atPosition, this->BeginReading()+=oldLength, EndWriting()); else atPosition = oldLength; - copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(atPosition)); + copy_string(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting()+=atPosition); } template @@ -659,7 +679,7 @@ basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) cutLength = NS_MIN(cutLength, myLength-cutStart); PRUint32 cutEnd = cutStart + cutLength; if ( cutEnd < myLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(cutStart)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=cutStart); SetLength(myLength-cutLength); } @@ -715,12 +735,12 @@ basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUin PRUint32 newLength = oldLength - cutLength + replacementLength; if ( cutLength > replacementLength ) - copy_string(this->BeginReading(cutEnd), this->EndReading(), BeginWriting(replacementEnd)); + copy_string(this->BeginReading()+=cutEnd, this->EndReading(), BeginWriting()+=replacementEnd); SetLength(newLength); if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(cutEnd), this->BeginReading(oldLength), BeginWriting(replacementEnd)); + copy_string_backward(this->BeginReading()+=cutEnd, this->BeginReading()+=oldLength, BeginWriting()+=replacementEnd); - copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart)); + copy_string(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting()+=cutStart); }