traded in |copy_chunky_backward| for |string_copy_backward| and moved it to "nsAReadableString.h" along with the |string_copy|s. Added tests for |SetLength|, which would have caught the problem in |nsString| I fixed earlier, and one for |Insert| that exposed the trouble in |copy_chunky_backward|.

This commit is contained in:
scc%netscape.com 2000-03-27 09:06:37 +00:00
Родитель 94523c4948
Коммит 92b5b65386
7 изменённых файлов: 213 добавлений и 120 удалений

Просмотреть файл

@ -63,15 +63,6 @@ using namespace std;
'C') is a string of |char|s.
*/
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT> class basic_nsLiteralString;
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
template <class CharT>
@ -88,6 +79,12 @@ struct nsReadableFragment
}
};
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT>
class nsReadingIterator
: public bidirectional_iterator_tag
@ -267,11 +264,11 @@ class basic_nsAReadableString
int Compare( const basic_nsAReadableString<CharT>& rhs ) const;
int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// |Equals()| is a synonym for |Compare()|
PRBool Equals( const basic_nsAReadableString<CharT>& rhs ) const;
PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// Comparison operators are all synonyms for |Compare()|
PRBool operator!=( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)!=0; }
@ -381,6 +378,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsAReadableString<CharT>& rh
return Compare(rhs) == 0;
}
#if 0
template <class CharT>
inline
PRBool
@ -388,7 +386,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsLiteralString<CharT>& rhs
{
return Compare(rhs) == 0;
}
#endif
template <class CharT>
inline
@ -561,6 +559,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsAReadableString<CharT>& r
return ::Compare(*this, rhs);
}
#if 0
template <class CharT>
inline
int
@ -568,7 +567,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsLiteralString<CharT>& rhs
{
return ::Compare(*this, rhs);
}
#endif
@ -907,7 +906,7 @@ string_copy( InputIterator first, InputIterator last, OutputIterator result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<InputIterator::value_type>::copy(result.operator->(), first.operator->(), lengthToCopy);
@ -928,7 +927,7 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<CharT>::copy(result, first.operator->(), lengthToCopy);
@ -939,6 +938,27 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
return result;
}
template <class InputIterator, class OutputIterator>
OutputIterator
string_copy_backward( InputIterator first, InputIterator last, OutputIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
NS_ASSERTION(lengthToCopy, "|string_copy_backward| will never terminate");
nsCharTraits<InputIterator::value_type>::move(result.operator->()-lengthToCopy, last.operator->()-lengthToCopy, lengthToCopy);
last -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
inline
PRBool
@ -972,7 +992,6 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
for (;;)
{
PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;

Просмотреть файл

@ -335,28 +335,6 @@ operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>&
}
template <class CharT>
nsWritingIterator<CharT>
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
@ -389,7 +367,7 @@ basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aR
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
string_copy_backward(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
string_copy(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
@ -422,7 +400,7 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
string_copy(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy_backward(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}

Просмотреть файл

@ -63,15 +63,6 @@ using namespace std;
'C') is a string of |char|s.
*/
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT> class basic_nsLiteralString;
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
template <class CharT>
@ -88,6 +79,12 @@ struct nsReadableFragment
}
};
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT>
class nsReadingIterator
: public bidirectional_iterator_tag
@ -267,11 +264,11 @@ class basic_nsAReadableString
int Compare( const basic_nsAReadableString<CharT>& rhs ) const;
int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// |Equals()| is a synonym for |Compare()|
PRBool Equals( const basic_nsAReadableString<CharT>& rhs ) const;
PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// Comparison operators are all synonyms for |Compare()|
PRBool operator!=( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)!=0; }
@ -381,6 +378,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsAReadableString<CharT>& rh
return Compare(rhs) == 0;
}
#if 0
template <class CharT>
inline
PRBool
@ -388,7 +386,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsLiteralString<CharT>& rhs
{
return Compare(rhs) == 0;
}
#endif
template <class CharT>
inline
@ -561,6 +559,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsAReadableString<CharT>& r
return ::Compare(*this, rhs);
}
#if 0
template <class CharT>
inline
int
@ -568,7 +567,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsLiteralString<CharT>& rhs
{
return ::Compare(*this, rhs);
}
#endif
@ -907,7 +906,7 @@ string_copy( InputIterator first, InputIterator last, OutputIterator result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<InputIterator::value_type>::copy(result.operator->(), first.operator->(), lengthToCopy);
@ -928,7 +927,7 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<CharT>::copy(result, first.operator->(), lengthToCopy);
@ -939,6 +938,27 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
return result;
}
template <class InputIterator, class OutputIterator>
OutputIterator
string_copy_backward( InputIterator first, InputIterator last, OutputIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
NS_ASSERTION(lengthToCopy, "|string_copy_backward| will never terminate");
nsCharTraits<InputIterator::value_type>::move(result.operator->()-lengthToCopy, last.operator->()-lengthToCopy, lengthToCopy);
last -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
inline
PRBool
@ -972,7 +992,6 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
for (;;)
{
PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;

Просмотреть файл

@ -335,28 +335,6 @@ operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>&
}
template <class CharT>
nsWritingIterator<CharT>
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
@ -389,7 +367,7 @@ basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aR
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
string_copy_backward(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
string_copy(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
@ -422,7 +400,7 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
string_copy(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy_backward(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}

Просмотреть файл

@ -63,15 +63,6 @@ using namespace std;
'C') is a string of |char|s.
*/
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT> class basic_nsLiteralString;
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
template <class CharT>
@ -88,6 +79,12 @@ struct nsReadableFragment
}
};
template <class CharT> class basic_nsAReadableString;
template <class CharT> class basic_nsAWritableString;
// ...because we sometimes use them as `out' params
template <class CharT>
class nsReadingIterator
: public bidirectional_iterator_tag
@ -267,11 +264,11 @@ class basic_nsAReadableString
int Compare( const basic_nsAReadableString<CharT>& rhs ) const;
int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// int Compare( const basic_nsLiteralString<CharT>& rhs ) const;
// |Equals()| is a synonym for |Compare()|
PRBool Equals( const basic_nsAReadableString<CharT>& rhs ) const;
PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// PRBool Equals( const basic_nsLiteralString<CharT>& rhs ) const;
// Comparison operators are all synonyms for |Compare()|
PRBool operator!=( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)!=0; }
@ -381,6 +378,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsAReadableString<CharT>& rh
return Compare(rhs) == 0;
}
#if 0
template <class CharT>
inline
PRBool
@ -388,7 +386,7 @@ basic_nsAReadableString<CharT>::Equals( const basic_nsLiteralString<CharT>& rhs
{
return Compare(rhs) == 0;
}
#endif
template <class CharT>
inline
@ -561,6 +559,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsAReadableString<CharT>& r
return ::Compare(*this, rhs);
}
#if 0
template <class CharT>
inline
int
@ -568,7 +567,7 @@ basic_nsAReadableString<CharT>::Compare( const basic_nsLiteralString<CharT>& rhs
{
return ::Compare(*this, rhs);
}
#endif
@ -907,7 +906,7 @@ string_copy( InputIterator first, InputIterator last, OutputIterator result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<InputIterator::value_type>::copy(result.operator->(), first.operator->(), lengthToCopy);
@ -928,7 +927,7 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
NS_ASSERTION(lengthToCopy, "|string_copy| will never terminate");
nsCharTraits<CharT>::copy(result, first.operator->(), lengthToCopy);
@ -939,6 +938,27 @@ string_copy( InputIterator first, InputIterator last, CharT* result )
return result;
}
template <class InputIterator, class OutputIterator>
OutputIterator
string_copy_backward( InputIterator first, InputIterator last, OutputIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
NS_ASSERTION(lengthToCopy, "|string_copy_backward| will never terminate");
nsCharTraits<InputIterator::value_type>::move(result.operator->()-lengthToCopy, last.operator->()-lengthToCopy, lengthToCopy);
last -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
inline
PRBool
@ -972,7 +992,6 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
for (;;)
{
PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;

Просмотреть файл

@ -335,28 +335,6 @@ operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>&
}
template <class CharT>
nsWritingIterator<CharT>
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( NS_MIN(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = NS_MIN(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
}
return result;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
@ -389,7 +367,7 @@ basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aR
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
string_copy_backward(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
string_copy(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
@ -422,7 +400,7 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
string_copy(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy_backward(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
string_copy(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}

Просмотреть файл

@ -54,6 +54,30 @@ literal_hello( PRUnichar* )
#endif
}
template <class T>
struct string_class_traits
{
};
NS_SPECIALIZE_TEMPLATE
struct string_class_traits<PRUnichar>
{
typedef PRUnichar* pointer;
typedef nsString implementation_t;
static basic_nsLiteralString<PRUnichar> literal_hello() { return ::literal_hello(pointer()); }
};
NS_SPECIALIZE_TEMPLATE
struct string_class_traits<char>
{
typedef char* pointer;
typedef nsCString implementation_t;
static basic_nsLiteralString<char> literal_hello() { return ::literal_hello(pointer()); }
};
static
void
CallCMid( nsAWritableCString& aResult, const nsAReadableCString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy )
@ -194,6 +218,81 @@ test_readable_hello( const basic_nsAReadableString<CharT>& aReadable )
}
template <class CharT>
int
test_SetLength( basic_nsAWritableString<CharT>& aWritable )
{
int tests_failed = 0;
string_class_traits<CharT>::implementation_t oldValue(aWritable);
size_t oldLength = aWritable.Length();
if ( oldValue != Substring(aWritable, 0, oldLength) )
{
cout << "FAILED growing a string in |test_SetLength|, saving the value didn't work." << endl;
++tests_failed;
}
size_t newLength = 2*(oldLength+1);
aWritable.SetLength(newLength);
if ( aWritable.Length() != newLength )
{
cout << "FAILED growing a string in |test_SetLength|, length is wrong." << endl;
++tests_failed;
}
if ( oldValue != Substring(aWritable, 0, oldLength) )
{
cout << "FAILED growing a string in |test_SetLength|, contents damaged after growing." << endl;
++tests_failed;
}
aWritable.SetLength(oldLength);
if ( aWritable.Length() != oldLength )
{
cout << "FAILED shrinking a string in |test_SetLength|." << endl;
++tests_failed;
}
if ( oldValue != Substring(aWritable, 0, oldLength) )
{
cout << "FAILED growing a string in |test_SetLength|, contents damaged after shrinking." << endl;
++tests_failed;
}
return tests_failed;
}
template <class CharT>
int
test_insert( basic_nsAWritableString<CharT>& aWritable )
{
int tests_failed = 0;
string_class_traits<CharT>::implementation_t oldValue(aWritable);
if ( oldValue != aWritable )
{
cout << "FAILED saving the old string value in |test_insert|." << endl;
++tests_failed;
}
string_class_traits<CharT>::implementation_t insertable( string_class_traits<CharT>::literal_hello() );
insertable.SetLength(1);
aWritable.Insert(insertable, 0);
if ( aWritable != (insertable + oldValue) )
{
cout << "FAILED in |test_insert|." << endl;
++tests_failed;
}
aWritable = oldValue;
return tests_failed;
}
@ -218,6 +317,9 @@ test_writable( basic_nsAWritableString<CharT>& aWritable )
tests_failed += test_readable_hello(aWritable);
}
tests_failed += test_SetLength(aWritable);
tests_failed += test_insert(aWritable);
return tests_failed;
}