diff --git a/string/public/nsAReadableString.h b/string/public/nsAReadableString.h index f9c343bc8af7..7c4a27857ba5 100644 --- a/string/public/nsAReadableString.h +++ b/string/public/nsAReadableString.h @@ -93,7 +93,7 @@ class basic_nsAReadableString const CharT* mEnd; const basic_nsAReadableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit ConstFragment( const basic_nsAReadableString* aOwner = 0 ) @@ -384,8 +384,29 @@ class nsPromiseConcatenation static const int kLeftString = 0; static const int kRightString = 1; + int + current_string( const ConstFragment& aFragment ) const + { + return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; + } + + int + use_left_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; + return kLeftString; + } + + int + use_right_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; + return kRightString; + } + public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) + : mFragmentIdentifierMask(aMask) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -393,9 +414,16 @@ class nsPromiseConcatenation virtual PRUint32 Length() const; + nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; + + private: + void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED + // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| + // which would break the algorithm for distributing bits in the fragment identifier + private: const basic_nsAReadableString* mStrings[2]; - mutable ConstFragment mFragment; + PRUint32 mFragmentIdentifierMask; }; NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) @@ -420,27 +448,26 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe { case kPrevFragment: case kNextFragment: - whichString = reinterpret_cast(aFragment.mFragmentIdentifier); + whichString = current_string(aFragment); break; case kFirstFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); break; case kLastFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); break; case kFragmentAt: PRUint32 leftLength = mStrings[kLeftString]->Length(); if ( aPosition < leftLength ) - whichString = kLeftString; + whichString = use_left_string(aFragment); else { - whichString = kRightString; + whichString = use_right_string(aFragment); aPosition -= leftLength; } - aFragment.mFragmentIdentifier = reinterpret_cast(whichString); break; } @@ -450,7 +477,7 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe do { done = true; - result = mStrings[whichString]->GetFragment(mFragment, aRequest, aPosition); + result = mStrings[whichString]->GetFragment(aFragment, aRequest, aPosition); if ( !result ) { @@ -458,24 +485,28 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe if ( aRequest == kNextFragment && whichString == kLeftString ) { aRequest = kFirstFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); } else if ( aRequest == kPrevFragment && whichString == kRightString ) { aRequest = kLastFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); } else done = true; } } while ( !done ); - - aFragment.mStart = mFragment.mStart; - aFragment.mEnd = mFragment.mEnd; return result; } +template +nsPromiseConcatenation +nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const + { + return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); + } + template class nsPromiseSubstring @@ -707,6 +738,9 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString< return nsPromiseConcatenation(lhs, rhs); } + + + template basic_ostream& operator<<( basic_ostream& os, const basic_nsAReadableString& s ) diff --git a/string/public/nsAWritableString.h b/string/public/nsAWritableString.h index 53657ad81ff7..e2a535e8bb0d 100644 --- a/string/public/nsAWritableString.h +++ b/string/public/nsAWritableString.h @@ -55,7 +55,7 @@ class basic_nsAWritableString CharT* mEnd; basic_nsAWritableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit Fragment( basic_nsAWritableString* aOwner = 0 ) diff --git a/xpcom/ds/nsAReadableString.h b/xpcom/ds/nsAReadableString.h index f9c343bc8af7..7c4a27857ba5 100644 --- a/xpcom/ds/nsAReadableString.h +++ b/xpcom/ds/nsAReadableString.h @@ -93,7 +93,7 @@ class basic_nsAReadableString const CharT* mEnd; const basic_nsAReadableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit ConstFragment( const basic_nsAReadableString* aOwner = 0 ) @@ -384,8 +384,29 @@ class nsPromiseConcatenation static const int kLeftString = 0; static const int kRightString = 1; + int + current_string( const ConstFragment& aFragment ) const + { + return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; + } + + int + use_left_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; + return kLeftString; + } + + int + use_right_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; + return kRightString; + } + public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) + : mFragmentIdentifierMask(aMask) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -393,9 +414,16 @@ class nsPromiseConcatenation virtual PRUint32 Length() const; + nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; + + private: + void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED + // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| + // which would break the algorithm for distributing bits in the fragment identifier + private: const basic_nsAReadableString* mStrings[2]; - mutable ConstFragment mFragment; + PRUint32 mFragmentIdentifierMask; }; NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) @@ -420,27 +448,26 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe { case kPrevFragment: case kNextFragment: - whichString = reinterpret_cast(aFragment.mFragmentIdentifier); + whichString = current_string(aFragment); break; case kFirstFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); break; case kLastFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); break; case kFragmentAt: PRUint32 leftLength = mStrings[kLeftString]->Length(); if ( aPosition < leftLength ) - whichString = kLeftString; + whichString = use_left_string(aFragment); else { - whichString = kRightString; + whichString = use_right_string(aFragment); aPosition -= leftLength; } - aFragment.mFragmentIdentifier = reinterpret_cast(whichString); break; } @@ -450,7 +477,7 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe do { done = true; - result = mStrings[whichString]->GetFragment(mFragment, aRequest, aPosition); + result = mStrings[whichString]->GetFragment(aFragment, aRequest, aPosition); if ( !result ) { @@ -458,24 +485,28 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe if ( aRequest == kNextFragment && whichString == kLeftString ) { aRequest = kFirstFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); } else if ( aRequest == kPrevFragment && whichString == kRightString ) { aRequest = kLastFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); } else done = true; } } while ( !done ); - - aFragment.mStart = mFragment.mStart; - aFragment.mEnd = mFragment.mEnd; return result; } +template +nsPromiseConcatenation +nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const + { + return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); + } + template class nsPromiseSubstring @@ -707,6 +738,9 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString< return nsPromiseConcatenation(lhs, rhs); } + + + template basic_ostream& operator<<( basic_ostream& os, const basic_nsAReadableString& s ) diff --git a/xpcom/ds/nsAWritableString.h b/xpcom/ds/nsAWritableString.h index 53657ad81ff7..e2a535e8bb0d 100644 --- a/xpcom/ds/nsAWritableString.h +++ b/xpcom/ds/nsAWritableString.h @@ -55,7 +55,7 @@ class basic_nsAWritableString CharT* mEnd; basic_nsAWritableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit Fragment( basic_nsAWritableString* aOwner = 0 ) diff --git a/xpcom/string/public/nsAReadableString.h b/xpcom/string/public/nsAReadableString.h index f9c343bc8af7..7c4a27857ba5 100644 --- a/xpcom/string/public/nsAReadableString.h +++ b/xpcom/string/public/nsAReadableString.h @@ -93,7 +93,7 @@ class basic_nsAReadableString const CharT* mEnd; const basic_nsAReadableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit ConstFragment( const basic_nsAReadableString* aOwner = 0 ) @@ -384,8 +384,29 @@ class nsPromiseConcatenation static const int kLeftString = 0; static const int kRightString = 1; + int + current_string( const ConstFragment& aFragment ) const + { + return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString; + } + + int + use_left_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask; + return kLeftString; + } + + int + use_right_string( ConstFragment& aFragment ) const + { + aFragment.mFragmentIdentifier |= mFragmentIdentifierMask; + return kRightString; + } + public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString ) + nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) + : mFragmentIdentifierMask(aMask) { mStrings[kLeftString] = &aLeftString; mStrings[kRightString] = &aRightString; @@ -393,9 +414,16 @@ class nsPromiseConcatenation virtual PRUint32 Length() const; + nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; + + private: + void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED + // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| + // which would break the algorithm for distributing bits in the fragment identifier + private: const basic_nsAReadableString* mStrings[2]; - mutable ConstFragment mFragment; + PRUint32 mFragmentIdentifierMask; }; NS_DEF_STRING_COMPARISONS(nsPromiseConcatenation) @@ -420,27 +448,26 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe { case kPrevFragment: case kNextFragment: - whichString = reinterpret_cast(aFragment.mFragmentIdentifier); + whichString = current_string(aFragment); break; case kFirstFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); break; case kLastFragment: - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); break; case kFragmentAt: PRUint32 leftLength = mStrings[kLeftString]->Length(); if ( aPosition < leftLength ) - whichString = kLeftString; + whichString = use_left_string(aFragment); else { - whichString = kRightString; + whichString = use_right_string(aFragment); aPosition -= leftLength; } - aFragment.mFragmentIdentifier = reinterpret_cast(whichString); break; } @@ -450,7 +477,7 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe do { done = true; - result = mStrings[whichString]->GetFragment(mFragment, aRequest, aPosition); + result = mStrings[whichString]->GetFragment(aFragment, aRequest, aPosition); if ( !result ) { @@ -458,24 +485,28 @@ nsPromiseConcatenation::GetFragment( ConstFragment& aFragment, FragmentRe if ( aRequest == kNextFragment && whichString == kLeftString ) { aRequest = kFirstFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kRightString); + whichString = use_right_string(aFragment); } else if ( aRequest == kPrevFragment && whichString == kRightString ) { aRequest = kLastFragment; - aFragment.mFragmentIdentifier = reinterpret_cast(whichString = kLeftString); + whichString = use_left_string(aFragment); } else done = true; } } while ( !done ); - - aFragment.mStart = mFragment.mStart; - aFragment.mEnd = mFragment.mEnd; return result; } +template +nsPromiseConcatenation +nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const + { + return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); + } + template class nsPromiseSubstring @@ -707,6 +738,9 @@ operator+( const basic_nsLiteralString& lhs, const basic_nsLiteralString< return nsPromiseConcatenation(lhs, rhs); } + + + template basic_ostream& operator<<( basic_ostream& os, const basic_nsAReadableString& s ) diff --git a/xpcom/string/public/nsAWritableString.h b/xpcom/string/public/nsAWritableString.h index 53657ad81ff7..e2a535e8bb0d 100644 --- a/xpcom/string/public/nsAWritableString.h +++ b/xpcom/string/public/nsAWritableString.h @@ -55,7 +55,7 @@ class basic_nsAWritableString CharT* mEnd; basic_nsAWritableString* mOwningString; - void* mFragmentIdentifier; + PRUint32 mFragmentIdentifier; explicit Fragment( basic_nsAWritableString* aOwner = 0 )