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:
scc%netscape.com 2000-03-24 22:06:57 +00:00
Родитель 9c10daa841
Коммит 402f35dfcd
21 изменённых файлов: 1461 добавлений и 1434 удалений

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

@ -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__)