Added "nsCharTraits.h"; no longer relying on |std::char_traits|. Renamed some things so overloading wouldn't fight with overriding.

git-svn-id: svn://10.0.0.236/trunk@63876 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
scc%netscape.com
2000-03-23 21:15:01 +00:00
parent 1ef0f2b114
commit cfed15f5a1
21 changed files with 512 additions and 551 deletions

View File

@@ -126,7 +126,7 @@ nsCString::~nsCString() {
}
#ifdef NEW_STRING_APIS
const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -141,7 +141,7 @@ const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentReque
}
}
char* nsCString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -60,12 +60,12 @@ class NS_COM nsCString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ConstFragment ConstFragment;
typedef nsAWritableCString::Fragment Fragment;
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ReadableFragment ReadableFragment;
typedef nsAWritableCString::WritableFragment WritableFragment;
virtual const char* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsCString( const nsAReadableCString& );

View File

@@ -137,7 +137,7 @@ nsString::~nsString() {
}
#ifdef NEW_STRING_APIS
const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -152,7 +152,7 @@ const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentR
}
}
PRUnichar* nsString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -68,11 +68,11 @@ class NS_COM nsString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableString::FragmentRequest FragmentRequest;
typedef nsAReadableString::ConstFragment ConstFragment;
typedef nsAWritableString::Fragment Fragment;
typedef nsAReadableString::ReadableFragment ReadableFragment;
typedef nsAWritableString::WritableFragment WritableFragment;
virtual const PRUnichar* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsString( const nsAReadableString& );

View File

