bug #75164: sr={brendan, sfraser}. Adding the generators |nsSubstituteC?String|, which will replace |ReplaceSubstring|. Also fixing a declaration in "nsAStringGenerator.h".

git-svn-id: svn://10.0.0.236/trunk@95820 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
scc%mozilla.org
2001-05-23 06:49:51 +00:00
parent d442d78367
commit 73c3c7385c
6 changed files with 492 additions and 2 deletions

View File

@@ -600,7 +600,179 @@ RFindInReadable( const nsACString& aPattern, nsReadingIterator<char>& aSearchSta
return found_it;
}
PRBool
nsSubstituteString::IsDependentOn( const nsAString& aString ) const
{
return mText.IsDependentOn(aString) || mPattern.IsDependentOn(aString) || mReplacement.IsDependentOn(aString);
}
PRUint32
nsSubstituteString::MaxLength() const
{
PRInt32 numberOfMatches = mNumberOfMatches;
// if we don't know exactly how long the result will be,
// calculate the longest possible result
if ( numberOfMatches < 0 )
{
if ( mReplacement.Length() <= mPattern.Length() )
numberOfMatches = 0; // substitutions shrink the result, so worst case is none
else
numberOfMatches = PRInt32(mText.Length() / mPattern.Length());
// substitutions grow the result, so worst case is the maximum number of times |mPattern| can be found
}
PRInt32 costPerMatch = PRInt32(mReplacement.Length()) - PRInt32(mPattern.Length());
return mText.Length() + (numberOfMatches * costPerMatch);
}
void
nsSubstituteString::CountMatches() const
{
nsReadingIterator<PRUnichar> textEnd;
nsReadingIterator<PRUnichar> searchEnd = mText.EndReading(textEnd);
nsReadingIterator<PRUnichar> searchStart;
mText.BeginReading(searchStart);
PRInt32 numberOfMatches = 0;
while ( FindInReadable(mPattern, searchStart, searchEnd) )
{
++numberOfMatches;
searchStart = searchEnd;
searchEnd = textEnd;
}
NS_CONST_CAST(nsSubstituteString*, this)->mNumberOfMatches = numberOfMatches;
}
PRUint32
nsSubstituteString::Length() const
{
if ( mNumberOfMatches < 0 )
CountMatches();
return MaxLength();
}
PRUnichar*
nsSubstituteString::operator()( PRUnichar* aDestBuffer ) const
{
nsReadingIterator<PRUnichar> replacementEnd;
mReplacement.EndReading(replacementEnd);
nsReadingIterator<PRUnichar> textEnd;
nsReadingIterator<PRUnichar> searchEnd = mText.EndReading(textEnd);
nsReadingIterator<PRUnichar> uncopiedStart;
nsReadingIterator<PRUnichar> searchStart = mText.BeginReading(uncopiedStart);
while ( FindInReadable(mPattern, searchStart, searchEnd) )
{
// |searchStart| and |searchEnd| now bracket the match
// copy everything up to this match
copy_string(uncopiedStart, searchStart, aDestBuffer); // updates |aDestBuffer|
// copy the replacement
nsReadingIterator<PRUnichar> replacementStart;
copy_string(mReplacement.BeginReading(replacementStart), replacementEnd, aDestBuffer);
// start searching from where the current match ends
uncopiedStart = searchStart = searchEnd;
searchEnd = textEnd;
}
// copy everything after the final (if any) match
copy_string(uncopiedStart, textEnd, aDestBuffer);
return aDestBuffer;
}
PRBool
nsSubstituteCString::IsDependentOn( const nsACString& aString ) const
{
return mText.IsDependentOn(aString) || mPattern.IsDependentOn(aString) || mReplacement.IsDependentOn(aString);
}
PRUint32
nsSubstituteCString::MaxLength() const
{
PRInt32 numberOfMatches = mNumberOfMatches;
// if we don't know exactly how long the result will be,
// calculate the longest possible result
if ( numberOfMatches < 0 )
{
if ( mReplacement.Length() <= mPattern.Length() )
numberOfMatches = 0; // substitutions shrink the result, so worst case is none
else
numberOfMatches = PRInt32(mText.Length() / mPattern.Length());
// substitutions grow the result, so worst case is the maximum number of times |mPattern| can be found
}
PRInt32 costPerMatch = PRInt32(mReplacement.Length()) - PRInt32(mPattern.Length());
return mText.Length() + (numberOfMatches * costPerMatch);
}
void
nsSubstituteCString::CountMatches() const
{
nsReadingIterator<char> textEnd;
nsReadingIterator<char> searchEnd = mText.EndReading(textEnd);
nsReadingIterator<char> searchStart;
mText.BeginReading(searchStart);
PRInt32 numberOfMatches = 0;
while ( FindInReadable(mPattern, searchStart, searchEnd) )
{
++numberOfMatches;
searchStart = searchEnd;
searchEnd = textEnd;
}
NS_CONST_CAST(nsSubstituteCString*, this)->mNumberOfMatches = numberOfMatches;
}
PRUint32
nsSubstituteCString::Length() const
{
if ( mNumberOfMatches < 0 )
CountMatches();
return MaxLength();
}
char*
nsSubstituteCString::operator()( char* aDestBuffer ) const
{
nsReadingIterator<char> replacementEnd;
mReplacement.EndReading(replacementEnd);
nsReadingIterator<char> textEnd;
nsReadingIterator<char> searchEnd = mText.EndReading(textEnd);
nsReadingIterator<char> uncopiedStart;
nsReadingIterator<char> searchStart = mText.BeginReading(uncopiedStart);
while ( FindInReadable(mPattern, searchStart, searchEnd) )
{
// |searchStart| and |searchEnd| now bracket the match
// copy everything up to this match
copy_string(uncopiedStart, searchStart, aDestBuffer); // updates |aDestBuffer|
// copy the replacement
nsReadingIterator<char> replacementStart;
copy_string(mReplacement.BeginReading(replacementStart), replacementEnd, aDestBuffer);
// start searching from where the current match ends
uncopiedStart = searchStart = searchEnd;
searchEnd = textEnd;
}
// copy everything after the final (if any) match
copy_string(uncopiedStart, textEnd, aDestBuffer);
return aDestBuffer;
}
NS_COM
PRBool