зеркало из https://github.com/mozilla/pjs.git
Lots of changes to get this stuff building on Solaris, et al. None of these changes effect the mainline build yet, and won't until |NEW_STRING_APIS| is defined for everyone (coming soon)
This commit is contained in:
Родитель
453e1e1288
Коммит
ea8e807dda
|
@ -126,7 +126,7 @@ nsCString::~nsCString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const char* nsCString::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen
|
|||
}
|
||||
}
|
||||
|
||||
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
char* nsCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) {
|
|||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Retrieves internal (1-byte) buffer ptr;
|
||||
* @update gess1/4/99
|
||||
|
@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const {
|
|||
return mStr;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -60,12 +60,8 @@ class NS_COM nsCString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableCString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableCString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableCString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsCString( const nsAReadableCString& );
|
||||
|
@ -184,6 +180,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
|
@ -196,6 +193,7 @@ public:
|
|||
const char* GetBuffer(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
@ -745,13 +743,11 @@ public:
|
|||
|
||||
};
|
||||
|
||||
#if 0
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&);
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern NS_COM int fputs(const nsCString& aString, FILE* out);
|
||||
//ostream& operator<<(ostream& aStream,const nsCString& aString);
|
||||
|
@ -800,6 +796,11 @@ public:
|
|||
char mBuffer[kDefaultStringSize];
|
||||
};
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&)
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
|
|
|
@ -137,7 +137,7 @@ nsString::~nsString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const PRUnichar* nsString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra
|
|||
}
|
||||
}
|
||||
|
||||
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
PRUnichar* nsString::GetWritableFragment( nsWritableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) {
|
|||
|
||||
|
||||
//static char gChar=0;
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
*
|
||||
* @update gess1/4/99
|
||||
|
@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -67,12 +67,8 @@ class NS_COM nsString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsString( const nsAReadableString& );
|
||||
|
@ -189,7 +185,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
|
@ -201,6 +196,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
|
@ -209,6 +205,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Getters/Setters...
|
||||
|
@ -221,6 +218,7 @@ public:
|
|||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -63,6 +63,7 @@ using namespace std;
|
|||
'C') is a string of |char|s.
|
||||
*/
|
||||
|
||||
template <class CharT> class basic_nsAReadableString;
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
// ...because we sometimes use them as `out' params
|
||||
|
@ -71,8 +72,171 @@ template <class CharT> class basic_nsLiteralString;
|
|||
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
|
||||
|
||||
|
||||
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
template <class CharT>
|
||||
struct nsReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
nsReadableFragment<CharT> mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsReadingIterator( const nsReadableFragment<CharT>& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsReadingIterator( const nsReadingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsReadableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
|
@ -85,213 +249,34 @@ class basic_nsAReadableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
|
||||
struct ReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
ReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
// friend class nsReadingIterator<CharT>;
|
||||
|
||||
public:
|
||||
|
||||
typedef nsReadingIterator<CharT> ConstIterator;
|
||||
|
||||
public:
|
||||
|
||||
virtual const void* Implementation() const;
|
||||
|
||||
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
// 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 ReadingIterator;
|
||||
class ReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
ReadableFragment mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
|
||||
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
ReadingIterator( const ReadableFragment& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
|
||||
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator++( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator--( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const ReadableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef ReadingIterator ConstIterator;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
BeginReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
EndReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -308,22 +293,6 @@ class basic_nsAReadableString
|
|||
|
||||
|
||||
|
||||
/*
|
||||
RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()|
|
||||
shouldn't be implemented because they're wrong access. I agree. Callers who really need
|
||||
this access should use the iterators instead. We'll use these to ease the transition to
|
||||
|nsAReadable...|, and then remove them as soon as possible.
|
||||
*/
|
||||
|
||||
PRBool IsUnicode() const { return PR_FALSE; }
|
||||
// ...but note specialization for |PRUnichar|, below
|
||||
|
||||
const char* GetBuffer() const { return 0; }
|
||||
const PRUnichar* GetUnicode() const { return 0; }
|
||||
// ...but note specializations for |char| and |PRUnichar|, below
|
||||
|
||||
|
||||
|
||||
CharT CharAt( PRUint32 ) const;
|
||||
CharT operator[]( PRUint32 ) const;
|
||||
CharT First() const;
|
||||
|
@ -411,6 +380,26 @@ class basic_nsAReadableString
|
|||
PRBool operator> ( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)> 0; }
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
#define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \
|
||||
inline \
|
||||
PRBool \
|
||||
|
@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString<CharT>)
|
|||
|
||||
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
PRBool
|
||||
basic_nsAReadableString<PRUnichar>::IsUnicode() const
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const char*
|
||||
basic_nsAReadableString<char>::GetBuffer() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const PRUnichar*
|
||||
basic_nsAReadableString<PRUnichar>::GetUnicode() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
const void*
|
||||
basic_nsAReadableString<CharT>::Implementation() const
|
||||
|
@ -501,7 +460,7 @@ CharT
|
|||
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
|
||||
{
|
||||
// ??? Is |CharAt()| supposed to be the 'safe' version?
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
|
||||
}
|
||||
|
||||
|
@ -539,7 +498,7 @@ basic_nsAReadableString<CharT>::CountChar( CharT c ) const
|
|||
PRUint32 result = 0;
|
||||
PRUint32 lengthToExamine = Length();
|
||||
|
||||
ReadingIterator iter( BeginReading() );
|
||||
nsReadingIterator<CharT> iter( BeginReading() );
|
||||
for (;;)
|
||||
{
|
||||
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
|
||||
|
@ -633,11 +592,8 @@ class basic_nsLiteralString
|
|||
allows the automatic conversion of a |CharT*|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
|
@ -724,29 +680,26 @@ class nsPromiseConcatenation
|
|||
|GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
enum { kLeftString, kRightString };
|
||||
|
||||
int
|
||||
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
|
||||
GetCurrentStringFromFragment( const nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetLeftStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetLeftStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
|
||||
return kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetRightStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetRightStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
|
||||
return kRightString;
|
||||
|
@ -785,7 +738,7 @@ nsPromiseConcatenation<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
int whichString;
|
||||
|
||||
|
@ -848,6 +801,7 @@ nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
nsPromiseConcatenation<CharT>::operator+( const basic_nsAReadableString<CharT>& rhs ) const
|
||||
{
|
||||
|
@ -875,11 +829,8 @@ class nsPromiseSubstring
|
|||
calls to |GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
|
||||
|
@ -909,7 +860,7 @@ nsPromiseSubstring<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
// Offset any request for a specific position (First, Last, At) by our
|
||||
// substrings startpos within the owning string
|
||||
|
@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
PRUint32 rLength = rhs.Length();
|
||||
PRUint32 lengthToCompare = NS_MIN(lLength, rLength);
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
|
||||
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
|
||||
nsReadingIterator<CharT> leftIter( lhs.BeginReading() );
|
||||
nsReadingIterator<CharT> rightIter( rhs.BeginReading() );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString<CharT>& rhs )
|
|||
*/
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStr
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
|
|
@ -30,6 +30,158 @@
|
|||
#include "nsAReadableString.h"
|
||||
|
||||
|
||||
template <class CharT>
|
||||
struct nsWritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsWritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
|
||||
template <class CharT>
|
||||
class nsWritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
nsWritableFragment<CharT> mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsWritingIterator( nsWritableFragment<CharT>& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsWritingIterator( const nsWritingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsWritableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
This file defines the abstract interfaces |nsAWritableString| and
|
||||
|nsAWritableCString|.
|
||||
|
@ -45,204 +197,29 @@ class basic_nsAWritableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
protected:
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
|
||||
struct WritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
WritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
// friend class nsWritingIterator<CharT>;
|
||||
|
||||
public:
|
||||
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
|
||||
typedef nsWritingIterator<CharT> Iterator;
|
||||
|
||||
friend class WritingIterator;
|
||||
class WritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
WritableFragment mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
WritingIterator( WritableFragment& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
|
||||
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator++( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator--( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const WritableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator==( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef WritingIterator Iterator;
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
BeginWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
EndWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,12 +298,45 @@ class basic_nsAWritableString
|
|||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition != rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
nsWritingIterator<CharT>
|
||||
copy_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
nsWritingIterator<CharT>
|
||||
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
|
|
@ -35,8 +35,29 @@ class basic_nsSharedString
|
|||
...
|
||||
*/
|
||||
{
|
||||
private:
|
||||
~basic_nsSharedString() { }
|
||||
// You can't sub-class me, or make an instance of me on the stack
|
||||
|
||||
// operator delete
|
||||
|
||||
public:
|
||||
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
virtual
|
||||
PRUint32
|
||||
Length() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
basic_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
mLength = aReadable.Length();
|
||||
copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0);
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
AddRef() const
|
||||
{
|
||||
|
@ -53,10 +74,31 @@ class basic_nsSharedString
|
|||
}
|
||||
|
||||
private:
|
||||
mutable nsrefcnt mRefCount;
|
||||
mutable nsrefcnt mRefCount;
|
||||
size_t mLength;
|
||||
CharT mData[1];
|
||||
};
|
||||
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper<CharT>)
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsSharedString<CharT>)
|
||||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsSharedString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
case kFragmentAt:
|
||||
aFragment.mEnd = (aFragment.mStart = mData) + mLength;
|
||||
return aFragment.mStart + anOffset;
|
||||
|
||||
case kPrevFragment:
|
||||
case kNextFragment:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -71,12 +113,17 @@ class nsSharedStringPtr
|
|||
};
|
||||
|
||||
|
||||
template <class CharT>
|
||||
basic_nsSharedString<CharT>*
|
||||
new_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
void* in_buffer = operator new( sizeof(basic_nsSharedString<CharT>) + aReadable.Length()*sizeof(CharT) );
|
||||
return new (in_buffer) basic_nsSharedString<CharT>(aReadable);
|
||||
}
|
||||
|
||||
|
||||
typedef basic_nsSharedString<PRUnichar> nsSharedString;
|
||||
typedef basic_nsSharedStringPtr<PRUnichar> nsSharedStringPtr;
|
||||
|
||||
typedef basic_nsSharedString<char> nsSharedCString;
|
||||
typedef basic_nsSharedStringPtr<char> nsSharedCStringPtr;
|
||||
|
||||
|
||||
#endif // !defined(_nsSharedString_h__)
|
||||
|
|
|
@ -63,6 +63,7 @@ using namespace std;
|
|||
'C') is a string of |char|s.
|
||||
*/
|
||||
|
||||
template <class CharT> class basic_nsAReadableString;
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
// ...because we sometimes use them as `out' params
|
||||
|
@ -71,8 +72,171 @@ template <class CharT> class basic_nsLiteralString;
|
|||
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
|
||||
|
||||
|
||||
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
template <class CharT>
|
||||
struct nsReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
nsReadableFragment<CharT> mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsReadingIterator( const nsReadableFragment<CharT>& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsReadingIterator( const nsReadingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsReadableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
|
@ -85,213 +249,34 @@ class basic_nsAReadableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
|
||||
struct ReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
ReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
// friend class nsReadingIterator<CharT>;
|
||||
|
||||
public:
|
||||
|
||||
typedef nsReadingIterator<CharT> ConstIterator;
|
||||
|
||||
public:
|
||||
|
||||
virtual const void* Implementation() const;
|
||||
|
||||
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
// 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 ReadingIterator;
|
||||
class ReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
ReadableFragment mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
|
||||
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
ReadingIterator( const ReadableFragment& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
|
||||
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator++( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator--( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const ReadableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef ReadingIterator ConstIterator;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
BeginReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
EndReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -308,22 +293,6 @@ class basic_nsAReadableString
|
|||
|
||||
|
||||
|
||||
/*
|
||||
RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()|
|
||||
shouldn't be implemented because they're wrong access. I agree. Callers who really need
|
||||
this access should use the iterators instead. We'll use these to ease the transition to
|
||||
|nsAReadable...|, and then remove them as soon as possible.
|
||||
*/
|
||||
|
||||
PRBool IsUnicode() const { return PR_FALSE; }
|
||||
// ...but note specialization for |PRUnichar|, below
|
||||
|
||||
const char* GetBuffer() const { return 0; }
|
||||
const PRUnichar* GetUnicode() const { return 0; }
|
||||
// ...but note specializations for |char| and |PRUnichar|, below
|
||||
|
||||
|
||||
|
||||
CharT CharAt( PRUint32 ) const;
|
||||
CharT operator[]( PRUint32 ) const;
|
||||
CharT First() const;
|
||||
|
@ -411,6 +380,26 @@ class basic_nsAReadableString
|
|||
PRBool operator> ( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)> 0; }
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
#define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \
|
||||
inline \
|
||||
PRBool \
|
||||
|
@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString<CharT>)
|
|||
|
||||
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
PRBool
|
||||
basic_nsAReadableString<PRUnichar>::IsUnicode() const
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const char*
|
||||
basic_nsAReadableString<char>::GetBuffer() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const PRUnichar*
|
||||
basic_nsAReadableString<PRUnichar>::GetUnicode() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
const void*
|
||||
basic_nsAReadableString<CharT>::Implementation() const
|
||||
|
@ -501,7 +460,7 @@ CharT
|
|||
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
|
||||
{
|
||||
// ??? Is |CharAt()| supposed to be the 'safe' version?
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
|
||||
}
|
||||
|
||||
|
@ -539,7 +498,7 @@ basic_nsAReadableString<CharT>::CountChar( CharT c ) const
|
|||
PRUint32 result = 0;
|
||||
PRUint32 lengthToExamine = Length();
|
||||
|
||||
ReadingIterator iter( BeginReading() );
|
||||
nsReadingIterator<CharT> iter( BeginReading() );
|
||||
for (;;)
|
||||
{
|
||||
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
|
||||
|
@ -633,11 +592,8 @@ class basic_nsLiteralString
|
|||
allows the automatic conversion of a |CharT*|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
|
@ -724,29 +680,26 @@ class nsPromiseConcatenation
|
|||
|GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
enum { kLeftString, kRightString };
|
||||
|
||||
int
|
||||
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
|
||||
GetCurrentStringFromFragment( const nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetLeftStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetLeftStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
|
||||
return kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetRightStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetRightStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
|
||||
return kRightString;
|
||||
|
@ -785,7 +738,7 @@ nsPromiseConcatenation<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
int whichString;
|
||||
|
||||
|
@ -848,6 +801,7 @@ nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
nsPromiseConcatenation<CharT>::operator+( const basic_nsAReadableString<CharT>& rhs ) const
|
||||
{
|
||||
|
@ -875,11 +829,8 @@ class nsPromiseSubstring
|
|||
calls to |GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
|
||||
|
@ -909,7 +860,7 @@ nsPromiseSubstring<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
// Offset any request for a specific position (First, Last, At) by our
|
||||
// substrings startpos within the owning string
|
||||
|
@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
PRUint32 rLength = rhs.Length();
|
||||
PRUint32 lengthToCompare = NS_MIN(lLength, rLength);
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
|
||||
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
|
||||
nsReadingIterator<CharT> leftIter( lhs.BeginReading() );
|
||||
nsReadingIterator<CharT> rightIter( rhs.BeginReading() );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString<CharT>& rhs )
|
|||
*/
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStr
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
|
|
@ -30,6 +30,158 @@
|
|||
#include "nsAReadableString.h"
|
||||
|
||||
|
||||
template <class CharT>
|
||||
struct nsWritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsWritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
|
||||
template <class CharT>
|
||||
class nsWritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
nsWritableFragment<CharT> mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsWritingIterator( nsWritableFragment<CharT>& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsWritingIterator( const nsWritingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsWritableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
This file defines the abstract interfaces |nsAWritableString| and
|
||||
|nsAWritableCString|.
|
||||
|
@ -45,204 +197,29 @@ class basic_nsAWritableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
protected:
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
|
||||
struct WritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
WritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
// friend class nsWritingIterator<CharT>;
|
||||
|
||||
public:
|
||||
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
|
||||
typedef nsWritingIterator<CharT> Iterator;
|
||||
|
||||
friend class WritingIterator;
|
||||
class WritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
WritableFragment mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
WritingIterator( WritableFragment& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
|
||||
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator++( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator--( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const WritableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator==( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef WritingIterator Iterator;
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
BeginWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
EndWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,12 +298,45 @@ class basic_nsAWritableString
|
|||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition != rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
nsWritingIterator<CharT>
|
||||
copy_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
nsWritingIterator<CharT>
|
||||
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
|
|
@ -35,8 +35,29 @@ class basic_nsSharedString
|
|||
...
|
||||
*/
|
||||
{
|
||||
private:
|
||||
~basic_nsSharedString() { }
|
||||
// You can't sub-class me, or make an instance of me on the stack
|
||||
|
||||
// operator delete
|
||||
|
||||
public:
|
||||
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
virtual
|
||||
PRUint32
|
||||
Length() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
basic_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
mLength = aReadable.Length();
|
||||
copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0);
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
AddRef() const
|
||||
{
|
||||
|
@ -53,10 +74,31 @@ class basic_nsSharedString
|
|||
}
|
||||
|
||||
private:
|
||||
mutable nsrefcnt mRefCount;
|
||||
mutable nsrefcnt mRefCount;
|
||||
size_t mLength;
|
||||
CharT mData[1];
|
||||
};
|
||||
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper<CharT>)
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsSharedString<CharT>)
|
||||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsSharedString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
case kFragmentAt:
|
||||
aFragment.mEnd = (aFragment.mStart = mData) + mLength;
|
||||
return aFragment.mStart + anOffset;
|
||||
|
||||
case kPrevFragment:
|
||||
case kNextFragment:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -71,12 +113,17 @@ class nsSharedStringPtr
|
|||
};
|
||||
|
||||
|
||||
template <class CharT>
|
||||
basic_nsSharedString<CharT>*
|
||||
new_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
void* in_buffer = operator new( sizeof(basic_nsSharedString<CharT>) + aReadable.Length()*sizeof(CharT) );
|
||||
return new (in_buffer) basic_nsSharedString<CharT>(aReadable);
|
||||
}
|
||||
|
||||
|
||||
typedef basic_nsSharedString<PRUnichar> nsSharedString;
|
||||
typedef basic_nsSharedStringPtr<PRUnichar> nsSharedStringPtr;
|
||||
|
||||
typedef basic_nsSharedString<char> nsSharedCString;
|
||||
typedef basic_nsSharedStringPtr<char> nsSharedCStringPtr;
|
||||
|
||||
|
||||
#endif // !defined(_nsSharedString_h__)
|
||||
|
|
|
@ -126,7 +126,7 @@ nsCString::~nsCString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const char* nsCString::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen
|
|||
}
|
||||
}
|
||||
|
||||
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
char* nsCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) {
|
|||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Retrieves internal (1-byte) buffer ptr;
|
||||
* @update gess1/4/99
|
||||
|
@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const {
|
|||
return mStr;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -60,12 +60,8 @@ class NS_COM nsCString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableCString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableCString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableCString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsCString( const nsAReadableCString& );
|
||||
|
@ -184,6 +180,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
|
@ -196,6 +193,7 @@ public:
|
|||
const char* GetBuffer(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
@ -745,13 +743,11 @@ public:
|
|||
|
||||
};
|
||||
|
||||
#if 0
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&);
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern NS_COM int fputs(const nsCString& aString, FILE* out);
|
||||
//ostream& operator<<(ostream& aStream,const nsCString& aString);
|
||||
|
@ -800,6 +796,11 @@ public:
|
|||
char mBuffer[kDefaultStringSize];
|
||||
};
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&)
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
|
|
|
@ -137,7 +137,7 @@ nsString::~nsString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const PRUnichar* nsString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra
|
|||
}
|
||||
}
|
||||
|
||||
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
PRUnichar* nsString::GetWritableFragment( nsWritableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) {
|
|||
|
||||
|
||||
//static char gChar=0;
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
*
|
||||
* @update gess1/4/99
|
||||
|
@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -67,12 +67,8 @@ class NS_COM nsString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsString( const nsAReadableString& );
|
||||
|
@ -189,7 +185,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
|
@ -201,6 +196,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
|
@ -209,6 +205,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Getters/Setters...
|
||||
|
@ -221,6 +218,7 @@ public:
|
|||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -126,7 +126,7 @@ nsCString::~nsCString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const char* nsCString::GetReadableFragment( nsReadableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -141,7 +141,7 @@ const char* nsCString::GetReadableFragment( ReadableFragment& aFragment, Fragmen
|
|||
}
|
||||
}
|
||||
|
||||
char* nsCString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
char* nsCString::GetWritableFragment( nsWritableFragment<char>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -204,7 +204,6 @@ void nsCString::SetCapacity(PRUint32 aLength) {
|
|||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Retrieves internal (1-byte) buffer ptr;
|
||||
* @update gess1/4/99
|
||||
|
@ -214,6 +213,7 @@ const char* nsCString::GetBuffer(void) const {
|
|||
return mStr;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -60,12 +60,8 @@ class NS_COM nsCString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableCString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableCString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableCString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const char* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const char* GetReadableFragment( nsReadableFragment<char>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual char* GetWritableFragment( nsWritableFragment<char>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsCString( const nsAReadableCString& );
|
||||
|
@ -184,6 +180,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
|
@ -196,6 +193,7 @@ public:
|
|||
const char* GetBuffer(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
@ -745,13 +743,11 @@ public:
|
|||
|
||||
};
|
||||
|
||||
#if 0
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const nsCString&);
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCString&)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern NS_COM int fputs(const nsCString& aString, FILE* out);
|
||||
//ostream& operator<<(ostream& aStream,const nsCString& aString);
|
||||
|
@ -800,6 +796,11 @@ public:
|
|||
char mBuffer[kDefaultStringSize];
|
||||
};
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const nsCAutoString&, const char*)
|
||||
NS_DEF_NON_TEMPLATE_STRING_COMPARISON_OPERATORS(const char*, const nsCAutoString&)
|
||||
#endif
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
|
|
|
@ -137,7 +137,7 @@ nsString::~nsString() {
|
|||
}
|
||||
|
||||
#ifdef NEW_STRING_APIS
|
||||
const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
const PRUnichar* nsString::GetReadableFragment( nsReadableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -152,7 +152,7 @@ const PRUnichar* nsString::GetReadableFragment( ReadableFragment& aFragment, Fra
|
|||
}
|
||||
}
|
||||
|
||||
PRUnichar* nsString::GetWritableFragment( WritableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
PRUnichar* nsString::GetWritableFragment( nsWritableFragment<PRUnichar>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) {
|
||||
switch ( aRequest ) {
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
|
@ -218,7 +218,6 @@ void nsString::SetCapacity(PRUint32 aLength) {
|
|||
|
||||
|
||||
//static char gChar=0;
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
*
|
||||
* @update gess1/4/99
|
||||
|
@ -243,6 +242,7 @@ const PRUnichar* nsString::GetUnicode(void) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -67,12 +67,8 @@ class NS_COM nsString :
|
|||
|
||||
#ifdef NEW_STRING_APIS
|
||||
protected:
|
||||
typedef nsAReadableString::FragmentRequest FragmentRequest;
|
||||
typedef nsAReadableString::ReadableFragment ReadableFragment;
|
||||
typedef nsAWritableString::WritableFragment WritableFragment;
|
||||
|
||||
virtual const PRUnichar* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 );
|
||||
virtual const PRUnichar* GetReadableFragment( nsReadableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 ) const;
|
||||
virtual PRUnichar* GetWritableFragment( nsWritableFragment<PRUnichar>&, nsFragmentRequest, PRUint32 );
|
||||
|
||||
public:
|
||||
nsString( const nsAReadableString& );
|
||||
|
@ -189,7 +185,6 @@ public:
|
|||
}
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
|
@ -201,6 +196,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
|
@ -209,6 +205,7 @@ public:
|
|||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************
|
||||
Getters/Setters...
|
||||
|
@ -221,6 +218,7 @@ public:
|
|||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
|
||||
#ifndef NEW_STRING_APIS
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
|
|
|
@ -63,6 +63,7 @@ using namespace std;
|
|||
'C') is a string of |char|s.
|
||||
*/
|
||||
|
||||
template <class CharT> class basic_nsAReadableString;
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
// ...because we sometimes use them as `out' params
|
||||
|
@ -71,8 +72,171 @@ template <class CharT> class basic_nsLiteralString;
|
|||
// ...because we sometimes use them as in params to force the conversion of |CharT*|s
|
||||
|
||||
|
||||
enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
template <class CharT>
|
||||
struct nsReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
class nsReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
nsReadableFragment<CharT> mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsReadingIterator( const nsReadableFragment<CharT>& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsReadingIterator( const nsReadingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsReadingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsReadableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsReadingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const nsReadingIterator<CharT>& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
|
@ -85,213 +249,34 @@ class basic_nsAReadableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
public:
|
||||
|
||||
struct ReadableFragment
|
||||
{
|
||||
const CharT* mStart;
|
||||
const CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
ReadableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
// friend class nsReadingIterator<CharT>;
|
||||
|
||||
public:
|
||||
|
||||
typedef nsReadingIterator<CharT> ConstIterator;
|
||||
|
||||
public:
|
||||
|
||||
virtual const void* Implementation() const;
|
||||
|
||||
enum FragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
|
||||
|
||||
// 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 ReadingIterator;
|
||||
class ReadingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef const CharT* pointer;
|
||||
typedef const CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAReadableString<CharT>;
|
||||
|
||||
ReadableFragment mFragment;
|
||||
const CharT* mPosition;
|
||||
const basic_nsAReadableString<CharT>* mOwningString;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
|
||||
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
ReadingIterator( const ReadableFragment& aFragment,
|
||||
const CharT* aStartingPosition,
|
||||
const basic_nsAReadableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// ReadingIterator( const ReadingIterator& ); ...use default copy-constructor
|
||||
// ReadingIterator& operator=( const ReadingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
CharT
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator++( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator
|
||||
operator--( int )
|
||||
{
|
||||
ReadingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const ReadableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReadingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
// Damn again! Problems with templates made me implement comparisons as members.
|
||||
|
||||
PRBool
|
||||
operator==( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const ReadingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef ReadingIterator ConstIterator;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
BeginReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator
|
||||
nsReadingIterator<CharT>
|
||||
EndReading( PRUint32 aOffset = 0 ) const
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
const CharT* startPos = GetReadableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAReadableString<CharT>::ReadingIterator(fragment, startPos, *this);
|
||||
return nsReadingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -308,22 +293,6 @@ class basic_nsAReadableString
|
|||
|
||||
|
||||
|
||||
/*
|
||||
RickG says the following three routines, |IsUnicode()|, |GetBuffer()|, and |GetUnicode()|
|
||||
shouldn't be implemented because they're wrong access. I agree. Callers who really need
|
||||
this access should use the iterators instead. We'll use these to ease the transition to
|
||||
|nsAReadable...|, and then remove them as soon as possible.
|
||||
*/
|
||||
|
||||
PRBool IsUnicode() const { return PR_FALSE; }
|
||||
// ...but note specialization for |PRUnichar|, below
|
||||
|
||||
const char* GetBuffer() const { return 0; }
|
||||
const PRUnichar* GetUnicode() const { return 0; }
|
||||
// ...but note specializations for |char| and |PRUnichar|, below
|
||||
|
||||
|
||||
|
||||
CharT CharAt( PRUint32 ) const;
|
||||
CharT operator[]( PRUint32 ) const;
|
||||
CharT First() const;
|
||||
|
@ -411,6 +380,26 @@ class basic_nsAReadableString
|
|||
PRBool operator> ( const basic_nsAReadableString<CharT>& rhs ) const { return Compare(rhs)> 0; }
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsReadingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetReadableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
#define NS_DEF_1_STRING_COMPARISON_OPERATOR(comp, T1, T2) \
|
||||
inline \
|
||||
PRBool \
|
||||
|
@ -444,36 +433,6 @@ NS_DEF_STRING_COMPARISONS(basic_nsAReadableString<CharT>)
|
|||
|
||||
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
PRBool
|
||||
basic_nsAReadableString<PRUnichar>::IsUnicode() const
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const char*
|
||||
basic_nsAReadableString<char>::GetBuffer() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
inline
|
||||
const PRUnichar*
|
||||
basic_nsAReadableString<PRUnichar>::GetUnicode() const
|
||||
// DEPRECATED: use the iterators instead
|
||||
{
|
||||
ReadableFragment fragment;
|
||||
GetReadableFragment(fragment, kFirstFragment);
|
||||
return fragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
const void*
|
||||
basic_nsAReadableString<CharT>::Implementation() const
|
||||
|
@ -501,7 +460,7 @@ CharT
|
|||
basic_nsAReadableString<CharT>::CharAt( PRUint32 aIndex ) const
|
||||
{
|
||||
// ??? Is |CharAt()| supposed to be the 'safe' version?
|
||||
ReadableFragment fragment;
|
||||
nsReadableFragment<CharT> fragment;
|
||||
return *GetReadableFragment(fragment, kFragmentAt, aIndex);
|
||||
}
|
||||
|
||||
|
@ -539,7 +498,7 @@ basic_nsAReadableString<CharT>::CountChar( CharT c ) const
|
|||
PRUint32 result = 0;
|
||||
PRUint32 lengthToExamine = Length();
|
||||
|
||||
ReadingIterator iter( BeginReading() );
|
||||
nsReadingIterator<CharT> iter( BeginReading() );
|
||||
for (;;)
|
||||
{
|
||||
PRUint32 lengthToExamineInThisFragment = iter.size_forward();
|
||||
|
@ -633,11 +592,8 @@ class basic_nsLiteralString
|
|||
allows the automatic conversion of a |CharT*|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -667,7 +623,7 @@ NS_DEF_STRING_COMPARISONS(basic_nsLiteralString<CharT>)
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
basic_nsLiteralString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
|
@ -724,29 +680,26 @@ class nsPromiseConcatenation
|
|||
|GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
enum { kLeftString, kRightString };
|
||||
|
||||
int
|
||||
GetCurrentStringFromFragment( const ReadableFragment& aFragment ) const
|
||||
GetCurrentStringFromFragment( const nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
return (aFragment.mFragmentIdentifier & mFragmentIdentifierMask) ? kRightString : kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetLeftStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetLeftStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier &= ~mFragmentIdentifierMask;
|
||||
return kLeftString;
|
||||
}
|
||||
|
||||
int
|
||||
SetRightStringInFragment( ReadableFragment& aFragment ) const
|
||||
SetRightStringInFragment( nsReadableFragment<CharT>& aFragment ) const
|
||||
{
|
||||
aFragment.mFragmentIdentifier |= mFragmentIdentifierMask;
|
||||
return kRightString;
|
||||
|
@ -785,7 +738,7 @@ nsPromiseConcatenation<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseConcatenation<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
int whichString;
|
||||
|
||||
|
@ -848,6 +801,7 @@ nsPromiseConcatenation<CharT>::GetReadableFragment( ReadableFragment& aFragment,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
nsPromiseConcatenation<CharT>::operator+( const basic_nsAReadableString<CharT>& rhs ) const
|
||||
{
|
||||
|
@ -875,11 +829,8 @@ class nsPromiseSubstring
|
|||
calls to |GetReadableFragment()|.
|
||||
*/
|
||||
{
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
typedef typename basic_nsAWritableString<CharT>::ReadableFragment ReadableFragment;
|
||||
|
||||
protected:
|
||||
virtual const CharT* GetReadableFragment( ReadableFragment&, FragmentRequest, PRUint32 ) const;
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
public:
|
||||
nsPromiseSubstring( const basic_nsAReadableString<CharT>& aString, PRUint32 aStartPos, PRUint32 aLength )
|
||||
|
@ -909,7 +860,7 @@ nsPromiseSubstring<CharT>::Length() const
|
|||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( ReadableFragment& aFragment, FragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
nsPromiseSubstring<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const
|
||||
{
|
||||
// Offset any request for a specific position (First, Last, At) by our
|
||||
// substrings startpos within the owning string
|
||||
|
@ -957,8 +908,8 @@ Compare( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
PRUint32 rLength = rhs.Length();
|
||||
PRUint32 lengthToCompare = NS_MIN(lLength, rLength);
|
||||
|
||||
basic_nsAReadableString<CharT>::ReadingIterator leftIter( lhs.BeginReading() );
|
||||
basic_nsAReadableString<CharT>::ReadingIterator rightIter( rhs.BeginReading() );
|
||||
nsReadingIterator<CharT> leftIter( lhs.BeginReading() );
|
||||
nsReadingIterator<CharT> rightIter( rhs.BeginReading() );
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -1025,6 +976,7 @@ Compare( const CharT* lhs, const basic_nsAReadableString<CharT>& rhs )
|
|||
*/
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1032,6 +984,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsAReadableStr
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1039,6 +992,7 @@ operator+( const basic_nsAReadableString<CharT>& lhs, const basic_nsLiteralStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableString<CharT>& rhs )
|
||||
{
|
||||
|
@ -1046,6 +1000,7 @@ operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsAReadableStrin
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
nsPromiseConcatenation<CharT>
|
||||
operator+( const basic_nsLiteralString<CharT>& lhs, const basic_nsLiteralString<CharT>& rhs )
|
||||
{
|
||||
|
|
|
@ -30,6 +30,158 @@
|
|||
#include "nsAReadableString.h"
|
||||
|
||||
|
||||
template <class CharT>
|
||||
struct nsWritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
nsWritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
|
||||
template <class CharT> class basic_nsAWritableString;
|
||||
|
||||
template <class CharT>
|
||||
class nsWritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
nsWritableFragment<CharT> mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
inline void normalize_forward();
|
||||
inline void normalize_backward();
|
||||
|
||||
nsWritingIterator( nsWritableFragment<CharT>& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// nsWritingIterator( const nsWritingIterator<CharT>& ); ...use default copy-constructor
|
||||
// nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator++( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>
|
||||
operator--( int )
|
||||
{
|
||||
nsWritingIterator<CharT> result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const nsWritableFragment<CharT>&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsWritingIterator<CharT>&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
This file defines the abstract interfaces |nsAWritableString| and
|
||||
|nsAWritableCString|.
|
||||
|
@ -45,204 +197,29 @@ class basic_nsAWritableString
|
|||
...
|
||||
*/
|
||||
{
|
||||
protected:
|
||||
typedef typename basic_nsAReadableString<CharT>::FragmentRequest FragmentRequest;
|
||||
|
||||
struct WritableFragment
|
||||
{
|
||||
CharT* mStart;
|
||||
CharT* mEnd;
|
||||
PRUint32 mFragmentIdentifier;
|
||||
|
||||
WritableFragment()
|
||||
: mStart(0), mEnd(0), mFragmentIdentifier(0)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
};
|
||||
// friend class nsWritingIterator<CharT>;
|
||||
|
||||
public:
|
||||
virtual CharT* GetWritableFragment( WritableFragment&, FragmentRequest, PRUint32 = 0 ) = 0;
|
||||
typedef nsWritingIterator<CharT> Iterator;
|
||||
|
||||
friend class WritingIterator;
|
||||
class WritingIterator
|
||||
: public bidirectional_iterator_tag
|
||||
{
|
||||
public:
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef CharT value_type;
|
||||
typedef CharT* pointer;
|
||||
typedef CharT& reference;
|
||||
typedef bidirectional_iterator_tag iterator_category;
|
||||
virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 = 0 ) = 0;
|
||||
|
||||
private:
|
||||
friend class basic_nsAWritableString<CharT>;
|
||||
|
||||
WritableFragment mFragment;
|
||||
CharT* mPosition;
|
||||
basic_nsAWritableString<CharT>* mOwningString;
|
||||
|
||||
void
|
||||
normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
void
|
||||
normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
WritingIterator( WritableFragment& aFragment,
|
||||
CharT* aStartingPosition,
|
||||
basic_nsAWritableString<CharT>& aOwningString )
|
||||
: mFragment(aFragment),
|
||||
mPosition(aStartingPosition),
|
||||
mOwningString(&aOwningString)
|
||||
{
|
||||
// nothing else to do here
|
||||
}
|
||||
|
||||
public:
|
||||
// WritingIterator( const WritingIterator& ); ...use default copy-constructor
|
||||
// WritingIterator& operator=( const WritingIterator& ); ...use default copy-assignment operator
|
||||
|
||||
|
||||
reference
|
||||
operator*() const
|
||||
{
|
||||
return *mPosition;
|
||||
}
|
||||
|
||||
pointer
|
||||
operator->() const
|
||||
{
|
||||
return mPosition;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator++()
|
||||
{
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator++( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
++mPosition;
|
||||
normalize_forward();
|
||||
return result;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator--()
|
||||
{
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator
|
||||
operator--( int )
|
||||
{
|
||||
WritingIterator result(*this);
|
||||
normalize_backward();
|
||||
--mPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
const WritableFragment&
|
||||
fragment() const
|
||||
{
|
||||
return mFragment;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_forward() const
|
||||
{
|
||||
return mFragment.mEnd - mPosition;
|
||||
}
|
||||
|
||||
difference_type
|
||||
size_backward() const
|
||||
{
|
||||
return mPosition - mFragment.mStart;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator+=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator-=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_forward());
|
||||
mPosition += one_hop;
|
||||
normalize_forward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
WritingIterator&
|
||||
operator-=( difference_type n )
|
||||
{
|
||||
if ( n < 0 )
|
||||
return operator+=(-n);
|
||||
|
||||
while ( n )
|
||||
{
|
||||
difference_type one_hop = NS_MIN(n, size_backward());
|
||||
mPosition -= one_hop;
|
||||
normalize_backward();
|
||||
n -= one_hop;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator==( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
PRBool
|
||||
operator!=( const WritingIterator& rhs ) const
|
||||
{
|
||||
return mPosition != rhs.mPosition;
|
||||
}
|
||||
};
|
||||
|
||||
typedef WritingIterator Iterator;
|
||||
|
||||
public:
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
BeginWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, aOffset);
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
basic_nsAWritableString<CharT>::WritingIterator
|
||||
nsWritingIterator<CharT>
|
||||
EndWriting( PRUint32 aOffset = 0 )
|
||||
{
|
||||
WritableFragment fragment;
|
||||
nsWritableFragment<CharT> fragment;
|
||||
CharT* startPos = GetWritableFragment(fragment, kFragmentAt, NS_MAX(0U, Length()-aOffset));
|
||||
return basic_nsAWritableString<CharT>::WritingIterator(fragment, startPos, *this);
|
||||
return nsWritingIterator<CharT>(fragment, startPos, *this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,12 +298,45 @@ class basic_nsAWritableString
|
|||
}
|
||||
};
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_forward()
|
||||
{
|
||||
if ( mPosition == mFragment.mEnd )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kNextFragment) )
|
||||
mPosition = mFragment.mStart;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
inline
|
||||
void
|
||||
nsWritingIterator<CharT>::normalize_backward()
|
||||
{
|
||||
if ( mPosition == mFragment.mStart )
|
||||
if ( mOwningString->GetWritableFragment(mFragment, kPrevFragment) )
|
||||
mPosition = mFragment.mEnd;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition == rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
inline
|
||||
PRBool
|
||||
operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
|
||||
{
|
||||
return lhs.mPosition != rhs.mPosition;
|
||||
}
|
||||
|
||||
template <class CharT>
|
||||
nsWritingIterator<CharT>
|
||||
copy_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
@ -346,10 +356,8 @@ copy_chunky( typename basic_nsAReadableString<CharT>::ReadingIterator first,
|
|||
}
|
||||
|
||||
template <class CharT>
|
||||
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 )
|
||||
nsWritingIterator<CharT>
|
||||
copy_backward_chunky( nsReadingIterator<CharT> first, nsReadingIterator<CharT> last, nsWritingIterator<CharT> result )
|
||||
{
|
||||
while ( first != last )
|
||||
{
|
||||
|
|
|
@ -35,8 +35,29 @@ class basic_nsSharedString
|
|||
...
|
||||
*/
|
||||
{
|
||||
private:
|
||||
~basic_nsSharedString() { }
|
||||
// You can't sub-class me, or make an instance of me on the stack
|
||||
|
||||
// operator delete
|
||||
|
||||
public:
|
||||
|
||||
virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
|
||||
|
||||
virtual
|
||||
PRUint32
|
||||
Length() const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
basic_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
mLength = aReadable.Length();
|
||||
copy(aReadable.BeginReading(), aReadable.EndReading(), mData+0);
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
AddRef() const
|
||||
{
|
||||
|
@ -53,10 +74,31 @@ class basic_nsSharedString
|
|||
}
|
||||
|
||||
private:
|
||||
mutable nsrefcnt mRefCount;
|
||||
mutable nsrefcnt mRefCount;
|
||||
size_t mLength;
|
||||
CharT mData[1];
|
||||
};
|
||||
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsStdStringWrapper<CharT>)
|
||||
NS_DEF_STRING_COMPARISONS(basic_nsSharedString<CharT>)
|
||||
|
||||
template <class CharT>
|
||||
const CharT*
|
||||
basic_nsSharedString<CharT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const
|
||||
{
|
||||
switch ( aRequest )
|
||||
{
|
||||
case kFirstFragment:
|
||||
case kLastFragment:
|
||||
case kFragmentAt:
|
||||
aFragment.mEnd = (aFragment.mStart = mData) + mLength;
|
||||
return aFragment.mStart + anOffset;
|
||||
|
||||
case kPrevFragment:
|
||||
case kNextFragment:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -71,12 +113,17 @@ class nsSharedStringPtr
|
|||
};
|
||||
|
||||
|
||||
template <class CharT>
|
||||
basic_nsSharedString<CharT>*
|
||||
new_nsSharedString( const basic_nsAReadableString<CharT>& aReadable )
|
||||
{
|
||||
void* in_buffer = operator new( sizeof(basic_nsSharedString<CharT>) + aReadable.Length()*sizeof(CharT) );
|
||||
return new (in_buffer) basic_nsSharedString<CharT>(aReadable);
|
||||
}
|
||||
|
||||
|
||||
typedef basic_nsSharedString<PRUnichar> nsSharedString;
|
||||
typedef basic_nsSharedStringPtr<PRUnichar> nsSharedStringPtr;
|
||||
|
||||
typedef basic_nsSharedString<char> nsSharedCString;
|
||||
typedef basic_nsSharedStringPtr<char> nsSharedCStringPtr;
|
||||
|
||||
|
||||
#endif // !defined(_nsSharedString_h__)
|
||||
|
|
Загрузка…
Ссылка в новой задаче