@@ -26,15 +26,20 @@
// WORK IN PROGRESS
#ifndef nscore_h___
#include "nscore.h"
// for |PRUnichar|
#endif
#include <string>
// for |char_traits|
#ifndef _nsCharTraits_h__
#include "nsCharTraits.h"
#endif
#include <iterator>
// for |bidirectional_iterator_tag|
#include <algorithm.h>
/*
This file defines the abstract interfaces |nsAReadableString| and
@@ -77,13 +82,13 @@ class basic_nsAReadableString
{
protected:
struct ConstFragment
struct ReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
PRUint32 mFragmentIdentifier;
ConstFragment()
ReadableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -96,12 +101,12 @@ class basic_nsAReadableString
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
// Damn! Had to make |GetConstFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
// Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
friend class ConstIterator;
class ConstIterator
: public std::bidirectional_iterator_tag
friend class ReadingIterator;
class ReadingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -113,15 +118,16 @@ class basic_nsAReadableString
private:
friend class basic_nsAReadableString<CharT>;
ConstFragment mFragment;
const CharT* mPosition;
ReadableFragment mFragment;
const CharT* mPosition;
const basic_nsAReadableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetConstFragment(mFragment, kNextFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -129,13 +135,13 @@ class basic_nsAReadableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetConstFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
ConstIterator( const ConstFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
ReadingIterator( const ReadableFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
: mFragment(aFragment),
mPosition(aStartingPosition),
mOwningString(&aOwningString)
@@ -144,8 +150,8 @@ class basic_nsAReadableString
}
public:
// ConstIterator( const ConstIterator& ); ...use default copy-constructor
// ConstIterator& operator=( const ConstIterator& ); ...use default copy-assignment operator
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
CharT
@@ -160,7 +166,7 @@ class basic_nsAReadableString
return mPosition;
}
ConstIterator&
ReadingIterator&
operator++()
{
++mPosition;
@@ -168,16 +174,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator++( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
ConstIterator&
ReadingIterator&
operator--()
{
normalize_backward();
@@ -185,16 +191,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator--( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const ConstFragment&
const ReadableFragment&
fragment() const
{
return mFragment;
@@ -212,7 +218,7 @@ class basic_nsAReadableString
return mPosition - mFragment.mStart;
}
ConstIterator&
ReadingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -220,7 +226,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -229,7 +235,7 @@ class basic_nsAReadableString
return *this;
}
ConstIterator&
ReadingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -237,7 +243,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -250,39 +256,41 @@ class basic_nsAReadableString
// Damn again! Problems with templates made me implement comparisons as members.
PRBool
operator==( const ConstIterator& rhs ) const
operator==( const ReadingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const ConstIterator& rhs ) const
operator!=( const ReadingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef ReadingIterator ConstIterator;
public:
ConstIterator
Begin( PRUint32 aOffset = 0 ) const
ReadingIterator
BeginReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, aOffset);
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
return ReadingIterator(fragment, startPos, *this);
}
ConstIterator
End( PRUint32 aOffset = 0 ) const
ReadingIterator
EndReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ReadingIterator(fragment, startPos, *this);
}
public:
virtual ~basic_nsAReadableString<CharT>() { }
virtual ~basic_nsAReadableString() { }
// ...yes, I expect to be sub-classed.
virtual PRUint32 Length() const = 0;
@@ -445,8 +453,8 @@ const char*
basic_nsAReadableString<char>::GetBuffer() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -456,8 +464,8 @@ const PRUnichar*
basic_nsAReadableString<PRUnichar>::GetUnicode() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -472,7 +480,7 @@ basic_nsAReadableString<CharT>::Implementation() const
/*
Note: the following four functions, |CharAt|, |operator[]|, |First|, and |Last|, are implemented
in the simplest reasonable scheme; by calling |GetConstFragment| and resolving the pointer it
in the simplest reasonable scheme; by calling |GetReadableFragment| and resolving the pointer it
returns. The alternative is to force at least one of these methods to be |virtual|. The ideal
candidate for that change would be |CharAt|.
@@ -488,8 +496,8 @@ CharT
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
{
// ??? Is |CharAt()| supposed to be the 'safe' version?
ConstFragment fragment;
return *GetConstFragment(fragment, kFragmentAt, aIndex);
ReadableFragment fragment;
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
}
template <class CharT>
@@ -521,12 +529,12 @@ PRUint32
basic_nsAReadableString<CharT>::CountChar( CharT c ) const
{
#if 1
return PRUint32(count(Begin(), End(), c));
return PRUint32(count(BeginReading(), EndReading(), c));
#else
PRUint32 result = 0;
PRUint32 lengthToExamine = Length();
ConstIterator iter( Begin() );
ReadingIterator iter( BeginReading() );
for (;;)
{
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
@@ -567,7 +575,7 @@ PRUint32
basic_nsAReadableString<CharT>::Right( basic_nsAWritableString<CharT>& aResult, PRUint32 aLengthToCopy ) const
{
PRUint32 myLength = Length();
aLengthToCopy = std::min(myLength, aLengthToCopy);
aLengthToCopy = min(myLength, aLengthToCopy);
aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy);
return aResult.Length();
}
@@ -621,17 +629,17 @@ class basic_nsLiteralString
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
// Note: _not_ explicit
basic_nsLiteralString( const CharT* aLiteral )
: mStart(aLiteral),
mEnd(mStart + char_traits<CharT>::length(mStart))
mEnd(mStart + nsCharTraits<CharT>::length(mStart))
{
// nothing else to do here
}
@@ -654,7 +662,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
template <class CharT>
const CharT*
basic_nsLiteralString<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
@@ -697,7 +705,7 @@ class nsPromiseConcatenation
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetConstFragment()|.
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
@@ -708,32 +716,32 @@ class nsPromiseConcatenation
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetConstFragment()|.
|GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const ConstFragment& aFragment ) const
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
{
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( ConstFragment& aFragment ) const
SetLeftStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
return kLeftString;
}
int
SetRightStringInFragment( ConstFragment& aFragment ) const
SetRightStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
return kRightString;
@@ -772,14 +780,14 @@ nsPromiseConcatenation<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
const int kLeftString = 0;
const int kRightString = 1;
int whichString;
// based on the request, pick which string we will forward the |GetConstFragment()| call into
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
@@ -814,7 +822,7 @@ nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, Fragm
do
{
done = true;
result = mStrings[whichString]->GetConstFragment(aFragment, aRequest, aPosition);
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
@@ -862,20 +870,20 @@ class nsPromiseSubstring
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetConstFragment()|.
calls to |GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( std::min(aStartPos, aString.Length()) ),
mLength( std::min(aLength, aString.Length()-mStartPos) )
mStartPos( min(aStartPos, aString.Length()) ),
mLength( min(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
@@ -899,7 +907,7 @@ nsPromiseSubstring<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
@@ -917,7 +925,7 @@ nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentR
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
return mString.GetConstFragment(aFragment, aRequest, aPosition);
return mString.GetReadableFragment(aFragment, aRequest, aPosition);
}
@@ -945,20 +953,20 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
PRUint32 lLength = lhs.Length();
PRUint32 rLength = rhs.Length();
PRUint32 lengthToCompare = std::min(lLength, rLength);
PRUint32 lengthToCompare = min(lLength, rLength);
basic_nsAReadableString<CharT>::ConstIterator leftIter( lhs.Begin() );
basic_nsAReadableString<CharT>::ConstIterator rightIter( rhs.Begin() );
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
for (;;)
{
PRUint32 lengthAvailable = PRUint32( std::min(leftIter.size_forward(), rightIter.size_forward()) );
PRUint32 lengthAvailable = PRUint32( min(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;
if ( int result = std::char_traits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
if ( int result = nsCharTraits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
return result;
if ( !(lengthToCompare -= lengthAvailable) )
@@ -1046,10 +1054,10 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<
#ifdef SCC_TESTS
template <class CharT, class TraitsT>
std::basic_ostream<CharT, class TraitsT>&
basic_ostream<CharT, TraitsT>&
operator<<( basic_ostream<CharT, TraitsT>& os, const basic_nsAReadableString<CharT>& s )
{
std::copy(s.Begin(), s.End(), ostream_iterator<CharT, CharT, TraitsT>(os));
copy(s.BeginReading(), s.EndReading(), ostream_iterator<CharT, CharT, TraitsT>(os));
return os;
}
#endif

View File

@@ -48,13 +48,13 @@ class basic_nsAWritableString
protected:
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
struct Fragment
struct WritableFragment
{
CharT* mStart;
CharT* mEnd;
PRUint32 mFragmentIdentifier;
Fragment()
WritableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -62,11 +62,11 @@ class basic_nsAWritableString
};
public:
virtual CharT* GetFragment( Fragment&, FragmentRequest, PRUint32 = 0 ) = 0;
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
friend class Iterator;
class Iterator
: public std::bidirectional_iterator_tag
friend class WritingIterator;
class WritingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -78,15 +78,15 @@ class basic_nsAWritableString
private:
friend class basic_nsAWritableString<CharT>;
Fragment mFragment;
CharT* mPosition;
WritableFragment mFragment;
CharT* mPosition;
basic_nsAWritableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetFragment(mFragment, kNextFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -94,11 +94,11 @@ class basic_nsAWritableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
Iterator( Fragment& aFragment,
WritingIterator( WritableFragment& aFragment,
CharT* aStartingPosition,
basic_nsAWritableString<CharT>& aOwningString )
: mFragment(aFragment),
@@ -109,8 +109,8 @@ class basic_nsAWritableString
}
public:
// Iterator( const Iterator& ); ...use default copy-constructor
// Iterator& operator=( const Iterator& ); ...use default copy-assignment operator
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
reference
@@ -125,7 +125,7 @@ class basic_nsAWritableString
return mPosition;
}
Iterator&
WritingIterator&
operator++()
{
++mPosition;
@@ -133,16 +133,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator++( int )
{
Iterator result(*this);
WritingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
Iterator&
WritingIterator&
operator--()
{
normalize_backward();
@@ -150,16 +150,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator--( int )
{
Iterator result(*this);
WritingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const Fragment&
const WritableFragment&
fragment() const
{
return mFragment;
@@ -177,7 +177,7 @@ class basic_nsAWritableString
return mPosition - mFragment.mStart;
}
Iterator&
WritingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -185,7 +185,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -194,7 +194,7 @@ class basic_nsAWritableString
return *this;
}
Iterator&
WritingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -202,7 +202,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -212,52 +212,37 @@ class basic_nsAWritableString
}
PRBool
operator==( const Iterator& rhs ) const
operator==( const WritingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const Iterator& rhs ) const
operator!=( const WritingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef WritingIterator Iterator;
public:
#ifdef HAVE_CPP_USING
using basic_nsAReadableString<CharT>::Begin;
using basic_nsAReadableString<CharT>::End;
#else
basic_nsAReadableString<CharT>::ConstIterator
Begin( PRUint32 aOffset = 0 ) const
WritingIterator
BeginWriting( PRUint32 aOffset = 0 )
{
return basic_nsAReadableString<CharT>::Begin(aOffset);
}
basic_nsAReadableString<CharT>::ConstIterator
End( PRUint32 aOffset = 0 ) const
{
return basic_nsAReadableString<CharT>::End(aOffset);
}
#endif
Iterator
Begin( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, aOffset);
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
return WritingIterator(fragment, startPos, *this);
}
Iterator
End( PRUint32 aOffset = 0 )
WritingIterator
EndWriting( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return WritingIterator(fragment, startPos, *this);
}
@@ -339,20 +324,20 @@ class basic_nsAWritableString
NS_DEF_STRING_COMPARISONS(basic_nsAWritableString<CharT>)
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_forward(), result.size_forward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_forward(), result.size_forward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
std::char_traits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
first += PRInt32(lengthToCopy);
result += PRInt32(lengthToCopy);
@@ -362,18 +347,18 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
}
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_backward(), result.size_backward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
std::char_traits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
@@ -390,7 +375,7 @@ void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
{
SetLength(rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin());
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting());
}
template <class CharT>
@@ -399,7 +384,7 @@ basic_nsAWritableString<CharT>::Append( const basic_nsAReadableString<CharT>& rh
{
PRUint32 oldLength = Length();
SetLength(oldLength + rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin(oldLength));
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting(oldLength));
}
template <class CharT>
@@ -407,31 +392,27 @@ void
basic_nsAWritableString<CharT>::AppendChar( CharT aChar )
{
SetLength(Length()+1);
*End(1) = aChar;
*EndWriting(1) = aChar;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aReadable, PRUint32 aPosition )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(readable_t::Begin(aPosition), readable_t::Begin(oldLength), End());
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
copy_chunky<CharT>(aReadable.Begin(), aReadable.End(), Begin(aPosition));
copy_chunky<CharT>(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Cut( PRUint32 cutStart, PRUint32 cutLength )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
copy_chunky<CharT>(readable_t::Begin(cutStart+cutLength), readable_t::End(), Begin(cutStart));
copy_chunky<CharT>(BeginReading(cutStart+cutLength), EndReading(), BeginWriting(cutStart));
SetLength(Length()-cutLength);
}
@@ -450,21 +431,19 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
PRUint32 newLength = oldLength - cutLength + replacementLength;
typedef typename basic_nsAReadableString<CharT> readable_t;
if ( cutLength > replacementLength )
copy_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::End(), Begin(replacementEnd));
copy_chunky<CharT>(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::Begin(oldLength), Begin(replacementEnd));
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
copy_chunky<CharT>(aReplacement.Begin(), aReplacement.End(), Begin(cutStart));
copy_chunky<CharT>(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}
// operator>>
// getline (maybe)
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
#endif // !defined(_nsAWritableString_h__)

View File

@@ -26,15 +26,20 @@
// WORK IN PROGRESS
#ifndef nscore_h___
#include "nscore.h"
// for |PRUnichar|
#endif
#include <string>
// for |char_traits|
#ifndef _nsCharTraits_h__
#include "nsCharTraits.h"
#endif
#include <iterator>
// for |bidirectional_iterator_tag|
#include <algorithm.h>
/*
This file defines the abstract interfaces |nsAReadableString| and
@@ -77,13 +82,13 @@ class basic_nsAReadableString
{
protected:
struct ConstFragment
struct ReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
PRUint32 mFragmentIdentifier;
ConstFragment()
ReadableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -96,12 +101,12 @@ class basic_nsAReadableString
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
// Damn! Had to make |GetConstFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
// Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
friend class ConstIterator;
class ConstIterator
: public std::bidirectional_iterator_tag
friend class ReadingIterator;
class ReadingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -113,15 +118,16 @@ class basic_nsAReadableString
private:
friend class basic_nsAReadableString<CharT>;
ConstFragment mFragment;
const CharT* mPosition;
ReadableFragment mFragment;
const CharT* mPosition;
const basic_nsAReadableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetConstFragment(mFragment, kNextFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -129,13 +135,13 @@ class basic_nsAReadableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetConstFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
ConstIterator( const ConstFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
ReadingIterator( const ReadableFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
: mFragment(aFragment),
mPosition(aStartingPosition),
mOwningString(&aOwningString)
@@ -144,8 +150,8 @@ class basic_nsAReadableString
}
public:
// ConstIterator( const ConstIterator& ); ...use default copy-constructor
// ConstIterator& operator=( const ConstIterator& ); ...use default copy-assignment operator
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
CharT
@@ -160,7 +166,7 @@ class basic_nsAReadableString
return mPosition;
}
ConstIterator&
ReadingIterator&
operator++()
{
++mPosition;
@@ -168,16 +174,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator++( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
ConstIterator&
ReadingIterator&
operator--()
{
normalize_backward();
@@ -185,16 +191,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator--( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const ConstFragment&
const ReadableFragment&
fragment() const
{
return mFragment;
@@ -212,7 +218,7 @@ class basic_nsAReadableString
return mPosition - mFragment.mStart;
}
ConstIterator&
ReadingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -220,7 +226,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -229,7 +235,7 @@ class basic_nsAReadableString
return *this;
}
ConstIterator&
ReadingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -237,7 +243,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -250,39 +256,41 @@ class basic_nsAReadableString
// Damn again! Problems with templates made me implement comparisons as members.
PRBool
operator==( const ConstIterator& rhs ) const
operator==( const ReadingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const ConstIterator& rhs ) const
operator!=( const ReadingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef ReadingIterator ConstIterator;
public:
ConstIterator
Begin( PRUint32 aOffset = 0 ) const
ReadingIterator
BeginReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, aOffset);
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
return ReadingIterator(fragment, startPos, *this);
}
ConstIterator
End( PRUint32 aOffset = 0 ) const
ReadingIterator
EndReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ReadingIterator(fragment, startPos, *this);
}
public:
virtual ~basic_nsAReadableString<CharT>() { }
virtual ~basic_nsAReadableString() { }
// ...yes, I expect to be sub-classed.
virtual PRUint32 Length() const = 0;
@@ -445,8 +453,8 @@ const char*
basic_nsAReadableString<char>::GetBuffer() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -456,8 +464,8 @@ const PRUnichar*
basic_nsAReadableString<PRUnichar>::GetUnicode() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -472,7 +480,7 @@ basic_nsAReadableString<CharT>::Implementation() const
/*
Note: the following four functions, |CharAt|, |operator[]|, |First|, and |Last|, are implemented
in the simplest reasonable scheme; by calling |GetConstFragment| and resolving the pointer it
in the simplest reasonable scheme; by calling |GetReadableFragment| and resolving the pointer it
returns. The alternative is to force at least one of these methods to be |virtual|. The ideal
candidate for that change would be |CharAt|.
@@ -488,8 +496,8 @@ CharT
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
{
// ??? Is |CharAt()| supposed to be the 'safe' version?
ConstFragment fragment;
return *GetConstFragment(fragment, kFragmentAt, aIndex);
ReadableFragment fragment;
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
}
template <class CharT>
@@ -521,12 +529,12 @@ PRUint32
basic_nsAReadableString<CharT>::CountChar( CharT c ) const
{
#if 1
return PRUint32(count(Begin(), End(), c));
return PRUint32(count(BeginReading(), EndReading(), c));
#else
PRUint32 result = 0;
PRUint32 lengthToExamine = Length();
ConstIterator iter( Begin() );
ReadingIterator iter( BeginReading() );
for (;;)
{
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
@@ -567,7 +575,7 @@ PRUint32
basic_nsAReadableString<CharT>::Right( basic_nsAWritableString<CharT>& aResult, PRUint32 aLengthToCopy ) const
{
PRUint32 myLength = Length();
aLengthToCopy = std::min(myLength, aLengthToCopy);
aLengthToCopy = min(myLength, aLengthToCopy);
aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy);
return aResult.Length();
}
@@ -621,17 +629,17 @@ class basic_nsLiteralString
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
// Note: _not_ explicit
basic_nsLiteralString( const CharT* aLiteral )
: mStart(aLiteral),
mEnd(mStart + char_traits<CharT>::length(mStart))
mEnd(mStart + nsCharTraits<CharT>::length(mStart))
{
// nothing else to do here
}
@@ -654,7 +662,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
template <class CharT>
const CharT*
basic_nsLiteralString<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
@@ -697,7 +705,7 @@ class nsPromiseConcatenation
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetConstFragment()|.
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
@@ -708,32 +716,32 @@ class nsPromiseConcatenation
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetConstFragment()|.
|GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const ConstFragment& aFragment ) const
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
{
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( ConstFragment& aFragment ) const
SetLeftStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
return kLeftString;
}
int
SetRightStringInFragment( ConstFragment& aFragment ) const
SetRightStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
return kRightString;
@@ -772,14 +780,14 @@ nsPromiseConcatenation<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
const int kLeftString = 0;
const int kRightString = 1;
int whichString;
// based on the request, pick which string we will forward the |GetConstFragment()| call into
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
@@ -814,7 +822,7 @@ nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, Fragm
do
{
done = true;
result = mStrings[whichString]->GetConstFragment(aFragment, aRequest, aPosition);
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
@@ -862,20 +870,20 @@ class nsPromiseSubstring
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetConstFragment()|.
calls to |GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( std::min(aStartPos, aString.Length()) ),
mLength( std::min(aLength, aString.Length()-mStartPos) )
mStartPos( min(aStartPos, aString.Length()) ),
mLength( min(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
@@ -899,7 +907,7 @@ nsPromiseSubstring<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
@@ -917,7 +925,7 @@ nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentR
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
return mString.GetConstFragment(aFragment, aRequest, aPosition);
return mString.GetReadableFragment(aFragment, aRequest, aPosition);
}
@@ -945,20 +953,20 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
PRUint32 lLength = lhs.Length();
PRUint32 rLength = rhs.Length();
PRUint32 lengthToCompare = std::min(lLength, rLength);
PRUint32 lengthToCompare = min(lLength, rLength);
basic_nsAReadableString<CharT>::ConstIterator leftIter( lhs.Begin() );
basic_nsAReadableString<CharT>::ConstIterator rightIter( rhs.Begin() );
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
for (;;)
{
PRUint32 lengthAvailable = PRUint32( std::min(leftIter.size_forward(), rightIter.size_forward()) );
PRUint32 lengthAvailable = PRUint32( min(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;
if ( int result = std::char_traits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
if ( int result = nsCharTraits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
return result;
if ( !(lengthToCompare -= lengthAvailable) )
@@ -1046,10 +1054,10 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<
#ifdef SCC_TESTS
template <class CharT, class TraitsT>
std::basic_ostream<CharT, class TraitsT>&
basic_ostream<CharT, TraitsT>&
operator<<( basic_ostream<CharT, TraitsT>& os, const basic_nsAReadableString<CharT>& s )
{
std::copy(s.Begin(), s.End(), ostream_iterator<CharT, CharT, TraitsT>(os));
copy(s.BeginReading(), s.EndReading(), ostream_iterator<CharT, CharT, TraitsT>(os));
return os;
}
#endif

View File

@@ -48,13 +48,13 @@ class basic_nsAWritableString
protected:
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
struct Fragment
struct WritableFragment
{
CharT* mStart;
CharT* mEnd;
PRUint32 mFragmentIdentifier;
Fragment()
WritableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -62,11 +62,11 @@ class basic_nsAWritableString
};
public:
virtual CharT* GetFragment( Fragment&, FragmentRequest, PRUint32 = 0 ) = 0;
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
friend class Iterator;
class Iterator
: public std::bidirectional_iterator_tag
friend class WritingIterator;
class WritingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -78,15 +78,15 @@ class basic_nsAWritableString
private:
friend class basic_nsAWritableString<CharT>;
Fragment mFragment;
CharT* mPosition;
WritableFragment mFragment;
CharT* mPosition;
basic_nsAWritableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetFragment(mFragment, kNextFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -94,11 +94,11 @@ class basic_nsAWritableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
Iterator( Fragment& aFragment,
WritingIterator( WritableFragment& aFragment,
CharT* aStartingPosition,
basic_nsAWritableString<CharT>& aOwningString )
: mFragment(aFragment),
@@ -109,8 +109,8 @@ class basic_nsAWritableString
}
public:
// Iterator( const Iterator& ); ...use default copy-constructor
// Iterator& operator=( const Iterator& ); ...use default copy-assignment operator
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
reference
@@ -125,7 +125,7 @@ class basic_nsAWritableString
return mPosition;
}
Iterator&
WritingIterator&
operator++()
{
++mPosition;
@@ -133,16 +133,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator++( int )
{
Iterator result(*this);
WritingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
Iterator&
WritingIterator&
operator--()
{
normalize_backward();
@@ -150,16 +150,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator--( int )
{
Iterator result(*this);
WritingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const Fragment&
const WritableFragment&
fragment() const
{
return mFragment;
@@ -177,7 +177,7 @@ class basic_nsAWritableString
return mPosition - mFragment.mStart;
}
Iterator&
WritingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -185,7 +185,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -194,7 +194,7 @@ class basic_nsAWritableString
return *this;
}
Iterator&
WritingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -202,7 +202,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -212,52 +212,37 @@ class basic_nsAWritableString
}
PRBool
operator==( const Iterator& rhs ) const
operator==( const WritingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const Iterator& rhs ) const
operator!=( const WritingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef WritingIterator Iterator;
public:
#ifdef HAVE_CPP_USING
using basic_nsAReadableString<CharT>::Begin;
using basic_nsAReadableString<CharT>::End;
#else
basic_nsAReadableString<CharT>::ConstIterator
Begin( PRUint32 aOffset = 0 ) const
WritingIterator
BeginWriting( PRUint32 aOffset = 0 )
{
return basic_nsAReadableString<CharT>::Begin(aOffset);
}
basic_nsAReadableString<CharT>::ConstIterator
End( PRUint32 aOffset = 0 ) const
{
return basic_nsAReadableString<CharT>::End(aOffset);
}
#endif
Iterator
Begin( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, aOffset);
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
return WritingIterator(fragment, startPos, *this);
}
Iterator
End( PRUint32 aOffset = 0 )
WritingIterator
EndWriting( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return WritingIterator(fragment, startPos, *this);
}
@@ -339,20 +324,20 @@ class basic_nsAWritableString
NS_DEF_STRING_COMPARISONS(basic_nsAWritableString<CharT>)
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_forward(), result.size_forward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_forward(), result.size_forward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
std::char_traits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
first += PRInt32(lengthToCopy);
result += PRInt32(lengthToCopy);
@@ -362,18 +347,18 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
}
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_backward(), result.size_backward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
std::char_traits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
@@ -390,7 +375,7 @@ void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
{
SetLength(rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin());
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting());
}
template <class CharT>
@@ -399,7 +384,7 @@ basic_nsAWritableString<CharT>::Append( const basic_nsAReadableString<CharT>& rh
{
PRUint32 oldLength = Length();
SetLength(oldLength + rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin(oldLength));
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting(oldLength));
}
template <class CharT>
@@ -407,31 +392,27 @@ void
basic_nsAWritableString<CharT>::AppendChar( CharT aChar )
{
SetLength(Length()+1);
*End(1) = aChar;
*EndWriting(1) = aChar;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aReadable, PRUint32 aPosition )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(readable_t::Begin(aPosition), readable_t::Begin(oldLength), End());
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
copy_chunky<CharT>(aReadable.Begin(), aReadable.End(), Begin(aPosition));
copy_chunky<CharT>(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Cut( PRUint32 cutStart, PRUint32 cutLength )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
copy_chunky<CharT>(readable_t::Begin(cutStart+cutLength), readable_t::End(), Begin(cutStart));
copy_chunky<CharT>(BeginReading(cutStart+cutLength), EndReading(), BeginWriting(cutStart));
SetLength(Length()-cutLength);
}
@@ -450,21 +431,19 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
PRUint32 newLength = oldLength - cutLength + replacementLength;
typedef typename basic_nsAReadableString<CharT> readable_t;
if ( cutLength > replacementLength )
copy_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::End(), Begin(replacementEnd));
copy_chunky<CharT>(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::Begin(oldLength), Begin(replacementEnd));
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
copy_chunky<CharT>(aReplacement.Begin(), aReplacement.End(), Begin(cutStart));
copy_chunky<CharT>(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}
// operator>>
// getline (maybe)
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
#endif // !defined(_nsAWritableString_h__)

View File

@@ -126,7 +126,7 @@ nsCString::~nsCString() {
}
#ifdef NEW_STRING_APIS
const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -141,7 +141,7 @@ const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentReque
}
}
char* nsCString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -60,12 +60,12 @@ class NS_COM nsCString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ConstFragment ConstFragment;
typedef nsAWritableCString::Fragment Fragment;
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ReadableFragment ReadableFragment;
typedef nsAWritableCString::WritableFragment WritableFragment;
virtual const char* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsCString( const nsAReadableCString& );

View File

@@ -137,7 +137,7 @@ nsString::~nsString() {
}
#ifdef NEW_STRING_APIS
const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -152,7 +152,7 @@ const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentR
}
}
PRUnichar* nsString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -68,11 +68,11 @@ class NS_COM nsString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableString::FragmentRequest FragmentRequest;
typedef nsAReadableString::ConstFragment ConstFragment;
typedef nsAWritableString::Fragment Fragment;
typedef nsAReadableString::ReadableFragment ReadableFragment;
typedef nsAWritableString::WritableFragment WritableFragment;
virtual const PRUnichar* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsString( const nsAReadableString& );

View File

@@ -126,7 +126,7 @@ nsCString::~nsCString() {
}
#ifdef NEW_STRING_APIS
const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -141,7 +141,7 @@ const char* nsCString::GetConstFragment( ConstFragment& aFragment, FragmentReque
}
}
char* nsCString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -60,12 +60,12 @@ class NS_COM nsCString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ConstFragment ConstFragment;
typedef nsAWritableCString::Fragment Fragment;
typedef nsAReadableCString::FragmentRequest FragmentRequest;
typedef nsAReadableCString::ReadableFragment ReadableFragment;
typedef nsAWritableCString::WritableFragment WritableFragment;
virtual const char* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsCString( const nsAReadableCString& );

View File

@@ -137,7 +137,7 @@ nsString::~nsString() {
}
#ifdef NEW_STRING_APIS
const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:
@@ -152,7 +152,7 @@ const PRUnichar* nsString::GetConstFragment( ConstFragment& aFragment, FragmentR
}
}
PRUnichar* nsString::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
switch ( aRequest ) {
case kFirstFragment:
case kLastFragment:

View File

@@ -68,11 +68,11 @@ class NS_COM nsString :
#ifdef NEW_STRING_APIS
protected:
typedef nsAReadableString::FragmentRequest FragmentRequest;
typedef nsAReadableString::ConstFragment ConstFragment;
typedef nsAWritableString::Fragment Fragment;
typedef nsAReadableString::ReadableFragment ReadableFragment;
typedef nsAWritableString::WritableFragment WritableFragment;
virtual const PRUnichar* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
nsString( const nsAReadableString& );

View File

@@ -26,15 +26,20 @@
// WORK IN PROGRESS
#ifndef nscore_h___
#include "nscore.h"
// for |PRUnichar|
#endif
#include <string>
// for |char_traits|
#ifndef _nsCharTraits_h__
#include "nsCharTraits.h"
#endif
#include <iterator>
// for |bidirectional_iterator_tag|
#include <algorithm.h>
/*
This file defines the abstract interfaces |nsAReadableString| and
@@ -77,13 +82,13 @@ class basic_nsAReadableString
{
protected:
struct ConstFragment
struct ReadableFragment
{
const CharT* mStart;
const CharT* mEnd;
PRUint32 mFragmentIdentifier;
ConstFragment()
ReadableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -96,12 +101,12 @@ class basic_nsAReadableString
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
// Damn! Had to make |GetConstFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
// Damn! Had to make |GetReadableFragment| public because the compilers suck. Should be protected.
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 = 0 ) const = 0;
friend class ConstIterator;
class ConstIterator
: public std::bidirectional_iterator_tag
friend class ReadingIterator;
class ReadingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -113,15 +118,16 @@ class basic_nsAReadableString
private:
friend class basic_nsAReadableString<CharT>;
ConstFragment mFragment;
const CharT* mPosition;
ReadableFragment mFragment;
const CharT* mPosition;
const basic_nsAReadableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetConstFragment(mFragment, kNextFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -129,13 +135,13 @@ class basic_nsAReadableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetConstFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
ConstIterator( const ConstFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
ReadingIterator( const ReadableFragment& aFragment,
const CharT* aStartingPosition,
const basic_nsAReadableString<CharT>& aOwningString )
: mFragment(aFragment),
mPosition(aStartingPosition),
mOwningString(&aOwningString)
@@ -144,8 +150,8 @@ class basic_nsAReadableString
}
public:
// ConstIterator( const ConstIterator& ); ...use default copy-constructor
// ConstIterator& operator=( const ConstIterator& ); ...use default copy-assignment operator
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
CharT
@@ -160,7 +166,7 @@ class basic_nsAReadableString
return mPosition;
}
ConstIterator&
ReadingIterator&
operator++()
{
++mPosition;
@@ -168,16 +174,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator++( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
ConstIterator&
ReadingIterator&
operator--()
{
normalize_backward();
@@ -185,16 +191,16 @@ class basic_nsAReadableString
return *this;
}
ConstIterator
ReadingIterator
operator--( int )
{
ConstIterator result(*this);
ReadingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const ConstFragment&
const ReadableFragment&
fragment() const
{
return mFragment;
@@ -212,7 +218,7 @@ class basic_nsAReadableString
return mPosition - mFragment.mStart;
}
ConstIterator&
ReadingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -220,7 +226,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -229,7 +235,7 @@ class basic_nsAReadableString
return *this;
}
ConstIterator&
ReadingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -237,7 +243,7 @@ class basic_nsAReadableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -250,39 +256,41 @@ class basic_nsAReadableString
// Damn again! Problems with templates made me implement comparisons as members.
PRBool
operator==( const ConstIterator& rhs ) const
operator==( const ReadingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const ConstIterator& rhs ) const
operator!=( const ReadingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef ReadingIterator ConstIterator;
public:
ConstIterator
Begin( PRUint32 aOffset = 0 ) const
ReadingIterator
BeginReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, aOffset);
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
return ReadingIterator(fragment, startPos, *this);
}
ConstIterator
End( PRUint32 aOffset = 0 ) const
ReadingIterator
EndReading( PRUint32 aOffset = 0 ) const
{
ConstFragment fragment;
const CharT* startPos = GetConstFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ConstIterator(fragment, startPos, *this);
ReadableFragment fragment;
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return ReadingIterator(fragment, startPos, *this);
}
public:
virtual ~basic_nsAReadableString<CharT>() { }
virtual ~basic_nsAReadableString() { }
// ...yes, I expect to be sub-classed.
virtual PRUint32 Length() const = 0;
@@ -445,8 +453,8 @@ const char*
basic_nsAReadableString<char>::GetBuffer() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -456,8 +464,8 @@ const PRUnichar*
basic_nsAReadableString<PRUnichar>::GetUnicode() const
// DEPRECATED: use the iterators instead
{
ConstFragment fragment;
GetConstFragment(fragment, kFirstFragment);
ReadableFragment fragment;
GetReadableFragment(fragment, kFirstFragment);
return fragment.mStart;
}
@@ -472,7 +480,7 @@ basic_nsAReadableString<CharT>::Implementation() const
/*
Note: the following four functions, |CharAt|, |operator[]|, |First|, and |Last|, are implemented
in the simplest reasonable scheme; by calling |GetConstFragment| and resolving the pointer it
in the simplest reasonable scheme; by calling |GetReadableFragment| and resolving the pointer it
returns. The alternative is to force at least one of these methods to be |virtual|. The ideal
candidate for that change would be |CharAt|.
@@ -488,8 +496,8 @@ CharT
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
{
// ??? Is |CharAt()| supposed to be the 'safe' version?
ConstFragment fragment;
return *GetConstFragment(fragment, kFragmentAt, aIndex);
ReadableFragment fragment;
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
}
template <class CharT>
@@ -521,12 +529,12 @@ PRUint32
basic_nsAReadableString<CharT>::CountChar( CharT c ) const
{
#if 1
return PRUint32(count(Begin(), End(), c));
return PRUint32(count(BeginReading(), EndReading(), c));
#else
PRUint32 result = 0;
PRUint32 lengthToExamine = Length();
ConstIterator iter( Begin() );
ReadingIterator iter( BeginReading() );
for (;;)
{
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
@@ -567,7 +575,7 @@ PRUint32
basic_nsAReadableString<CharT>::Right( basic_nsAWritableString<CharT>& aResult, PRUint32 aLengthToCopy ) const
{
PRUint32 myLength = Length();
aLengthToCopy = std::min(myLength, aLengthToCopy);
aLengthToCopy = min(myLength, aLengthToCopy);
aResult = Substring(*this, myLength-aLengthToCopy, aLengthToCopy);
return aResult.Length();
}
@@ -621,17 +629,17 @@ class basic_nsLiteralString
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
// Note: _not_ explicit
basic_nsLiteralString( const CharT* aLiteral )
: mStart(aLiteral),
mEnd(mStart + char_traits<CharT>::length(mStart))
mEnd(mStart + nsCharTraits<CharT>::length(mStart))
{
// nothing else to do here
}
@@ -654,7 +662,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
template <class CharT>
const CharT*
basic_nsLiteralString<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
@@ -697,7 +705,7 @@ class nsPromiseConcatenation
Instances of this class only exist as anonymous temporary results from |operator+()|.
This is the machinery that makes string concatenation efficient. No allocations or
character copies are required unless and until a final assignment is made. It works
its magic by overriding and forwarding calls to |GetConstFragment()|.
its magic by overriding and forwarding calls to |GetReadableFragment()|.
Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|.
- no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33|
@@ -708,32 +716,32 @@ class nsPromiseConcatenation
for a user to need to control it. Too many strings summed together can easily be worked
around with an intermediate assignment. I wouldn't have the parentheses limitation if I
assigned the identifier mask starting at the top, the first time anybody called
|GetConstFragment()|.
|GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
enum { kLeftString, kRightString };
int
GetCurrentStringFromFragment( const ConstFragment& aFragment ) const
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
{
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
}
int
SetLeftStringInFragment( ConstFragment& aFragment ) const
SetLeftStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
return kLeftString;
}
int
SetRightStringInFragment( ConstFragment& aFragment ) const
SetRightStringInFragment( ReadableFragment& aFragment ) const
{
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
return kRightString;
@@ -772,14 +780,14 @@ nsPromiseConcatenation<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
const int kLeftString = 0;
const int kRightString = 1;
int whichString;
// based on the request, pick which string we will forward the |GetConstFragment()| call into
// based on the request, pick which string we will forward the |GetReadableFragment()| call into
switch ( aRequest )
{
@@ -814,7 +822,7 @@ nsPromiseConcatenation<CharT>::GetConstFragment( ConstFragment& aFragment, Fragm
do
{
done = true;
result = mStrings[whichString]->GetConstFragment(aFragment, aRequest, aPosition);
result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition);
if ( !result )
{
@@ -862,20 +870,20 @@ class nsPromiseSubstring
...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous
temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only
holds a pointer, no string data of its own. It does its magic by overriding and forwarding
calls to |GetConstFragment()|.
calls to |GetReadableFragment()|.
*/
{
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
protected:
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
public:
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
: mString(aString),
mStartPos( std::min(aStartPos, aString.Length()) ),
mLength( std::min(aLength, aString.Length()-mStartPos) )
mStartPos( min(aStartPos, aString.Length()) ),
mLength( min(aLength, aString.Length()-mStartPos) )
{
// nothing else to do here
}
@@ -899,7 +907,7 @@ nsPromiseSubstring<CharT>::Length() const
template <class CharT>
const CharT*
nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
{
// Offset any request for a specific position (First, Last, At) by our
// substrings startpos within the owning string
@@ -917,7 +925,7 @@ nsPromiseSubstring<CharT>::GetConstFragment( ConstFragment& aFragment, FragmentR
else if ( aRequest == kFragmentAt )
aPosition += mStartPos;
return mString.GetConstFragment(aFragment, aRequest, aPosition);
return mString.GetReadableFragment(aFragment, aRequest, aPosition);
}
@@ -945,20 +953,20 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
PRUint32 lLength = lhs.Length();
PRUint32 rLength = rhs.Length();
PRUint32 lengthToCompare = std::min(lLength, rLength);
PRUint32 lengthToCompare = min(lLength, rLength);
basic_nsAReadableString<CharT>::ConstIterator leftIter( lhs.Begin() );
basic_nsAReadableString<CharT>::ConstIterator rightIter( rhs.Begin() );
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
for (;;)
{
PRUint32 lengthAvailable = PRUint32( std::min(leftIter.size_forward(), rightIter.size_forward()) );
PRUint32 lengthAvailable = PRUint32( min(leftIter.size_forward(), rightIter.size_forward()) );
// assert( lengthAvailable >= 0 );
if ( lengthAvailable > lengthToCompare )
lengthAvailable = lengthToCompare;
if ( int result = std::char_traits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
if ( int result = nsCharTraits<CharT>::compare(leftIter.operator->(), rightIter.operator->(), lengthAvailable) )
return result;
if ( !(lengthToCompare -= lengthAvailable) )
@@ -1046,10 +1054,10 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<
#ifdef SCC_TESTS
template <class CharT, class TraitsT>
std::basic_ostream<CharT, class TraitsT>&
basic_ostream<CharT, TraitsT>&
operator<<( basic_ostream<CharT, TraitsT>& os, const basic_nsAReadableString<CharT>& s )
{
std::copy(s.Begin(), s.End(), ostream_iterator<CharT, CharT, TraitsT>(os));
copy(s.BeginReading(), s.EndReading(), ostream_iterator<CharT, CharT, TraitsT>(os));
return os;
}
#endif

View File

@@ -48,13 +48,13 @@ class basic_nsAWritableString
protected:
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
struct Fragment
struct WritableFragment
{
CharT* mStart;
CharT* mEnd;
PRUint32 mFragmentIdentifier;
Fragment()
WritableFragment()
: mStart(0), mEnd(0), mFragmentIdentifier(0)
{
// nothing else to do here
@@ -62,11 +62,11 @@ class basic_nsAWritableString
};
public:
virtual CharT* GetFragment( Fragment&, FragmentRequest, PRUint32 = 0 ) = 0;
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
friend class Iterator;
class Iterator
: public std::bidirectional_iterator_tag
friend class WritingIterator;
class WritingIterator
: public bidirectional_iterator_tag
{
public:
typedef ptrdiff_t difference_type;
@@ -78,15 +78,15 @@ class basic_nsAWritableString
private:
friend class basic_nsAWritableString<CharT>;
Fragment mFragment;
CharT* mPosition;
WritableFragment mFragment;
CharT* mPosition;
basic_nsAWritableString<CharT>* mOwningString;
void
normalize_forward()
{
if ( mPosition == mFragment.mEnd )
if ( mOwningString->GetFragment(mFragment, kNextFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
mPosition = mFragment.mStart;
}
@@ -94,11 +94,11 @@ class basic_nsAWritableString
normalize_backward()
{
if ( mPosition == mFragment.mStart )
if ( mOwningString->GetFragment(mFragment, kPrevFragment) )
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
mPosition = mFragment.mEnd;
}
Iterator( Fragment& aFragment,
WritingIterator( WritableFragment& aFragment,
CharT* aStartingPosition,
basic_nsAWritableString<CharT>& aOwningString )
: mFragment(aFragment),
@@ -109,8 +109,8 @@ class basic_nsAWritableString
}
public:
// Iterator( const Iterator& ); ...use default copy-constructor
// Iterator& operator=( const Iterator& ); ...use default copy-assignment operator
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
reference
@@ -125,7 +125,7 @@ class basic_nsAWritableString
return mPosition;
}
Iterator&
WritingIterator&
operator++()
{
++mPosition;
@@ -133,16 +133,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator++( int )
{
Iterator result(*this);
WritingIterator result(*this);
++mPosition;
normalize_forward();
return result;
}
Iterator&
WritingIterator&
operator--()
{
normalize_backward();
@@ -150,16 +150,16 @@ class basic_nsAWritableString
return *this;
}
Iterator
WritingIterator
operator--( int )
{
Iterator result(*this);
WritingIterator result(*this);
normalize_backward();
--mPosition;
return result;
}
const Fragment&
const WritableFragment&
fragment() const
{
return mFragment;
@@ -177,7 +177,7 @@ class basic_nsAWritableString
return mPosition - mFragment.mStart;
}
Iterator&
WritingIterator&
operator+=( difference_type n )
{
if ( n < 0 )
@@ -185,7 +185,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_forward());
difference_type one_hop = min(n, size_forward());
mPosition += one_hop;
normalize_forward();
n -= one_hop;
@@ -194,7 +194,7 @@ class basic_nsAWritableString
return *this;
}
Iterator&
WritingIterator&
operator-=( difference_type n )
{
if ( n < 0 )
@@ -202,7 +202,7 @@ class basic_nsAWritableString
while ( n )
{
difference_type one_hop = std::min(n, size_backward());
difference_type one_hop = min(n, size_backward());
mPosition -= one_hop;
normalize_backward();
n -= one_hop;
@@ -212,52 +212,37 @@ class basic_nsAWritableString
}
PRBool
operator==( const Iterator& rhs ) const
operator==( const WritingIterator& rhs ) const
{
return mPosition == rhs.mPosition;
}
PRBool
operator!=( const Iterator& rhs ) const
operator!=( const WritingIterator& rhs ) const
{
return mPosition != rhs.mPosition;
}
};
typedef WritingIterator Iterator;
public:
#ifdef HAVE_CPP_USING
using basic_nsAReadableString<CharT>::Begin;
using basic_nsAReadableString<CharT>::End;
#else
basic_nsAReadableString<CharT>::ConstIterator
Begin( PRUint32 aOffset = 0 ) const
WritingIterator
BeginWriting( PRUint32 aOffset = 0 )
{
return basic_nsAReadableString<CharT>::Begin(aOffset);
}
basic_nsAReadableString<CharT>::ConstIterator
End( PRUint32 aOffset = 0 ) const
{
return basic_nsAReadableString<CharT>::End(aOffset);
}
#endif
Iterator
Begin( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, aOffset);
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
return WritingIterator(fragment, startPos, *this);
}
Iterator
End( PRUint32 aOffset = 0 )
WritingIterator
EndWriting( PRUint32 aOffset = 0 )
{
Fragment fragment;
CharT* startPos = GetFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return Iterator(fragment, startPos, *this);
WritableFragment fragment;
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, max(0U, Length()-aOffset));
return WritingIterator(fragment, startPos, *this);
}
@@ -339,20 +324,20 @@ class basic_nsAWritableString
NS_DEF_STRING_COMPARISONS(basic_nsAWritableString<CharT>)
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_forward(), result.size_forward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_forward(), result.size_forward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(last.operator->() - first.operator->()));
// assert(lengthToCopy > 0);
std::char_traits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::copy(result.operator->(), first.operator->(), lengthToCopy);
first += PRInt32(lengthToCopy);
result += PRInt32(lengthToCopy);
@@ -362,18 +347,18 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
}
template <class CharT>
typename basic_nsAWritableString<CharT>::Iterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ConstIterator first,
typename basic_nsAReadableString<CharT>::ConstIterator last,
typename basic_nsAWritableString<CharT>::Iterator result )
typename basic_nsAWritableString<CharT>::WritingIterator
copy_backward_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
typename basic_nsAReadableString<CharT>::ReadingIterator last,
typename basic_nsAWritableString<CharT>::WritingIterator result )
{
while ( first != last )
{
PRUint32 lengthToCopy = PRUint32( std::min(first.size_backward(), result.size_backward()) );
PRUint32 lengthToCopy = PRUint32( min(first.size_backward(), result.size_backward()) );
if ( first.fragment().mStart == last.fragment().mStart )
lengthToCopy = std::min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
lengthToCopy = min(lengthToCopy, PRUint32(first.operator->() - last.operator->()));
std::char_traits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
nsCharTraits<CharT>::move(result.operator->(), first.operator->(), lengthToCopy);
first -= PRInt32(lengthToCopy);
result -= PRInt32(lengthToCopy);
@@ -390,7 +375,7 @@ void
basic_nsAWritableString<CharT>::Assign( const basic_nsAReadableString<CharT>& rhs )
{
SetLength(rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin());
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting());
}
template <class CharT>
@@ -399,7 +384,7 @@ basic_nsAWritableString<CharT>::Append( const basic_nsAReadableString<CharT>& rh
{
PRUint32 oldLength = Length();
SetLength(oldLength + rhs.Length());
copy_chunky<CharT>(rhs.Begin(), rhs.End(), Begin(oldLength));
copy_chunky<CharT>(rhs.BeginReading(), rhs.EndReading(), BeginWriting(oldLength));
}
template <class CharT>
@@ -407,31 +392,27 @@ void
basic_nsAWritableString<CharT>::AppendChar( CharT aChar )
{
SetLength(Length()+1);
*End(1) = aChar;
*EndWriting(1) = aChar;
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Insert( const basic_nsAReadableString<CharT>& aReadable, PRUint32 aPosition )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
PRUint32 oldLength = Length();
SetLength(oldLength + aReadable.Length());
if ( aPosition < oldLength )
copy_backward_chunky<CharT>(readable_t::Begin(aPosition), readable_t::Begin(oldLength), End());
copy_backward_chunky<CharT>(BeginReading(aPosition), BeginReading(oldLength), EndWriting());
else
aPosition = oldLength;
copy_chunky<CharT>(aReadable.Begin(), aReadable.End(), Begin(aPosition));
copy_chunky<CharT>(aReadable.BeginReading(), aReadable.EndReading(), BeginWriting(aPosition));
}
template <class CharT>
void
basic_nsAWritableString<CharT>::Cut( PRUint32 cutStart, PRUint32 cutLength )
{
typedef typename basic_nsAReadableString<CharT> readable_t;
copy_chunky<CharT>(readable_t::Begin(cutStart+cutLength), readable_t::End(), Begin(cutStart));
copy_chunky<CharT>(BeginReading(cutStart+cutLength), EndReading(), BeginWriting(cutStart));
SetLength(Length()-cutLength);
}
@@ -450,21 +431,19 @@ basic_nsAWritableString<CharT>::Replace( PRUint32 cutStart, PRUint32 cutLength,
PRUint32 newLength = oldLength - cutLength + replacementLength;
typedef typename basic_nsAReadableString<CharT> readable_t;
if ( cutLength > replacementLength )
copy_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::End(), Begin(replacementEnd));
copy_chunky<CharT>(BeginReading(cutEnd), EndReading(), BeginWriting(replacementEnd));
SetLength(newLength);
if ( cutLength < replacementLength )
copy_backward_chunky<CharT>(readable_t::Begin(cutEnd), readable_t::Begin(oldLength), Begin(replacementEnd));
copy_backward_chunky<CharT>(BeginReading(cutEnd), BeginReading(oldLength), BeginWriting(replacementEnd));
copy_chunky<CharT>(aReplacement.Begin(), aReplacement.End(), Begin(cutStart));
copy_chunky<CharT>(aReplacement.BeginReading(), aReplacement.EndReading(), BeginWriting(cutStart));
}
// operator>>
// getline (maybe)
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
typedef basic_nsAWritableString<PRUnichar> nsAWritableString;
typedef basic_nsAWritableString<char> nsAWritableCString;
#endif // !defined(_nsAWritableString_h__)

View File

@@ -36,7 +36,7 @@ class nsStringAllocator
};
template < class CharT, class TraitsT = char_traits<CharT>, class AllocatorT = nsStringAllocator<CharT> >
template < class CharT, class TraitsT = nsCharTraits<CharT>, class AllocatorT = nsStringAllocator<CharT> >
class basic_nsStdStringWrapper
: public basic_nsAWritableString<CharT>
/*
@@ -47,8 +47,8 @@ class basic_nsStdStringWrapper
std::basic_string<CharT, TraitsT, AllocatorT> mRawString;
typedef typename basic_nsAWritableString<CharT>::FragmentRequest FragmentRequest;
typedef typename basic_nsAWritableString<CharT>::ConstFragment ConstFragment;
typedef typename basic_nsAWritableString<CharT>::Fragment Fragment;
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
typedef typename basic_nsAWritableString<CharT>::WritableFragment WritableFragment;
typedef std::basic_string<CharT, TraitsT, AllocatorT> basic_string_t;
@@ -71,8 +71,8 @@ class basic_nsStdStringWrapper
protected:
virtual const void* Implementation() const;
virtual const CharT* GetConstFragment( ConstFragment&, FragmentRequest, PRUint32 ) const;
virtual CharT* GetFragment( Fragment&, FragmentRequest, PRUint32 );
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
public:
basic_nsStdStringWrapper() { }
@@ -164,7 +164,7 @@ basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::Implementation() const
template <class CharT, class TraitsT, class AllocatorT>
const CharT*
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetConstFragment( ConstFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
{
switch ( aRequest )
{
@@ -183,7 +183,7 @@ basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetConstFragment( ConstFra
template <class CharT, class TraitsT, class AllocatorT>
CharT*
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetFragment( Fragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset )
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset )
{
switch ( aRequest )
{
@@ -219,7 +219,7 @@ template <class CharT, class TraitsT, class AllocatorT>
void
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::Append( const basic_nsAReadableString<CharT>& rhs )
{
mRawString.append(rhs.Begin(), rhs.End());
mRawString.append(rhs.BeginReading(), rhs.EndReading());
}
template <class CharT, class TraitsT, class AllocatorT>
@@ -233,7 +233,7 @@ template <class CharT, class TraitsT, class AllocatorT>
void
basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::Insert( const basic_nsAReadableString<CharT>& rhs, PRUint32 atPosition )
{
mRawString.insert(mRawString.begin()+atPosition, rhs.Begin(), rhs.End());
mRawString.insert(mRawString.begin()+atPosition, rhs.BeginReading(), rhs.EndReading());
}
template <class CharT, class TraitsT, class AllocatorT>

View File

@@ -16,7 +16,7 @@ print_string( const nsAReadableString& s )
char operator()( PRUnichar c ) { return char(c); }
};
transform(s.Begin(), s.End(), ostream_iterator<char>(cout), PRUnichar_to_char());
transform(s.BeginReading(), s.EndReading(), ostream_iterator<char>(cout), PRUnichar_to_char());
return cout;
}
@@ -71,11 +71,11 @@ test_multifragment_iterators( const basic_nsAReadableString<CharT>& aString )
int tests_failed = 0;
ConstIterator iter1 = aString.Begin();
ConstIterator iter2 = aString.Begin();
ConstIterator iter1 = aString.BeginReading();
ConstIterator iter2 = aString.BeginReading();
++iter2; ++iter2;
ConstIterator iter3 = aString.End();
ConstIterator iter3 = aString.EndReading();
--iter3;
++iter1; ++iter1;
if ( iter1 != iter2 )
@@ -180,7 +180,7 @@ test_readable_hello( const basic_nsAReadableString<CharT>& aReadable )
++tests_failed;
}
basic_nsAReadableString<CharT>::ConstIterator iter = aReadable.Begin();
basic_nsAReadableString<CharT>::ConstIterator iter = aReadable.BeginReading();
if ( *iter != CharT('H') )
{
cout << "FAILED |test_readable_hello|: didn't start out pointing to the right thing, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
@@ -195,25 +195,25 @@ test_readable_hello( const basic_nsAReadableString<CharT>& aReadable )
++tests_failed;
}
iter = aReadable.End();
iter = aReadable.EndReading();
--iter;
if ( *iter != CharT('o') )
{
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |End()|, or else couldn't be decremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading()|, or else couldn't be decremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
++tests_failed;
}
basic_nsAReadableString<CharT>::ConstIterator iter1 = aReadable.Begin(3);
basic_nsAReadableString<CharT>::ConstIterator iter1 = aReadable.BeginReading(3);
if ( *iter1 != CharT('l') )
{
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |Begin(n)|, or else couldn't be dereferenced. --> '" << *iter1 << "'" << endl;
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |BeginReading(n)|, or else couldn't be dereferenced. --> '" << *iter1 << "'" << endl;
++tests_failed;
}
basic_nsAReadableString<CharT>::ConstIterator iter2 = aReadable.End(2);
basic_nsAReadableString<CharT>::ConstIterator iter2 = aReadable.EndReading(2);
if ( *iter2 != CharT('l') )
{
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |End(n)|, or else couldn't be dereferenced. --> '" << *iter2 << "'" << endl;
cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading(n)|, or else couldn't be dereferenced. --> '" << *iter2 << "'" << endl;
++tests_failed;
}