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:
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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& );
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__)
|
||||
|
||||
Binary file not shown.
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user