From 3ea67f16a24e49380f94cfec8b42d33517a76123 Mon Sep 17 00:00:00 2001 From: "scc%mozilla.org" Date: Tue, 6 Mar 2001 16:07:04 +0000 Subject: [PATCH] STRING_081_BRANCH work ... none of this is on the trunk git-svn-id: svn://10.0.0.236/branches/STRING_081_BRANCH@88662 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/string/macbuild/string.mcp | Bin 70851 -> 74691 bytes mozilla/string/obsolete/nsString.cpp | 4 + mozilla/string/obsolete/nsString.h | 13 +- mozilla/string/obsolete/nsString2.h | 14 +- mozilla/string/public/MANIFEST | 10 +- mozilla/string/public/Makefile.in | 38 +- mozilla/string/public/makefile.win | 10 +- mozilla/string/public/nsAReadableString.h | 1110 +---------------- mozilla/string/public/nsAString.h | 724 ++++++++++- mozilla/string/public/nsAWritableString.h | 583 +-------- mozilla/string/public/nsBufferHandleUtils.h | 34 +- mozilla/string/public/nsCharTraits.h | 12 +- mozilla/string/public/nsDependentString.h | 20 +- mozilla/string/public/nsFragmentedString.h | 6 +- mozilla/string/public/nsLiteralString.h | 27 +- mozilla/string/public/nsLocalString.h | 20 +- mozilla/string/public/nsSharedBufferList.h | 13 +- mozilla/string/public/nsSlidingString.h | 4 +- mozilla/string/public/nsStringIterator.h | 57 +- mozilla/string/src/Makefile.in | 2 + mozilla/string/src/makefile.win | 2 + mozilla/string/src/nsReadableUtils.cpp | 45 +- mozilla/xpcom/string/macbuild/string.mcp | Bin 70851 -> 74691 bytes mozilla/xpcom/string/obsolete/nsString.cpp | 4 + mozilla/xpcom/string/obsolete/nsString.h | 13 +- mozilla/xpcom/string/obsolete/nsString2.h | 14 +- mozilla/xpcom/string/public/MANIFEST | 10 +- mozilla/xpcom/string/public/Makefile.in | 38 +- mozilla/xpcom/string/public/makefile.win | 10 +- .../xpcom/string/public/nsAReadableString.h | 1110 +---------------- mozilla/xpcom/string/public/nsAString.h | 724 ++++++++++- .../xpcom/string/public/nsAWritableString.h | 583 +-------- .../xpcom/string/public/nsBufferHandleUtils.h | 34 +- mozilla/xpcom/string/public/nsCharTraits.h | 12 +- .../xpcom/string/public/nsDependentString.h | 20 +- .../xpcom/string/public/nsFragmentedString.h | 6 +- mozilla/xpcom/string/public/nsLiteralString.h | 27 +- mozilla/xpcom/string/public/nsLocalString.h | 20 +- .../xpcom/string/public/nsSharedBufferList.h | 13 +- mozilla/xpcom/string/public/nsSlidingString.h | 4 +- .../xpcom/string/public/nsStringIterator.h | 57 +- mozilla/xpcom/string/src/Makefile.in | 2 + mozilla/xpcom/string/src/makefile.win | 2 + mozilla/xpcom/string/src/nsReadableUtils.cpp | 45 +- 44 files changed, 1802 insertions(+), 3694 deletions(-) diff --git a/mozilla/string/macbuild/string.mcp b/mozilla/string/macbuild/string.mcp index 17264396504b24ec79de465535ad9eab3e98d369..8eae5fa1440e20a82477625edcc76e199e555bf4 100644 GIT binary patch delta 2530 zcmd^>-%lJ>6vyu@v#{*a@?+&kwY5}WfBzJdwx%Y~Qd&w|m*qz(VA>Ultbtv!yV^vX zEFleBjWNZGA$_ovK9~}SqDzVoKA4c$RDzGxAP9jl zcpMCZesBtOfTzHD@H7|zhe0!V0z^R%=;o`Xox9G#I|I&wKCW6X@g-~BK6+M*f(xK$ z2yKD`!u&gHNt{Y4?VpLszGUX5Ol786>91H$}X z*&)7Svsf_G0i66}+lj*m3T|;~ckZKS({kD{gqSOrbMlt5wkCSRi&*{>nOKyi_P)+0 zZ!2sywf9vvxkyfau`H%$)!Ud$RmM>7;6nFe(7mi%xJ>;PmMVs!{)P+f28P*+OP_F= zc^@p*62nZ@qTRqSAHjuo0>eyorrp3WU%+LM*))-a8JcN5$Tuo~;33=95Z+T11J(uH zzyrL%2mBxaf`I0R`PJN!{4IOA!k0?w_^+j9rBq}e@Xxe%v0Wt=*E}I&;m$pX|EwU+;V}-yEF^ zm3(^YEyiB@CjZgY9aHw<_KwrX(I`%7twMknqZJD&Yq}?rTxwHXkAC)#JZAjV* zX)86GWiA=;Nb8oiN?NL0?{bpR)D0XOjE@8`NJ#lgjcyLfQ6 z!AyrWDm)jwZsED%^$5=cuUB}~o_)fjCOs!S`q1?Yj}Fjz;n9a~KzQ`I8x$UWLx%Ff z>%Z^V{h78d9?4w}A+diYikKJpfFA@v5YXH(-;69#K5(~23%IMbKNVg3Zr}l4-~)aT z06{==k;au<|Bnu}JkX)xe>$~9JD*Lwc6y-}o7`fWeG|qQH9z(9*h>9OMCCV+?#chS zbxpBg4;`3+_Pc%{fAhrp=QqDrjhsK<)Q=2#T5jZNiIJyeMV^)td0IZ?X~~eMWkQ~o26;88w11Y6M}_2*Rilgi#|1qec)$jUbE~K^QfHFlq#0)CfXP@r9zf zYOAtcT=gz?^}{)vP4Sp)p}B)L<&EOcI`I!=a&5z=L`}uH3YxIiuv;lLH7jO2V^%hv znHWP9J)w`c@jpbNczS2t)<1WlLa8afLH|>h*IubmtfsT&g^M63eatTvEK(4+jbcUx U7LUUg#5d=mm)E|kQnr=90jo^gTmS$7 delta 963 zcmX?noaOLJ7UAUl{2T@b24)5ZMhyl=j@Jx~TpNXRI9YXpf_jrDaEeQM0a>0vYzxHx zKx_%b#z1T``3|Qyt1pn{H`#=%d}4sXx4QufcAmxRGxf*+uc$g$WefbfV2RavLNLkQy>7r0jp&JiUP6fWCtD>)c_zT0mxs$ zz`y}g9l(&EXXBiaSQKK%n^zoAl%JbfoVs}>Pa?}i_k)v93qGDK(B3hbeSXg7MZ)}y z6J5$StBY>2*u2%Rm1$zYt;tq_EfZZzHyZ~v8L*$6`{V!rtL>ZjG;L!N6mawOaRu7S z52d*#%bgc@RD$x9p|lE=R)EsnP?`ry%Ry;U?vV)DGRwUcdH%>-c%htXgUSfYD?B!|mjaX2fIgBNNr+`W5O?0!iDh=$`uixx4g zTD1z!2g*%!EZnp(LWTWgu)+WTFWEO=6#LCMIqJ9=MBq<7M4;#-SO6G2h7f_S(@+(& z+<*c<7`F?vGTvaB7@)a%!KK5x&|uiO9T?FdQLX8sl8hhNxD9{?bWG=#V$@>dX`F5@ z#n{KzasiY=x1W|`3}RvvS_e|FU0IfqlgXIj?0g0WR)*Y?0%%47%7H-}Pzyr?P`nsO zgOV>4@UTpemuD1XYYzYl)NHSoXXIk?V--d+1eAWEVD5h)17--4I1k8;0zktvfi#l% Pym}zNX8UDD#t)1DW+?Kp diff --git a/mozilla/string/obsolete/nsString.cpp b/mozilla/string/obsolete/nsString.cpp index 057ffcea00c..364766afd74 100644 --- a/mozilla/string/obsolete/nsString.cpp +++ b/mozilla/string/obsolete/nsString.cpp @@ -832,6 +832,7 @@ void nsCString::AssignWithConversion(PRUnichar aChar) { AppendWithConversion(aChar); } +#if 0 void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable ) { if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) ) @@ -839,6 +840,7 @@ void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable ) else nsAWritableCString::do_AppendFromReadable(aReadable); } +#endif /** @@ -962,6 +964,7 @@ void nsCString::InsertWithConversion(PRUnichar aChar,PRUint32 anOffset){ StrInsert(*this,anOffset,temp,0,1); } +#if 0 void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUint32 atPosition ) { if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) ) @@ -969,6 +972,7 @@ void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUi else nsAWritableCString::do_InsertFromReadable(aReadable, atPosition); } +#endif diff --git a/mozilla/string/obsolete/nsString.h b/mozilla/string/obsolete/nsString.h index 5c90e1e12f3..eb9928fa893 100644 --- a/mozilla/string/obsolete/nsString.h +++ b/mozilla/string/obsolete/nsString.h @@ -57,11 +57,10 @@ class NS_COM nsSubsumeCStr; class NS_COM nsCString : - public nsAWritableCString, + public nsAFlatCString, public nsStr { protected: - virtual const void* Implementation() const { return "nsCString"; } virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); @@ -306,7 +305,7 @@ public: nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; } nsCString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsCString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsCString& operator=( char aChar ) { Assign(aChar); return *this; } @@ -333,12 +332,14 @@ public: void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16 void AppendFloat( double aFloat ); - virtual void do_AppendFromReadable( const nsAReadableCString& ); void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset); // Why no |InsertWithConversion(PRUnichar*)|? +#if 0 + virtual void do_AppendFromReadable( const nsAReadableCString& ); virtual void do_InsertFromReadable( const nsAReadableCString&, PRUint32 ); +#endif /********************************************************************** @@ -490,7 +491,7 @@ public: void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED public: nsCAutoString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +// nsCAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; } @@ -574,7 +575,7 @@ public: nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); return *this; } nsSubsumeCStr& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeCStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsSubsumeCStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsSubsumeCStr& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsSubsumeCStr& operator=( char aChar ) { Assign(aChar); return *this; } private: diff --git a/mozilla/string/obsolete/nsString2.h b/mozilla/string/obsolete/nsString2.h index be4a9698aaa..798c13802b1 100644 --- a/mozilla/string/obsolete/nsString2.h +++ b/mozilla/string/obsolete/nsString2.h @@ -55,6 +55,10 @@ #include "nsAWritableString.h" #include "nsLiteralString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" +#endif + #ifdef STANDALONE_MI_STRING_TESTS class nsAReadableString { public: virtual ~nsAReadableString() { } }; class nsAWritableString : public nsAReadableString { public: virtual ~nsAWritableString() { } }; @@ -69,7 +73,7 @@ class nsISizeOfHandler; class NS_COM nsSubsumeStr; class NS_COM nsString : - public nsAWritableString, + public nsAFlatString, public nsStr { protected: @@ -343,7 +347,7 @@ public: nsString& operator=( const nsString& aString ) { Assign(aString); return *this; } nsString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } @@ -563,7 +567,7 @@ public: void operator=( char ); // NOT TO BE IMPLEMENTED public: nsAutoString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +// nsAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsAutoString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsAutoString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } @@ -596,7 +600,7 @@ class NS_COM NS_ConvertASCIItoUCS2 return GetUnicode(); } - operator nsLiteralString() const + operator const nsLiteralString() const { return nsLiteralString(mUStr, mLength); } @@ -685,7 +689,7 @@ public: nsSubsumeStr& operator=( const nsSubsumeStr& aReadable ) { Assign(aReadable); return *this; } nsSubsumeStr& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsSubsumeStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsSubsumeStr& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsSubsumeStr& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } private: diff --git a/mozilla/string/public/MANIFEST b/mozilla/string/public/MANIFEST index 6742f976d7e..cb9a692fd76 100644 --- a/mozilla/string/public/MANIFEST +++ b/mozilla/string/public/MANIFEST @@ -21,21 +21,29 @@ # +nsAFlatString.h nsAlgorithm.h -nsAString.h +nsAPromiseString.h nsAReadableString.h +nsAString.h nsAWritableString.h nsBufferHandle.h nsBufferHandleUtils.h nsCharTraits.h +nsCommonString.h nsFragmentedString.h nsLiteralString.h nsLocalString.h nsPrintfCString.h nsPrivateSharableString.h +nsPromiseConcatenation.h +nsPromiseFlatString.h +nsPromiseSubstring.h nsReadableUtils.h nsSharedBufferList.h nsSlidingString.h nsStringFragment.h +nsStringFwd.h nsStringIterator.h nsStringIteratorUtils.h +nsStringTraits.h diff --git a/mozilla/string/public/Makefile.in b/mozilla/string/public/Makefile.in index 394a6c8043b..8d13477a3b6 100644 --- a/mozilla/string/public/Makefile.in +++ b/mozilla/string/public/Makefile.in @@ -31,24 +31,32 @@ include $(DEPTH)/config/autoconf.mk MODULE = string EXPORTS = \ + nsAFlatString.h \ nsAlgorithm.h \ + nsAPromiseString.h \ + nsAReadableString.h \ nsAString.h \ - nsBufferHandle.h \ - nsBufferHandleUtils.h \ - nsPrivateSharableString.h \ + nsAWritableString.h \ + nsBufferHandle.h \ + nsBufferHandleUtils.h \ nsCharTraits.h \ - nsAReadableString.h \ - nsAWritableString.h \ - nsReadableUtils.h \ - nsSharedBufferList.h \ - nsSlidingString.h \ - nsFragmentedString.h \ - nsLiteralString.h \ - nsLocalString.h \ - nsPrintfCString.h \ - nsStringFragment.h \ - nsStringIterator.h \ - nsStringIteratorUtils.h \ + nsCommonString.h \ + nsFragmentedString.h \ + nsLiteralString.h \ + nsLocalString.h \ + nsPrintfCString.h \ + nsPrivateSharableString.h \ + nsPromiseConcatenation.h \ + nsPromiseFlatString.h \ + nsPromiseSubstring.h \ + nsReadableUtils.h \ + nsSharedBufferList.h \ + nsSlidingString.h \ + nsStringFragment.h \ + nsStringFwd.h \ + nsStringIterator.h \ + nsStringIteratorUtils.h \ + nsStringTraits.h \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/string/public/makefile.win b/mozilla/string/public/makefile.win index ae1d7a2e561..37f2222ac6c 100644 --- a/mozilla/string/public/makefile.win +++ b/mozilla/string/public/makefile.win @@ -25,24 +25,32 @@ DEPTH=..\.. EXPORTS = \ + nsAFlatString.h \ nsAlgorithm.h \ - nsAString.h \ + nsAPromiseString.h \ nsAReadableString.h \ + nsAString.h \ nsAWritableString.h \ nsBufferHandle.h \ nsBufferHandleUtils.h \ nsCharTraits.h \ + nsCommonString.h \ nsFragmentedString.h \ nsLiteralString.h \ nsLocalString.h \ nsPrintfCString.h \ nsPrivateSharableString.h \ + nsPromiseConcatenation.h \ + nsPromiseFlatString.h \ + nsPromiseSubstring.h \ nsReadableUtils.h \ nsSharedBufferList.h \ nsSlidingString.h \ nsStringFragment.h \ + nsStringFwd.h \ nsStringIterator.h \ nsStringIteratorUtils.h \ + nsStringTraits.h \ $(NULL) include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/string/public/nsAReadableString.h b/mozilla/string/public/nsAReadableString.h index 3b76ccce3f5..5133bc7d35b 100644 --- a/mozilla/string/public/nsAReadableString.h +++ b/mozilla/string/public/nsAReadableString.h @@ -24,1111 +24,25 @@ #ifndef nsAReadableString_h___ #define nsAReadableString_h___ -#ifndef nscore_h___ -#include "nscore.h" - // for |PRUnichar| +#ifndef nsAString_h___ +#include "nsAString.h" #endif -#ifndef nsCharTraits_h___ -#include "nsCharTraits.h" +typedef const nsAString nsAReadableString; +typedef const nsACString nsAReadableCString; + // what about the |const|? + +#ifndef nsPromiseSubstring_h___ +#include "nsPromiseSubstring.h" #endif -#ifndef nsPrivateSharableString_h___ -#include "nsPrivateSharableString.h" +#ifndef nsPromiseConcatenation_h___ +#include "nsPromiseConcatenation.h" #endif -#ifndef nsStringIterator_h___ -#include "nsStringIterator.h" +#ifndef nsPromiseFlatString_h___ +#include "nsPromiseFlatString.h" #endif -#include "nsMemory.h" - -/* - This file defines the abstract interfaces |nsAReadableString| and - |nsAReadableCString| (the 'A' is for 'abstract', as opposed to the 'I' in - [XP]COM interface names). - - These types are intended to be as source compatible as possible with the original - definitions of |const nsString&| and |const nsCString&|, respectively. In otherwords, - these interfaces provide only non-mutating access to the underlying strings. We - split the these interfaces out from the mutating parts (see - "nsAWritableString.h") because tests showed that we could exploit specialized - implementations in some areas; we need an abstract interface to bring the whole - family of strings together. - - |nsAReadableString| is a string of |PRUnichar|s. |nsAReadableCString| (note the - 'C') is a string of |char|s. -*/ - -template class basic_nsAReadableString; - -template class basic_nsAWritableString; - // ...because we sometimes use them as `out' params - -#ifdef _MSC_VER - // Under VC++, at the highest warning level, we are overwhelmed with warnings - // about a possible error when |operator->()| is used against something that - // doesn't have members, e.g., a |PRUnichar|. This is to be expected with - // templates, so we disable the warning. - #pragma warning( disable: 4284 ) -#endif - - - // - // nsAReadable[C]String - // - -template -class basic_nsAReadableString - : public nsPrivateSharableString - { - public: -// typedef CharT char_type; -// typedef PRUint32 size_type; -// typedef PRUint32 index_type; - - typedef nsReadingIterator const_iterator; - - - // basic_nsAReadableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAReadableString( const basic_nsAReadableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - private: - // NOT TO BE IMPLEMENTED - void operator=( const basic_nsAReadableString& ); // but assignment is _not_ OK (we're immutable) so make it impossible - - public: - virtual ~basic_nsAReadableString() { } - // ...yes, I expect to be sub-classed. - - nsReadingIterator& BeginReading( nsReadingIterator& ) const; - nsReadingIterator& EndReading( nsReadingIterator& ) const; - - virtual PRUint32 Length() const = 0; - PRBool IsEmpty() const; - - /** - * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. - * These signatures should be pushed down into interfaces that guarantee flat allocation. - * Clients at _this_ level should always use iterators. - */ - CharT CharAt( PRUint32 ) const; - CharT operator[]( PRUint32 ) const; - CharT First() const; - CharT Last() const; - - PRUint32 CountChar( CharT ) const; - - - /* - |Left|, |Mid|, and |Right| are annoying signatures that seem better almost - any _other_ way than they are now. Consider these alternatives - - aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| - aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| - Left(aReadable, 17, aWritable); // ...a global function that does the assignment - - as opposed to the current signature - - aReadable.Left(aWritable, 17); // ...a member function that does the assignment - - or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality - - aWritable = Substring(aReadable, 0, 17); - */ - - PRUint32 Left( basic_nsAWritableString&, PRUint32 ) const; - PRUint32 Mid( basic_nsAWritableString&, PRUint32, PRUint32 ) const; - PRUint32 Right( basic_nsAWritableString&, PRUint32 ) const; - - // Find( ... ) const; - PRInt32 FindChar( CharT, PRUint32 aOffset = 0 ) const; - // FindCharInSet( ... ) const; - // RFind( ... ) const; - // RFindChar( ... ) const; - // RFindCharInSet( ... ) const; - - - int Compare( const basic_nsAReadableString& rhs ) const; - int Compare( const CharT* ) const; -// int Compare( const CharT*, PRUint32 ) const; -// int Compare( CharT ) const; - - // |Equals()| is a synonym for |Compare()| - PRBool Equals( const basic_nsAReadableString& rhs ) const; - PRBool Equals( const CharT* ) const; -// PRBool Equals( const CharT*, PRUint32 ) const; -// PRBool Equals( CharT ) const; - - // Comparison operators are all synonyms for |Compare()| - PRBool operator!=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)!=0; } - PRBool operator< ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)< 0; } - PRBool operator<=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)<=0; } - PRBool operator==( const basic_nsAReadableString& rhs ) const { return Compare(rhs)==0; } - PRBool operator>=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)>=0; } - PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } - - - /* - Shouldn't be implemented because they're i18n sensitive. - Let's leave them in |nsString| for now. - */ - - // ToLowerCase - // ToUpperCase - // EqualsIgnoreCase - // IsASCII - // IsSpace - // IsAlpha - // IsDigit - // ToFloat - // ToInteger - - // char* ToNewCString() const; - // char* ToNewUTF8String() const; - // PRUnichar* ToNewUnicode() const; - // char* ToCString( char*, PRUint32, PRUint32 ) const; - - - /* - Shouldn't be implemented because it's wrong duplication. - Let's leave it in |nsString| for now. - */ - - // nsString* ToNewString() const; - // NO! The right way to say this is |new nsString( fromAReadableString )| - - - /* - Shouldn't be implemented because they're not generally applicable. - Let's leave them in |nsString| for now. - */ - - // IsOrdered - // BinarySearch - - // protected: - virtual const void* Implementation() const; - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return &aString == this; } -// virtual PRBool PromisesExactly( const basic_nsAReadableString& aString ) const { return false; } - - private: - // NOT TO BE IMPLEMENTED - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - PRUint32 CountChar( incompatible_char_type ) const; -// in Compare( incompatible_char_type ) const; -// PRBool Equals( incompatible_char_type ) const; - }; - - /* - The following macro defines a cast that helps us solve type-unification error problems on compilers - with poor template support. String clients probably _never_ need to use it. String implementors - sometimes will. - */ - -#ifdef NEED_CPP_TEMPLATE_CAST_TO_BASE -#define NS_READABLE_CAST(CharT, expr) (NS_STATIC_CAST(const basic_nsAReadableString&, (expr))) -#else -#define NS_READABLE_CAST(CharT, expr) (expr) -#endif - - /** - * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? - */ -template -inline -nsReadingIterator& -basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - -template -inline -nsReadingIterator& -basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - -template -inline -PRBool -basic_nsAReadableString::IsEmpty() const - { - return Length() == 0; - } - -template -inline -PRBool -basic_nsAReadableString::Equals( const basic_nsAReadableString& rhs ) const - { - return Length() == rhs.Length() && Compare(rhs) == 0; - } - -template -inline -PRBool -operator==( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() == rhs.get(); - } - -template -inline -PRBool -operator!=( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() != rhs.get(); - } - - -#define NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _CharT* rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), rhs) comp 0); \ - } - -#define NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _CharT* lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(lhs, NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - template NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - template NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_3_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - -#define NS_DEF_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - - -NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsAReadableString, CharT) - - - -template -const void* -basic_nsAReadableString::Implementation() const - { - return 0; - } - - - -template -CharT -basic_nsAReadableString::CharAt( PRUint32 aIndex ) const - { - NS_ASSERTION(aIndex iter; - return *(BeginReading(iter).advance(PRInt32(aIndex))); - } - -template -inline -CharT -basic_nsAReadableString::operator[]( PRUint32 aIndex ) const - { - return CharAt(aIndex); - } - -template -CharT -basic_nsAReadableString::First() const - { - NS_ASSERTION(Length()>0, "|First()| on an empty string"); - - nsReadingIterator iter; - return *BeginReading(iter); - } - -template -CharT -basic_nsAReadableString::Last() const - { - NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - - nsReadingIterator iter; - EndReading(iter); - - if ( !IsEmpty() ) - iter.advance(-1); - - return *iter; // Note: this has undefined results if |IsEmpty()| - } - -template -PRUint32 -basic_nsAReadableString::CountChar( CharT c ) const - { -#if 0 - nsReadingIterator countBegin, countEnd; - return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); -#else - PRUint32 result = 0; - PRUint32 lengthToExamine = Length(); - - nsReadingIterator iter; - for ( BeginReading(iter); ; ) - { - PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - const CharT* fromBegin = iter.get(); - result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); - if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) - return result; - iter.advance(lengthToExamineInThisFragment); - } - // never reached; quiets warnings - return 0; -#endif - } - -#if 0 - // had to move these definitions into "nsAWritableString.h" -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } -#endif - -template -PRInt32 -basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const - { - nsReadingIterator iter, done_searching; - BeginReading(iter).advance( PRInt32(aOffset) ); - EndReading(done_searching); - - PRUint32 lengthSearched = 0; - while ( iter != done_searching ) - { - PRInt32 fragmentLength = iter.size_forward(); - const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); - if ( charFoundAt ) - return lengthSearched + (charFoundAt-iter.get()) + aOffset; - - lengthSearched += fragmentLength; - iter.advance(fragmentLength); - } - - return -1; - } - - - - - - - - -#if 0 -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs, PRUint32 rhs_length ) const - { - return Compare(literal_string(rhs, rhs_length)) == 0; - } -#endif - -#if 0 -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs, PRUint32 rhs_length ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, literal_string(rhs, rhs_length))); - } -#endif - - - - // - // nsPromiseConcatenation - // - -template class nsPromiseReadable : public basic_nsAReadableString { }; - -template -class nsPromiseConcatenation - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS - - Instances of this class only exist as anonymous temporary results from |operator+()|. - This is the machinery that makes string concatenation efficient. No allocations or - character copies are required unless and until a final assignment is made. It works - its magic by overriding and forwarding calls to |GetReadableFragment()|. - - Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|. - - no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33| - - left to right evaluation is required ... do not use parentheses to override this - - In practice, neither of these is onerous. Parentheses do not change the semantics of the - concatenation, only the order in which the result is assembled ... so there's no reason - for a user to need to control it. Too many strings summed together can easily be worked - around with an intermediate assignment. I wouldn't have the parentheses limitation if I - assigned the identifier mask starting at the top, the first time anybody called - |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - enum { kLeftString, kRightString }; - - int - GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const - { - return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString; - } - - int - SetLeftStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask); - return kLeftString; - } - - int - SetRightStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask); - return kRightString; - } - - public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) - : mFragmentIdentifierMask(aMask) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - nsPromiseConcatenation( const nsPromiseConcatenation& aLeftString, const basic_nsAReadableString& aRightString ) - : mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - // nsPromiseConcatenation( const nsPromiseConcatenation& ); // auto-generated copy-constructor should be OK - // ~nsPromiseConcatenation(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseConcatenation& ); // we're immutable, you can't assign into a concatenation - - public: - - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& ) const; -// virtual PRBool PromisesExactly( const basic_nsAReadableString& ) const; - -// nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; - - PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; } - - private: - void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED - // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| - // which would break the algorithm for distributing bits in the fragment identifier - - private: - const basic_nsAReadableString* mStrings[2]; - PRUint32 mFragmentIdentifierMask; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseConcatenation, CharT) - -template -PRUint32 -nsPromiseConcatenation::Length() const - { - return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); - } - -template -PRBool -nsPromiseConcatenation::Promises( const basic_nsAReadableString& aString ) const - { - return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString); - } - -#if 0 -PRBool -nsPromiseConcatenation::PromisesExactly( const basic_nsAReadableString& aString ) const - { - // Not really like this, test for the empty string, etc - return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString; - } -#endif - -template -const CharT* -nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - int whichString; - - // based on the request, pick which string we will forward the |GetReadableFragment()| call into - - switch ( aRequest ) - { - case kPrevFragment: - case kNextFragment: - whichString = GetCurrentStringFromFragment(aFragment); - break; - - case kFirstFragment: - whichString = SetLeftStringInFragment(aFragment); - break; - - case kLastFragment: - whichString = SetRightStringInFragment(aFragment); - break; - - case kFragmentAt: - PRUint32 leftLength = mStrings[kLeftString]->Length(); - if ( aPosition < leftLength ) - whichString = SetLeftStringInFragment(aFragment); - else - { - whichString = SetRightStringInFragment(aFragment); - aPosition -= leftLength; - } - break; - - } - - const CharT* result; - PRBool done; - do - { - done = PR_TRUE; - result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition); - - if ( !result ) - { - done = PR_FALSE; - if ( aRequest == kNextFragment && whichString == kLeftString ) - { - aRequest = kFirstFragment; - whichString = SetRightStringInFragment(aFragment); - } - else if ( aRequest == kPrevFragment && whichString == kRightString ) - { - aRequest = kLastFragment; - whichString = SetLeftStringInFragment(aFragment); - } - else - done = PR_TRUE; - } - } - while ( !done ); - return result; - } - -#if 0 -template -inline -nsPromiseConcatenation -nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const - { - return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); - } -#endif - - - - - - // - // nsPromiseSubstring - // - -template -class nsPromiseSubstring - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS (mostly) - - ...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous - temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only - holds a pointer, no string data of its own. It does its magic by overriding and forwarding - calls to |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - public: - nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsPromiseSubstring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - : mString(aStart.string()) - { - nsReadingIterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } - - // nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK - // ~nsPromiseSubstring(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring - - public: - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return mString.Promises(aString); } - - private: - const basic_nsAReadableString& mString; - PRUint32 mStartPos; - PRUint32 mLength; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseSubstring, CharT) - -template -PRUint32 -nsPromiseSubstring::Length() const - { - return mLength; - } - -template -const CharT* -nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - // Offset any request for a specific position (First, Last, At) by our - // substrings startpos within the owning string - - if ( aRequest == kFirstFragment ) - { - aPosition = mStartPos; - aRequest = kFragmentAt; - } - else if ( aRequest == kLastFragment ) - { - aPosition = mStartPos + mLength; - aRequest = kFragmentAt; - } - else if ( aRequest == kFragmentAt ) - aPosition += mStartPos; - - // requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing - - const CharT* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition); - - // If |GetReadableFragment| returns |0|, then we are off the string, the contents of the - // fragment are garbage. - - // Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null - if ( position_ptr ) - { - // if there's more physical data in the returned fragment than I logically have left... - size_t logical_size_backward = aPosition - mStartPos; - if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward ) - aFragment.mStart = position_ptr - logical_size_backward; - - size_t logical_size_forward = mLength - logical_size_backward; - if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward ) - aFragment.mEnd = position_ptr + logical_size_forward; - } - - return position_ptr; - } - - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - #define NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T) \ - template \ - inline \ - nsPromiseConcatenation \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation(lhs, rhs); \ - } - - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring, nsPromiseSubstring) - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation, nsPromiseSubstring) - -#endif // NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - - // - // Global functions - // - -template -inline -PRBool -SameImplementation( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - const void* imp_tag = lhs.Implementation(); - return imp_tag && (imp_tag==rhs.Implementation()); - } - -inline -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) - { - return nsPromiseSubstring(aString, aStartPos, aSubstringLength); - } - -inline -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) - { - return nsPromiseSubstring(aString, aStartPos, aSubstringLength); - } - -inline -nsPromiseSubstring -Substring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return nsPromiseSubstring(aStart, aEnd); - } - -inline -nsPromiseSubstring -Substring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return nsPromiseSubstring(aStart, aEnd); - } - -template -int -Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - if ( &lhs == &rhs ) - return 0; - - PRUint32 lLength = lhs.Length(); - PRUint32 rLength = rhs.Length(); - PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - - nsReadingIterator leftIter, rightIter; - lhs.BeginReading(leftIter); - rhs.BeginReading(rightIter); - - int result; - - for (;;) - { - PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) ); - - if ( lengthAvailable > lengthToCompare ) - lengthAvailable = lengthToCompare; - - // Note: |result| should be declared in this |if| expression, but some compilers don't like that - if ( (result = nsCharTraits::compare(leftIter.get(), rightIter.get(), lengthAvailable)) != 0 ) - return result; - - if ( !(lengthToCompare -= lengthAvailable) ) - break; - - leftIter.advance( PRInt32(lengthAvailable) ); - rightIter.advance( PRInt32(lengthAvailable) ); - } - - if ( lLength < rLength ) - return -1; - else if ( rLength < lLength ) - return 1; - else - return 0; - } - -template -inline -int -Compare( const basic_nsAReadableString& lhs, const CharT* rhs ) - { - return Compare(lhs, NS_READABLE_CAST(CharT, literal_string(rhs))); - } - -template -inline -int -Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) - { - return Compare(NS_READABLE_CAST(CharT, literal_string(lhs)), rhs); - } - -// XXX Note that these are located here because some compilers are -// sensitive to the ordering of declarations with regard to templates. -template -inline -int -basic_nsAReadableString::Compare( const basic_nsAReadableString& rhs ) const - { - return ::Compare(*this, rhs); - } - -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs ) const - { - return Compare(literal_string(rhs)) == 0; - } - -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, literal_string(rhs))); - } - - - - /* - How shall we provide |operator+()|? - - What would it return? It has to return a stack based object, because the client will - not be given an opportunity to handle memory management in an expression like - - myWritableString = stringA + stringB + stringC; - - ...so the `obvious' answer of returning a new |nsSharedString| is no good. We could - return an |nsString|, if that name were in scope here, though there's no telling what the client - will really want to do with the result. What might be better, though, - is to return a `promise' to concatenate some strings... - - By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle - assignment and other interesting uses within writable strings, plus we drastically reduce - the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings - in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work - to implement the virtual functions of readables. - */ - -template -inline -nsPromiseConcatenation -operator+( const nsPromiseConcatenation& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1); - } - -template -inline -nsPromiseConcatenation -operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs); - } - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - #define NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - inline \ - nsPromiseConcatenation<_CharT> \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation<_CharT>(lhs, rhs); \ - } - - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring<_CharT>, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, nsPromiseSubstring<_CharT>, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation<_CharT>, _StringT, _CharT) - - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String2T, _String1T, _CharT) - -#else - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) -#endif - - -#define kDefaultFlatStringSize 64 - -template -class basic_nsPromiseFlatString - : public basic_nsAReadableString - { - public: - explicit basic_nsPromiseFlatString( const basic_nsAReadableString& ); - - virtual - ~basic_nsPromiseFlatString( ) - { - if (mOwnsBuffer) - nsMemory::Free((void*)mBuffer); - } - - virtual PRUint32 Length() const { return mLength; } - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const; - - const CharT* get() const { return mBuffer; } - operator const CharT*() const { return get(); } // to be deprecated, prefer |get()| - - protected: - PRUint32 mLength; - const CharT* mBuffer; - PRBool mOwnsBuffer; - CharT mInlineBuffer[kDefaultFlatStringSize]; - }; - -template -basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsAReadableString& aString ) - : mLength(aString.Length()), - mOwnsBuffer(PR_FALSE) - { - typedef nsReadingIterator iterator; - - iterator start; - iterator end; - - aString.BeginReading(start); - aString.EndReading(end); - - // First count the number of buffers - PRInt32 buffer_count = 0; - while ( start != end ) - { - buffer_count++; - start.advance(start.size_forward()); - } - - // Now figure out what we want to do with the string - aString.BeginReading(start); - // XXX Not guaranteed null-termination in the first case - // If it's a single buffer, we just use the implementation's buffer - if ( buffer_count == 1 ) - mBuffer = start.get(); - // If it's too big for our inline buffer, we allocate a new one - else if ( mLength > kDefaultFlatStringSize-1 ) - { - CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - CharT* toBegin = result; - *copy_string(start, end, toBegin) = CharT(0); - - mBuffer = result; - mOwnsBuffer = PR_TRUE; - } - // Otherwise copy into our internal buffer - else - { - mBuffer = mInlineBuffer; - CharT* toBegin = &mInlineBuffer[0]; - copy_string( start, end, toBegin); - mInlineBuffer[mLength] = 0; - } - } - - -template -const CharT* -basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment& aFragment, - nsFragmentRequest aRequest, - PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mBuffer) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - - -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; - -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; - #endif // !defined(nsAReadableString_h___) diff --git a/mozilla/string/public/nsAString.h b/mozilla/string/public/nsAString.h index c9e909d007b..e63ebf7becb 100644 --- a/mozilla/string/public/nsAString.h +++ b/mozilla/string/public/nsAString.h @@ -23,6 +23,10 @@ #ifndef nsAString_h___ #define nsAString_h___ +#ifndef nsStringFwd_h___ +#include "nsStringFwd.h" +#endif + #ifndef nsPrivateSharableString_h___ #include "nsPrivateSharableString.h" #endif @@ -36,61 +40,723 @@ * */ -class nsAString +class NS_COM nsAString : public nsPrivateSharableString { public: - typedef PRUint32 size_type; + typedef nsAString self_type; + typedef nsAPromiseString promise_type; + typedef PRUnichar char_type; + typedef char incompatible_char_type; + + + typedef nsReadingIterator const_iterator; + typedef nsWritingIterator iterator; + + typedef PRUint32 size_type; + typedef PRUint32 index_type; + + - typedef nsReadingIterator const_iterator; - typedef nsWritingIterator iterator; // nsAString(); // auto-generated default constructor OK (we're abstract anyway) - // nsAString( const nsAString& ); // auto-generated copy-constructor OK (again, only because we're abstract) + // nsAString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract) virtual ~nsAString() { } // ...yes, I expect to be sub-classed - const_iterator& BeginReading( const_iterator& ) const; - const_iterator& EndReading( const_iterator& ) const; + inline const_iterator& BeginReading( const_iterator& ) const; + inline const_iterator& EndReading( const_iterator& ) const; - iterator& BeginWriting( iterator& ); - iterator& EndWriting( iterator& ); + inline iterator& BeginWriting( iterator& ); + inline iterator& EndWriting( iterator& ); virtual size_type Length() const = 0; - PRBool IsEmpty() const; + PRBool IsEmpty() const { return Length() == 0; } + + inline PRBool Equals( const self_type& ) const; - // ... + /** + * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. + * These signatures should be pushed down into interfaces that guarantee flat allocation. + * Clients at _this_ level should always use iterators. + */ + char_type First() const; + char_type Last() const; + + size_type CountChar( char_type ) const; + + + /* + |Left|, |Mid|, and |Right| are annoying signatures that seem better almost + any _other_ way than they are now. Consider these alternatives + + aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| + aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| + Left(aReadable, 17, aWritable); // ...a global function that does the assignment + + as opposed to the current signature + + aReadable.Left(aWritable, 17); // ...a member function that does the assignment + + or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality + + aWritable = Substring(aReadable, 0, 17); + */ + + size_type Left( self_type&, size_type ) const; + size_type Mid( self_type&, PRUint32, PRUint32 ) const; + size_type Right( self_type&, size_type ) const; + + // Find( ... ) const; + PRInt32 FindChar( char_type, index_type aOffset = 0 ) const; + // FindCharInSet( ... ) const; + // RFind( ... ) const; + // RFindChar( ... ) const; + // RFindCharInSet( ... ) const; + + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( size_type ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ + virtual void SetLength( size_type ) = 0; + + + void + Truncate( size_type aNewLength=0 ) + { + NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); + + if ( aNewLength < this->Length() ) + SetLength(aNewLength); + } + + + // PRBool SetCharAt( char_type, index_type ) = 0; + + + + // void ToLowerCase(); + // void ToUpperCase(); + + // void StripChars( const char_type* aSet ); + // void StripChar( ... ); + // void StripWhitespace(); + // void ReplaceChar( ... ); + // void ReplaceSubstring( ... ); + // void Trim( ... ); + // void CompressSet( ... ); + // void CompressWhitespace( ... ); + + + + // + // |Assign()|, |operator=()| + // + + void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); } + inline void Assign( const promise_type& aReadable ); + void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } + void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } + void Assign( char_type aChar ) { do_AssignFromElement(aChar); } + + // copy-assignment operator. I must define my own if I don't want the compiler to make me one + self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; } + + self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; } + self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; } + self_type& operator=( char_type aChar ) { Assign(aChar); return *this; } + + + + // + // |Append()|, |operator+=()| + // + + void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); } + inline void Append( const promise_type& aReadable ); + void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } + void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } + void Append( char_type aChar ) { do_AppendFromElement(aChar); } + + self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; } + self_type& operator+=( char_type aChar ) { Append(aChar); return *this; } + + + + /** + * The following index based routines need to be recast with iterators. + */ + + // + // |Insert()| + // Note: I would really like to move the |atPosition| parameter to the front of the argument list + // + + void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); } + inline void Insert( const promise_type& aReadable, index_type atPosition ); + void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } + void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } + void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); } + + + + virtual void Cut( index_type cutStart, size_type cutLength ); + + + + void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } +// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } + + private: + // NOT TO BE IMPLEMENTED + index_type CountChar( incompatible_char_type ) const; + void operator= ( incompatible_char_type ); + void Assign ( incompatible_char_type ); + void operator+= ( incompatible_char_type ); + void Append ( incompatible_char_type ); + void Insert ( incompatible_char_type, index_type ); + + + protected: + void AssignFromReadable( const self_type& ); + void AssignFromPromise( const self_type& ); + virtual void do_AssignFromReadable( const self_type& ); + virtual void do_AssignFromElementPtr( const char_type* ); + virtual void do_AssignFromElementPtrLength( const char_type*, size_type ); + virtual void do_AssignFromElement( char_type ); + + void AppendFromReadable( const self_type& ); + void AppendFromPromise( const self_type& ); + virtual void do_AppendFromReadable( const self_type& ); + virtual void do_AppendFromElementPtr( const char_type* ); + virtual void do_AppendFromElementPtrLength( const char_type*, size_type ); + virtual void do_AppendFromElement( char_type ); + + void InsertFromReadable( const self_type&, index_type ); + void InsertFromPromise( const self_type&, index_type ); + virtual void do_InsertFromReadable( const self_type&, index_type ); + virtual void do_InsertFromElementPtr( const char_type*, index_type ); + virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type ); + virtual void do_InsertFromElement( char_type, index_type ); + + void ReplaceFromReadable( index_type, size_type, const self_type& ); + void ReplaceFromPromise( index_type, size_type, const self_type& ); + virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& ); + + +// protected: + public: + virtual const char_type* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; + virtual char_type* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + virtual PRBool Promises( const self_type& aString ) const { return &aString == this; } }; +class NS_COM nsACString + : public nsPrivateSharableString + { + public: + typedef nsACString self_type; + typedef nsAPromiseCString promise_type; + typedef char char_type; + typedef PRUnichar incompatible_char_type; + + + typedef nsReadingIterator const_iterator; + typedef nsWritingIterator iterator; + + typedef PRUint32 size_type; + typedef PRUint32 index_type; + + + + + // nsACString(); // auto-generated default constructor OK (we're abstract anyway) + // nsACString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract) + virtual ~nsACString() { } // ...yes, I expect to be sub-classed + + inline const_iterator& BeginReading( const_iterator& ) const; + inline const_iterator& EndReading( const_iterator& ) const; + + inline iterator& BeginWriting( iterator& ); + inline iterator& EndWriting( iterator& ); + + virtual size_type Length() const = 0; + PRBool IsEmpty() const { return Length() == 0; } + + inline PRBool Equals( const self_type& ) const; + + + /** + * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. + * These signatures should be pushed down into interfaces that guarantee flat allocation. + * Clients at _this_ level should always use iterators. + */ + char_type First() const; + char_type Last() const; + + size_type CountChar( char_type ) const; + + + /* + |Left|, |Mid|, and |Right| are annoying signatures that seem better almost + any _other_ way than they are now. Consider these alternatives + + aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| + aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| + Left(aReadable, 17, aWritable); // ...a global function that does the assignment + + as opposed to the current signature + + aReadable.Left(aWritable, 17); // ...a member function that does the assignment + + or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality + + aWritable = Substring(aReadable, 0, 17); + */ + + size_type Left( self_type&, size_type ) const; + size_type Mid( self_type&, PRUint32, PRUint32 ) const; + size_type Right( self_type&, size_type ) const; + + // Find( ... ) const; + PRInt32 FindChar( char_type, PRUint32 aOffset = 0 ) const; + // FindCharInSet( ... ) const; + // RFind( ... ) const; + // RFindChar( ... ) const; + // RFindCharInSet( ... ) const; + + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( size_type ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ + virtual void SetLength( size_type ) = 0; + + + void + Truncate( size_type aNewLength=0 ) + { + NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); + + if ( aNewLength < this->Length() ) + SetLength(aNewLength); + } + + + // PRBool SetCharAt( char_type, index_type ) = 0; + + + + // void ToLowerCase(); + // void ToUpperCase(); + + // void StripChars( const char_type* aSet ); + // void StripChar( ... ); + // void StripWhitespace(); + // void ReplaceChar( ... ); + // void ReplaceSubstring( ... ); + // void Trim( ... ); + // void CompressSet( ... ); + // void CompressWhitespace( ... ); + + + + // + // |Assign()|, |operator=()| + // + + void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); } + inline void Assign( const promise_type& aReadable ); + void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } + void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } + void Assign( char_type aChar ) { do_AssignFromElement(aChar); } + + // copy-assignment operator. I must define my own if I don't want the compiler to make me one + self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; } + + self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; } + self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; } + self_type& operator=( char_type aChar ) { Assign(aChar); return *this; } + + + + // + // |Append()|, |operator+=()| + // + + void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); } + inline void Append( const promise_type& aReadable ); + void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } + void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } + void Append( char_type aChar ) { do_AppendFromElement(aChar); } + + self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; } + self_type& operator+=( char_type aChar ) { Append(aChar); return *this; } + + + + /** + * The following index based routines need to be recast with iterators. + */ + + // + // |Insert()| + // Note: I would really like to move the |atPosition| parameter to the front of the argument list + // + + void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); } + inline void Insert( const promise_type& aReadable, index_type atPosition ); + void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } + void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } + void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); } + + + + virtual void Cut( index_type cutStart, size_type cutLength ); + + + + void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } +// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } + + private: + // NOT TO BE IMPLEMENTED + index_type CountChar( incompatible_char_type ) const; + void operator= ( incompatible_char_type ); + void Assign ( incompatible_char_type ); + void operator+= ( incompatible_char_type ); + void Append ( incompatible_char_type ); + void Insert ( incompatible_char_type, index_type ); + + + protected: + void AssignFromReadable( const self_type& ); + void AssignFromPromise( const self_type& ); + virtual void do_AssignFromReadable( const self_type& ); + virtual void do_AssignFromElementPtr( const char_type* ); + virtual void do_AssignFromElementPtrLength( const char_type*, size_type ); + virtual void do_AssignFromElement( char_type ); + + void AppendFromReadable( const self_type& ); + void AppendFromPromise( const self_type& ); + virtual void do_AppendFromReadable( const self_type& ); + virtual void do_AppendFromElementPtr( const char_type* ); + virtual void do_AppendFromElementPtrLength( const char_type*, size_type ); + virtual void do_AppendFromElement( char_type ); + + void InsertFromReadable( const self_type&, index_type ); + void InsertFromPromise( const self_type&, index_type ); + virtual void do_InsertFromReadable( const self_type&, index_type ); + virtual void do_InsertFromElementPtr( const char_type*, index_type ); + virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type ); + virtual void do_InsertFromElement( char_type, index_type ); + + void ReplaceFromReadable( index_type, size_type, const self_type& ); + void ReplaceFromPromise( index_type, size_type, const self_type& ); + virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& ); + + +// protected: + public: + virtual const char_type* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; + virtual char_type* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + virtual PRBool Promises( const self_type& aString ) const { return &aString == this; } + }; + +#include "nsAPromiseString.h" + +inline +void +nsAString::Assign( const nsAPromiseString& aReadable ) + { + AssignFromPromise(aReadable); + } + +inline +void +nsAString::Append( const nsAPromiseString& aReadable ) + { + AppendFromPromise(aReadable); + } + +inline +void +nsAString::Insert( const nsAPromiseString& aReadable, index_type atPosition ) + { + InsertFromPromise(aReadable, atPosition); + } + +inline +void +nsACString::Assign( const nsAPromiseCString& aReadable ) + { + AssignFromPromise(aReadable); + } + +inline +void +nsACString::Append( const nsAPromiseCString& aReadable ) + { + AppendFromPromise(aReadable); + } + +inline +void +nsACString::Insert( const nsAPromiseCString& aReadable, index_type atPosition ) + { + InsertFromPromise(aReadable, atPosition); + } + + + /** + * Note: measure -- should the |Begin...| and |End...| be |inline|? + */ +inline +nsAString::const_iterator& +nsAString::BeginReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } + +inline +nsAString::const_iterator& +nsAString::EndReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +inline +nsAString::iterator& +nsAString::BeginWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } + + +inline +nsAString::iterator& +nsAString::EndWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +NS_COM int Compare( const nsAString& lhs, const nsAString& rhs ); + +inline +PRBool +nsAString::Equals( const nsAString& rhs ) const + { + return Length()==rhs.Length() && Compare(*this, rhs)==0; + } + +inline +PRBool +operator!=( const nsAString& lhs, const nsAString& rhs ) + { + return !lhs.Equals(rhs); + } + +inline +PRBool +operator< ( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)< 0; + } + +inline +PRBool +operator<=( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)<=0; + } + +inline +PRBool +operator==( const nsAString& lhs, const nsAString& rhs ) + { + return lhs.Equals(rhs); + } + +inline +PRBool +operator>=( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)>=0; + } + +inline +PRBool +operator> ( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)> 0; + } + +inline +nsAString::size_type +nsAString::Left( nsAString& aResult, size_type aLengthToCopy ) const + { + return Mid(aResult, 0, aLengthToCopy); + } + /** * */ -class nsACString - : public nsPrivateSharableString +inline +nsACString::const_iterator& +nsACString::BeginReading( const_iterator& aResult ) const { - public: - typedef PRUint32 size_type; + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } - typedef nsReadingIterator const_iterator; - typedef nsWritingIterator iterator; +inline +nsACString::const_iterator& +nsACString::EndReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } - // nsACString(); // auto-generated default constructor OK (we're abstract anyway) - // nsACString( const nsACString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - virtual ~nsACString() { } // ...yes, I expect to be sub-classed +inline +nsACString::iterator& +nsACString::BeginWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } - const_iterator& BeginReading( const_iterator& ) const; - const_iterator& EndReading( const_iterator& ) const; - iterator& BeginWriting( iterator& ); - iterator& EndWriting( iterator& ); +inline +nsACString::iterator& +nsACString::EndWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +NS_COM int Compare( const nsACString& lhs, const nsACString& rhs ); + +inline +PRBool +nsACString::Equals( const self_type& rhs ) const + { + return Length()==rhs.Length() && Compare(*this, rhs)==0; + } + +inline +PRBool +operator!=( const nsACString& lhs, const nsACString& rhs ) + { + return !lhs.Equals(rhs); + } + +inline +PRBool +operator< ( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)< 0; + } + +inline +PRBool +operator<=( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)<=0; + } + +inline +PRBool +operator==( const nsACString& lhs, const nsACString& rhs ) + { + return lhs.Equals(rhs); + } + +inline +PRBool +operator>=( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)>=0; + } + +inline +PRBool +operator> ( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)> 0; + } + +inline +nsACString::size_type +nsACString::Left( nsACString& aResult, size_type aLengthToCopy ) const + { + return Mid(aResult, 0, aLengthToCopy); + } - virtual size_type Length() const = 0; - PRBool IsEmpty() const; - - // ... - }; #endif // !defined(nsAString_h___) diff --git a/mozilla/string/public/nsAWritableString.h b/mozilla/string/public/nsAWritableString.h index b123dce5dbc..e8cd01cd33d 100644 --- a/mozilla/string/public/nsAWritableString.h +++ b/mozilla/string/public/nsAWritableString.h @@ -24,590 +24,11 @@ #ifndef nsAWritableString_h___ #define nsAWritableString_h___ - // See also... #ifndef nsAReadableString_h___ #include "nsAReadableString.h" #endif -#ifndef nsLiteralString_h___ -#include "nsLiteralString.h" -#endif - - -template class basic_nsAWritableString; - -/* - This file defines the abstract interfaces |nsAWritableString| and - |nsAWritableCString|. - - |nsAWritableString| is a string of |PRUnichar|s. |nsAWritableCString| (note the - 'C') is a string of |char|s. -*/ - -template -class basic_nsAWritableString - : public basic_nsAReadableString - /* - ... - */ - { - // friend class nsWritingIterator; - - public: - typedef CharT char_type; - typedef PRUint32 size_type; - typedef PRUint32 index_type; - - typedef nsWritingIterator iterator; - - // basic_nsAWritableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAWritableString( const basic_nsAWritableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - // ~basic_nsAWritableString(); // auto-generated destructor OK - // see below for copy-assignment operator - - virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - - /** - * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? - */ - nsWritingIterator& - BeginWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - - - nsWritingIterator& - EndWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - - - /** - * |SetCapacity| is not required to do anything; however, it can be used - * as a hint to the implementation to reduce allocations. - * |SetCapacity(0)| is a suggestion to discard all associated storage. - */ - virtual void SetCapacity( PRUint32 ) { } - - /** - * |SetLength| is used in two ways: - * 1) to |Cut| a suffix of the string; - * 2) to prepare to |Append| or move characters around. - * - * External callers are not allowed to use |SetLength| is this latter capacity. - * Should this really be a public operation? - * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you - * override the |do_...| routines to not need this facility. - * - * This distinction makes me think the two different uses should be split into - * two distinct functions. - */ - virtual void SetLength( PRUint32 ) = 0; - - - void - Truncate( PRUint32 aNewLength=0 ) - { - NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); - - if ( aNewLength < this->Length() ) - SetLength(aNewLength); - } - - - // PRBool SetCharAt( char_type, index_type ) = 0; - - - - // void ToLowerCase(); - // void ToUpperCase(); - - // void StripChars( const CharT* aSet ); - // void StripChar( ... ); - // void StripWhitespace(); - // void ReplaceChar( ... ); - // void ReplaceSubstring( ... ); - // void Trim( ... ); - // void CompressSet( ... ); - // void CompressWhitespace( ... ); - - - - // - // |Assign()|, |operator=()| - // - - void Assign( const basic_nsAReadableString& aReadable ) { AssignFromReadable(aReadable); } - void Assign( const nsPromiseReadable& aReadable ) { AssignFromPromise(aReadable); } - void Assign( const CharT* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } - void Assign( const CharT* aPtr, PRUint32 aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } - void Assign( CharT aChar ) { do_AssignFromElement(aChar); } - - // copy-assignment operator. I must define my own if I don't want the compiler to make me one - basic_nsAWritableString& operator=( const basic_nsAWritableString& aWritable ) { Assign(aWritable); return *this; } - - basic_nsAWritableString& operator=( const basic_nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const CharT* aPtr ) { Assign(aPtr); return *this; } - basic_nsAWritableString& operator=( CharT aChar ) { Assign(aChar); return *this; } - - - - // - // |Append()|, |operator+=()| - // - - void Append( const basic_nsAReadableString& aReadable ) { AppendFromReadable(aReadable); } - void Append( const nsPromiseReadable& aReadable ) { AppendFromPromise(aReadable); } - void Append( const CharT* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } - void Append( const CharT* aPtr, PRUint32 aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } - void Append( CharT aChar ) { do_AppendFromElement(aChar); } - - basic_nsAWritableString& operator+=( const basic_nsAReadableString& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const nsPromiseReadable& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const CharT* aPtr ) { Append(aPtr); return *this; } - basic_nsAWritableString& operator+=( CharT aChar ) { Append(aChar); return *this; } - - - - /** - * The following index based routines need to be recast with iterators. - */ - - // - // |Insert()| - // Note: I would really like to move the |atPosition| parameter to the front of the argument list - // - - void Insert( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) { InsertFromReadable(aReadable, atPosition); } - void Insert( const nsPromiseReadable& aReadable, PRUint32 atPosition ) { InsertFromPromise(aReadable, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } - void Insert( CharT aChar, PRUint32 atPosition ) { do_InsertFromElement(aChar, atPosition); } - - - - virtual void Cut( PRUint32 cutStart, PRUint32 cutLength ); - - - - void Replace( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } - void Replace( PRUint32 cutStart, PRUint32 cutLength, const nsPromiseReadable& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } - - private: - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - - // NOT TO BE IMPLEMENTED - void operator= ( incompatible_char_type ); - void Assign ( incompatible_char_type ); - void operator+= ( incompatible_char_type ); - void Append ( incompatible_char_type ); - void Insert ( incompatible_char_type, PRUint32 ); - - - protected: - void AssignFromReadable( const basic_nsAReadableString& ); - void AssignFromPromise( const basic_nsAReadableString& ); - virtual void do_AssignFromReadable( const basic_nsAReadableString& ); - virtual void do_AssignFromElementPtr( const CharT* ); - virtual void do_AssignFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AssignFromElement( CharT ); - - void AppendFromReadable( const basic_nsAReadableString& ); - void AppendFromPromise( const basic_nsAReadableString& ); - virtual void do_AppendFromReadable( const basic_nsAReadableString& ); - virtual void do_AppendFromElementPtr( const CharT* ); - virtual void do_AppendFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AppendFromElement( CharT ); - - void InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - void InsertFromPromise( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromElementPtr( const CharT*, PRUint32 ); - virtual void do_InsertFromElementPtrLength( const CharT*, PRUint32, PRUint32 ); - virtual void do_InsertFromElement( CharT, PRUint32 ); - - void ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - void ReplaceFromPromise( PRUint32, PRUint32, const basic_nsAReadableString& ); - virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - }; - - - - - - // - // |Assign()| - // - -template -void -basic_nsAWritableString::AssignFromReadable( const basic_nsAReadableString& rhs ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &rhs ) - do_AssignFromReadable(rhs); - // else, self-assign is a no-op - } - -template -void -basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString& aReadable ) - /* - ...this function is only called when a promise that somehow references |this| is assigned _into_ |this|. - E.g., - - ... writable& w ... - ... readable& r ... - - w = r + w; - - In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before - anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents - of |r| before being retrieved to be appended. - - We could have a really tricky solution where we tell the promise to resolve _just_ the data promised - by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g., - in the case above, |Insert| could have special behavior with significantly better performance. Since - it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the - entire promise. If we measure and this turns out to show up on performance radar, we then have the - option to fix either the callers or this mechanism. - */ - { - if ( !aReadable.Promises(*this) ) - do_AssignFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - // Note: not exception safe. We need something to manage temporary buffers like this - - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AssignFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableString& aReadable ) - { - SetLength(0); - SetLength(aReadable.Length()); - // first setting the length to |0| avoids copying characters only to be overwritten later - // in the case where the implementation decides to re-allocate - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtr( const CharT* aPtr ) - { - do_AssignFromReadable(literal_string(aPtr)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtrLength( const CharT* aPtr, PRUint32 aLength ) - { - do_AssignFromReadable(literal_string(aPtr, aLength)); - } - -template -void -basic_nsAWritableString::do_AssignFromElement( CharT aChar ) - { - do_AssignFromReadable(literal_string(&aChar, 1)); - } - - - - // - // |Append()| - // - -template -void -basic_nsAWritableString::AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_AppendFromReadable(aReadable); - else - AppendFromPromise(aReadable); - } - -template -void -basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_AppendFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AppendFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtr( const CharT* aChar ) - { - do_AppendFromReadable(literal_string(aChar)); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtrLength( const CharT* aChar, PRUint32 aLength ) - { - do_AppendFromReadable(literal_string(aChar, aLength)); - } - -template -void -basic_nsAWritableString::do_AppendFromElement( CharT aChar ) - { - do_AppendFromReadable(literal_string(&aChar, 1)); - } - - - - // - // |Insert()| - // - -template -void -basic_nsAWritableString::InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_InsertFromReadable(aReadable, atPosition); - else - InsertFromPromise(aReadable, atPosition); - } - -template -void -basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( !aReadable.Promises(*this) ) - do_InsertFromReadable(aReadable, atPosition); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_InsertFromElementPtrLength(buffer, atPosition, length); - delete buffer; - } - // else assert - } - } - -template -void -basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); - else - atPosition = oldLength; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtr( const CharT* aPtr, PRUint32 atPosition ) - { - do_InsertFromReadable(literal_string(aPtr), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtrLength( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) - { - do_InsertFromReadable(literal_string(aPtr, aLength), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElement( CharT aChar, PRUint32 atPosition ) - { - do_InsertFromReadable(literal_string(&aChar, 1), atPosition); - } - - - - // - // |Cut()| - // - -template -void -basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) - { - PRUint32 myLength = this->Length(); - cutLength = NS_MIN(cutLength, myLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutEnd < myLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - SetLength(myLength-cutLength); - } - - - - // - // |Replace()| - // - -template -void -basic_nsAWritableString::ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReplacement ) - do_ReplaceFromReadable(cutStart, cutLength, aReplacement); - else - ReplaceFromPromise(cutStart, cutLength, aReplacement); - } - -template -void -basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_ReplaceFromReadable(cutStart, cutLength, aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_ReplaceFromReadable(cutStart, cutLength, literal_string(buffer, length)); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - PRUint32 oldLength = this->Length(); - - cutStart = NS_MIN(cutStart, oldLength); - cutLength = NS_MIN(cutLength, oldLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - PRUint32 replacementLength = aReplacement.Length(); - PRUint32 replacementEnd = cutStart + replacementLength; - - PRUint32 newLength = oldLength - cutLength + replacementLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutLength > replacementLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - SetLength(newLength); - if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - - copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - } - - -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } - - - - - // - // Types - // - -typedef basic_nsAWritableString nsAWritableString; -typedef basic_nsAWritableString nsAWritableCString; +typedef nsAString nsAWritableString; +typedef nsACString nsAWritableCString; #endif // !defined(nsAWritableString_h___) diff --git a/mozilla/string/public/nsBufferHandleUtils.h b/mozilla/string/public/nsBufferHandleUtils.h index 6f05fabe22a..06e37e94b10 100644 --- a/mozilla/string/public/nsBufferHandleUtils.h +++ b/mozilla/string/public/nsBufferHandleUtils.h @@ -25,9 +25,12 @@ #ifndef nsBufferHandleUtils_h___ #define nsBufferHandleUtils_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |basic_nsAReadableString|... +#ifndef nsAString_h___ +#include "nsAString.h" +#endif + +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" #endif #include @@ -62,21 +65,22 @@ NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr ) return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr)); } -template +template HandleT* -NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic_nsAReadableString& aDataSource, PRUint32 aAdditionalCapacity ) +NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity ) { - typedef CharT* CharT_ptr; + typedef typename StringT::char_type char_type; + typedef char_type* char_ptr; // figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part - size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, CharT_ptr(0)); + size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, char_ptr(0)); - // figure out how many |CharT|s wee need to fit in the data part + // figure out how many |char_type|s wee need to fit in the data part size_t data_length = aDataSource.Length(); size_t buffer_length = data_length + aAdditionalCapacity; // how many bytes is that (including a zero-terminator so we can claim to be flat)? - size_t buffer_size = buffer_length * sizeof(CharT); + size_t buffer_size = buffer_length * sizeof(char_type); HandleT* result = 0; @@ -84,17 +88,17 @@ NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic if ( handle_ptr ) { - CharT* data_start_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); - CharT* data_end_ptr = data_start_ptr + data_length; - CharT* buffer_end_ptr = data_start_ptr + buffer_length; + char_ptr data_start_ptr = char_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); + char_ptr data_end_ptr = data_start_ptr + data_length; + char_ptr buffer_end_ptr = data_start_ptr + buffer_length; - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = data_start_ptr; + StringT::const_iterator fromBegin, fromEnd; + char_ptr toBegin = data_start_ptr; copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin); // and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate if ( aAdditionalCapacity > 0 ) - *toBegin = CharT(0); + *toBegin = char_type(0); result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, data_start_ptr, buffer_end_ptr, PR_TRUE); } diff --git a/mozilla/string/public/nsCharTraits.h b/mozilla/string/public/nsCharTraits.h index 964c6be8646..bcebf129a78 100644 --- a/mozilla/string/public/nsCharTraits.h +++ b/mozilla/string/public/nsCharTraits.h @@ -39,6 +39,8 @@ #include "nsStringIteratorUtils.h" #endif +class nsAString; +class nsACString; #ifdef HAVE_CPP_BOOL typedef bool nsCharTraits_bool; @@ -49,8 +51,8 @@ template struct nsCharTraits { - typedef CharT char_type; - typedef char incompatible_char_type; + typedef CharT char_type; + typedef char incompatible_char_type; static void @@ -214,8 +216,8 @@ struct nsCharTraits NS_SPECIALIZE_TEMPLATE struct nsCharTraits { - typedef char char_type; - typedef PRUnichar incompatible_char_type; + typedef char char_type; + typedef PRUnichar incompatible_char_type; static void @@ -341,7 +343,7 @@ struct nsCharTraits NS_SPECIALIZE_TEMPLATE struct nsCharTraits { - typedef wchar_t char_type; + typedef wchar_t char_type; static void diff --git a/mozilla/string/public/nsDependentString.h b/mozilla/string/public/nsDependentString.h index 6e44379e262..e380a36c9c3 100644 --- a/mozilla/string/public/nsDependentString.h +++ b/mozilla/string/public/nsDependentString.h @@ -23,8 +23,8 @@ #ifndef nsLocalString_h___ #define nsLocalString_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" #endif /* @@ -46,10 +46,11 @@ */ class NS_COM nsLocalString - : public basic_nsAReadableString + : public nsAFlatString { protected: virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -84,10 +85,7 @@ class NS_COM nsLocalString public: virtual PRUint32 Length() const; - - - const PRUnichar* get() const { return mStart; } - operator const PRUnichar*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const PRUnichar* mStart; @@ -97,10 +95,11 @@ class NS_COM nsLocalString class NS_COM nsLocalCString - : public basic_nsAReadableString + : public nsAFlatCString { protected: virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -135,10 +134,7 @@ class NS_COM nsLocalCString public: virtual PRUint32 Length() const; - - - const char* get() const { return mStart; } - operator const char*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const char* mStart; diff --git a/mozilla/string/public/nsFragmentedString.h b/mozilla/string/public/nsFragmentedString.h index e5348b42f48..0dd1ca183cd 100644 --- a/mozilla/string/public/nsFragmentedString.h +++ b/mozilla/string/public/nsFragmentedString.h @@ -27,8 +27,8 @@ // WORK IN PROGRESS -#ifndef nsAWritableString_h___ -#include "nsAWritableString.h" +#ifndef nsAString_h___ +#include "nsAString.h" #endif #ifndef nsSharedBufferList_h___ @@ -37,7 +37,7 @@ class nsFragmentedString - : public basic_nsAWritableString + : public nsAString /* ... */ diff --git a/mozilla/string/public/nsLiteralString.h b/mozilla/string/public/nsLiteralString.h index 53a735ba4f1..7f772b8d9b5 100644 --- a/mozilla/string/public/nsLiteralString.h +++ b/mozilla/string/public/nsLiteralString.h @@ -34,37 +34,24 @@ typedef const nsLocalString nsLiteralString; typedef const nsLocalCString nsLiteralCString; -template -struct nsLiteralStringTraits - { - }; - -NS_SPECIALIZE_TEMPLATE -struct nsLiteralStringTraits - { - typedef nsLiteralString literal_string_type; - }; - -NS_SPECIALIZE_TEMPLATE -struct nsLiteralStringTraits - { - typedef nsLiteralCString literal_string_type; - }; +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif template inline -const typename nsLiteralStringTraits::literal_string_type +const typename nsStringTraits::literal_string_type literal_string( const CharT* aPtr ) { - return nsLiteralStringTraits::literal_string_type(aPtr); + return nsStringTraits::literal_string_type(aPtr); } template inline -const typename nsLiteralStringTraits::literal_string_type +const typename nsStringTraits::literal_string_type literal_string( const CharT* aPtr, PRUint32 aLength ) { - return nsLiteralStringTraits::literal_string_type(aPtr, aLength); + return nsStringTraits::literal_string_type(aPtr, aLength); } #ifdef HAVE_CPP_2BYTE_WCHAR_T diff --git a/mozilla/string/public/nsLocalString.h b/mozilla/string/public/nsLocalString.h index 6e44379e262..e380a36c9c3 100644 --- a/mozilla/string/public/nsLocalString.h +++ b/mozilla/string/public/nsLocalString.h @@ -23,8 +23,8 @@ #ifndef nsLocalString_h___ #define nsLocalString_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" #endif /* @@ -46,10 +46,11 @@ */ class NS_COM nsLocalString - : public basic_nsAReadableString + : public nsAFlatString { protected: virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -84,10 +85,7 @@ class NS_COM nsLocalString public: virtual PRUint32 Length() const; - - - const PRUnichar* get() const { return mStart; } - operator const PRUnichar*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const PRUnichar* mStart; @@ -97,10 +95,11 @@ class NS_COM nsLocalString class NS_COM nsLocalCString - : public basic_nsAReadableString + : public nsAFlatCString { protected: virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -135,10 +134,7 @@ class NS_COM nsLocalCString public: virtual PRUint32 Length() const; - - - const char* get() const { return mStart; } - operator const char*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const char* mStart; diff --git a/mozilla/string/public/nsSharedBufferList.h b/mozilla/string/public/nsSharedBufferList.h index 5a5ad9330c5..4fda3118cb8 100755 --- a/mozilla/string/public/nsSharedBufferList.h +++ b/mozilla/string/public/nsSharedBufferList.h @@ -35,13 +35,12 @@ // for |PRUnichar| #endif -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |nsReadingIterator| +#ifndef nsAString_h___ +#include "nsAString.h" #endif -#ifndef nsLiteralString_h___ -#include "nsLiteralString.h" +#ifndef nsLocalString_h___ +#include "nsLocalString.h" #endif #ifndef nsBufferHandleUtils_h___ @@ -184,12 +183,12 @@ class NS_COM nsSharedBufferList NewSingleAllocationBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalCapacity = 1 ) { typedef Buffer* Buffer_ptr; - return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), NS_READABLE_CAST(PRUnichar, literal_string(aData, aDataLength)), aAdditionalCapacity); + return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), nsLocalString(aData, aDataLength), aAdditionalCapacity); } static Buffer* - NewSingleAllocationBuffer( const nsAReadableString& aReadable, PRUint32 aAdditionalCapacity = 1 ) + NewSingleAllocationBuffer( const nsAString& aReadable, PRUint32 aAdditionalCapacity = 1 ) { typedef Buffer* Buffer_ptr; return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), aReadable, aAdditionalCapacity); diff --git a/mozilla/string/public/nsSlidingString.h b/mozilla/string/public/nsSlidingString.h index 079e7e2f1eb..4c0d24f1797 100755 --- a/mozilla/string/public/nsSlidingString.h +++ b/mozilla/string/public/nsSlidingString.h @@ -69,7 +69,7 @@ class nsSlidingString; * a substring over a buffer list, this */ class NS_COM nsSlidingSubstring - : virtual public nsPromiseReadable + : virtual public nsAPromiseString { friend class nsSlidingString; @@ -154,7 +154,7 @@ class NS_COM nsSlidingSubstring * */ class NS_COM nsSlidingString - : virtual public nsPromiseReadable, + : virtual public nsAPromiseString, private nsSlidingSubstring { friend class nsSlidingSubstring; diff --git a/mozilla/string/public/nsStringIterator.h b/mozilla/string/public/nsStringIterator.h index 316bd540465..4f777635cdd 100644 --- a/mozilla/string/public/nsStringIterator.h +++ b/mozilla/string/public/nsStringIterator.h @@ -27,14 +27,21 @@ #include "nsStringFragment.h" #endif +#ifndef nsCharTraits_h___ +#include "nsCharTraits.h" +#endif + +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif + #ifndef nsAlgorithm_h___ #include "nsAlgorithm.h" // for |NS_MIN|, |NS_MAX|, and |NS_COUNT|... #endif -template class basic_nsAReadableString; -template class basic_nsAWritableString; + @@ -56,11 +63,13 @@ class nsReadingIterator // typedef bidirectional_iterator_tag iterator_category; private: - friend class basic_nsAReadableString; + friend class nsAString; + friend class nsACString; + typedef typename nsStringTraits::abstract_string_type string_type; - nsReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; + nsReadableFragment mFragment; + const CharT* mPosition; + const string_type* mOwningString; public: nsReadingIterator() { } @@ -132,7 +141,7 @@ class nsReadingIterator return mFragment; } - const basic_nsAReadableString& + const string_type& string() const { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); @@ -155,8 +164,8 @@ class nsReadingIterator advance( difference_type n ) { while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); + { + difference_type one_hop = NS_MIN(n, size_forward()); NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); // perhaps I should |break| if |!one_hop|? @@ -194,11 +203,13 @@ class nsWritingIterator // typedef bidirectional_iterator_tag iterator_category; private: - friend class basic_nsAWritableString; + friend class nsAString; + friend class nsACString; + typedef typename nsStringTraits::abstract_string_type string_type; - nsWritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; + nsWritableFragment mFragment; + CharT* mPosition; + string_type* mOwningString; public: nsWritingIterator() { } @@ -276,14 +287,14 @@ class nsWritingIterator return mFragment; } - const basic_nsAWritableString& + const string_type& string() const { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); return *mOwningString; } - basic_nsAWritableString& + string_type& string() { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); @@ -364,6 +375,22 @@ nsReadingIterator::normalize_backward() mPosition = mFragment.mEnd; } +template +inline +PRBool +operator==( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) + { + return lhs.get() == rhs.get(); + } + +template +inline +PRBool +operator!=( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) + { + return lhs.get() != rhs.get(); + } + // // |nsWritingIterator|s diff --git a/mozilla/string/src/Makefile.in b/mozilla/string/src/Makefile.in index 16189711271..95adc2aa6f0 100644 --- a/mozilla/string/src/Makefile.in +++ b/mozilla/string/src/Makefile.in @@ -34,6 +34,8 @@ LIBRARY_NAME = string_s REQUIRES = xpcom CPPSRCS = \ + nsAString.cpp \ + nsCommonString.cpp \ nsLocalString.cpp \ nsFragmentedString.cpp \ nsPrintfCString.cpp \ diff --git a/mozilla/string/src/makefile.win b/mozilla/string/src/makefile.win index d4cd1a950d1..fa8056981e9 100644 --- a/mozilla/string/src/makefile.win +++ b/mozilla/string/src/makefile.win @@ -29,6 +29,8 @@ LIBRARY_NAME=string_s LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN CPP_OBJS = \ + .\$(OBJDIR)\nsAString.obj \ + .\$(OBJDIR)\nsCommonString.obj \ .\$(OBJDIR)\nsLocalString.obj \ .\$(OBJDIR)\nsFragmentedString.obj \ .\$(OBJDIR)\nsPrintfCString.obj \ diff --git a/mozilla/string/src/nsReadableUtils.cpp b/mozilla/string/src/nsReadableUtils.cpp index 4ffde71a5b6..8e2f50892f6 100755 --- a/mozilla/string/src/nsReadableUtils.cpp +++ b/mozilla/string/src/nsReadableUtils.cpp @@ -26,6 +26,11 @@ #include "nsString.h" #include "nsCRT.h" +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif + + template class CalculateLength { @@ -106,7 +111,7 @@ class LossyConvertEncoding NS_COM void -CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) +CopyUCS2toASCII( const nsAString& aSource, nsAWritableCString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); @@ -121,7 +126,7 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) NS_COM void -CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) +CopyASCIItoUCS2( const nsACString& aSource, nsAWritableString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); @@ -142,10 +147,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) * @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|. * */ -template +template inline ToCharT* -AllocateStringCopy( const basic_nsAReadableString& aSource, ToCharT* ) +AllocateStringCopy( const FromStringT& aSource, ToCharT* ) { return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT))); } @@ -153,7 +158,7 @@ AllocateStringCopy( const basic_nsAReadableString& aSource, ToCharT* NS_COM char* -ToNewCString( const nsAReadableString& aSource ) +ToNewCString( const nsAString& aSource ) { char* result = AllocateStringCopy(aSource, (char*)0); @@ -165,7 +170,7 @@ ToNewCString( const nsAReadableString& aSource ) NS_COM char* -ToNewUTF8String( const nsAReadableString& aSource ) +ToNewUTF8String( const nsAString& aSource ) { NS_ConvertUCS2toUTF8 temp(aSource); @@ -189,7 +194,7 @@ ToNewUTF8String( const nsAReadableString& aSource ) NS_COM char* -ToNewCString( const nsAReadableCString& aSource ) +ToNewCString( const nsACString& aSource ) { // no conversion needed, just allocate a buffer of the correct length and copy into it @@ -203,7 +208,7 @@ ToNewCString( const nsAReadableCString& aSource ) NS_COM PRUnichar* -ToNewUnicode( const nsAReadableString& aSource ) +ToNewUnicode( const nsAString& aSource ) { // no conversion needed, just allocate a buffer of the correct length and copy into it @@ -217,7 +222,7 @@ ToNewUnicode( const nsAReadableString& aSource ) NS_COM PRUnichar* -ToNewUnicode( const nsAReadableCString& aSource ) +ToNewUnicode( const nsACString& aSource ) { PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); @@ -229,7 +234,7 @@ ToNewUnicode( const nsAReadableCString& aSource ) NS_COM PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength ) +CopyUnicodeTo( const nsAString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength ) { nsReadingIterator fromBegin, fromEnd; PRUnichar* toBegin = aDest; @@ -268,7 +273,7 @@ AppendUnicodeTo( const nsReadingIterator& aSrcStart, NS_COM PRBool -IsASCII( const nsAReadableString& aString ) +IsASCII( const nsAString& aString ) { static const PRUnichar NOT_ASCII = PRUnichar(~0x007F); @@ -375,7 +380,7 @@ ToLowerCase( nsAWritableCString& aCString ) template inline // probably wishful thinking PRBool -FindInReadable_Impl( const basic_nsAReadableString& aPattern, +FindInReadable_Impl( const typename nsStringTraits::abstract_string_type& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { @@ -443,14 +448,14 @@ FindInReadable_Impl( const basic_nsAReadableString& aPattern, NS_COM PRBool -FindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +FindInReadable( const nsAString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } NS_COM PRBool -FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +FindInReadable( const nsACString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } @@ -463,7 +468,7 @@ FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSe template inline // probably wishful thinking PRBool -RFindInReadable_Impl( const basic_nsAReadableString& aPattern, +RFindInReadable_Impl( const typename nsStringTraits::abstract_string_type& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { @@ -499,14 +504,14 @@ RFindInReadable_Impl( const basic_nsAReadableString& aPattern, NS_COM PRBool -RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +RFindInReadable( const nsAString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } NS_COM PRBool -RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +RFindInReadable( const nsACString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } @@ -557,7 +562,7 @@ FindCharInReadable( char aChar, nsReadingIterator& aSearchStart, const nsR template PRUint32 -CountCharInReadable_Impl( const basic_nsAReadableString& aStr, +CountCharInReadable_Impl( const typename nsStringTraits::abstract_string_type& aStr, CharT aChar ) { PRUint32 count = 0; @@ -578,7 +583,7 @@ CountCharInReadable_Impl( const basic_nsAReadableString& aStr, NS_COM PRUint32 -CountCharInReadable( const nsAReadableString& aStr, +CountCharInReadable( const nsAString& aStr, PRUnichar aChar ) { return CountCharInReadable_Impl(aStr, aChar); @@ -586,7 +591,7 @@ CountCharInReadable( const nsAReadableString& aStr, NS_COM PRUint32 -CountCharInReadable( const nsAReadableCString& aStr, +CountCharInReadable( const nsACString& aStr, char aChar ) { return CountCharInReadable_Impl(aStr, aChar); diff --git a/mozilla/xpcom/string/macbuild/string.mcp b/mozilla/xpcom/string/macbuild/string.mcp index 17264396504b24ec79de465535ad9eab3e98d369..8eae5fa1440e20a82477625edcc76e199e555bf4 100644 GIT binary patch delta 2530 zcmd^>-%lJ>6vyu@v#{*a@?+&kwY5}WfBzJdwx%Y~Qd&w|m*qz(VA>Ultbtv!yV^vX zEFleBjWNZGA$_ovK9~}SqDzVoKA4c$RDzGxAP9jl zcpMCZesBtOfTzHD@H7|zhe0!V0z^R%=;o`Xox9G#I|I&wKCW6X@g-~BK6+M*f(xK$ z2yKD`!u&gHNt{Y4?VpLszGUX5Ol786>91H$}X z*&)7Svsf_G0i66}+lj*m3T|;~ckZKS({kD{gqSOrbMlt5wkCSRi&*{>nOKyi_P)+0 zZ!2sywf9vvxkyfau`H%$)!Ud$RmM>7;6nFe(7mi%xJ>;PmMVs!{)P+f28P*+OP_F= zc^@p*62nZ@qTRqSAHjuo0>eyorrp3WU%+LM*))-a8JcN5$Tuo~;33=95Z+T11J(uH zzyrL%2mBxaf`I0R`PJN!{4IOA!k0?w_^+j9rBq}e@Xxe%v0Wt=*E}I&;m$pX|EwU+;V}-yEF^ zm3(^YEyiB@CjZgY9aHw<_KwrX(I`%7twMknqZJD&Yq}?rTxwHXkAC)#JZAjV* zX)86GWiA=;Nb8oiN?NL0?{bpR)D0XOjE@8`NJ#lgjcyLfQ6 z!AyrWDm)jwZsED%^$5=cuUB}~o_)fjCOs!S`q1?Yj}Fjz;n9a~KzQ`I8x$UWLx%Ff z>%Z^V{h78d9?4w}A+diYikKJpfFA@v5YXH(-;69#K5(~23%IMbKNVg3Zr}l4-~)aT z06{==k;au<|Bnu}JkX)xe>$~9JD*Lwc6y-}o7`fWeG|qQH9z(9*h>9OMCCV+?#chS zbxpBg4;`3+_Pc%{fAhrp=QqDrjhsK<)Q=2#T5jZNiIJyeMV^)td0IZ?X~~eMWkQ~o26;88w11Y6M}_2*Rilgi#|1qec)$jUbE~K^QfHFlq#0)CfXP@r9zf zYOAtcT=gz?^}{)vP4Sp)p}B)L<&EOcI`I!=a&5z=L`}uH3YxIiuv;lLH7jO2V^%hv znHWP9J)w`c@jpbNczS2t)<1WlLa8afLH|>h*IubmtfsT&g^M63eatTvEK(4+jbcUx U7LUUg#5d=mm)E|kQnr=90jo^gTmS$7 delta 963 zcmX?noaOLJ7UAUl{2T@b24)5ZMhyl=j@Jx~TpNXRI9YXpf_jrDaEeQM0a>0vYzxHx zKx_%b#z1T``3|Qyt1pn{H`#=%d}4sXx4QufcAmxRGxf*+uc$g$WefbfV2RavLNLkQy>7r0jp&JiUP6fWCtD>)c_zT0mxs$ zz`y}g9l(&EXXBiaSQKK%n^zoAl%JbfoVs}>Pa?}i_k)v93qGDK(B3hbeSXg7MZ)}y z6J5$StBY>2*u2%Rm1$zYt;tq_EfZZzHyZ~v8L*$6`{V!rtL>ZjG;L!N6mawOaRu7S z52d*#%bgc@RD$x9p|lE=R)EsnP?`ry%Ry;U?vV)DGRwUcdH%>-c%htXgUSfYD?B!|mjaX2fIgBNNr+`W5O?0!iDh=$`uixx4g zTD1z!2g*%!EZnp(LWTWgu)+WTFWEO=6#LCMIqJ9=MBq<7M4;#-SO6G2h7f_S(@+(& z+<*c<7`F?vGTvaB7@)a%!KK5x&|uiO9T?FdQLX8sl8hhNxD9{?bWG=#V$@>dX`F5@ z#n{KzasiY=x1W|`3}RvvS_e|FU0IfqlgXIj?0g0WR)*Y?0%%47%7H-}Pzyr?P`nsO zgOV>4@UTpemuD1XYYzYl)NHSoXXIk?V--d+1eAWEVD5h)17--4I1k8;0zktvfi#l% Pym}zNX8UDD#t)1DW+?Kp diff --git a/mozilla/xpcom/string/obsolete/nsString.cpp b/mozilla/xpcom/string/obsolete/nsString.cpp index 057ffcea00c..364766afd74 100644 --- a/mozilla/xpcom/string/obsolete/nsString.cpp +++ b/mozilla/xpcom/string/obsolete/nsString.cpp @@ -832,6 +832,7 @@ void nsCString::AssignWithConversion(PRUnichar aChar) { AppendWithConversion(aChar); } +#if 0 void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable ) { if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) ) @@ -839,6 +840,7 @@ void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable ) else nsAWritableCString::do_AppendFromReadable(aReadable); } +#endif /** @@ -962,6 +964,7 @@ void nsCString::InsertWithConversion(PRUnichar aChar,PRUint32 anOffset){ StrInsert(*this,anOffset,temp,0,1); } +#if 0 void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUint32 atPosition ) { if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) ) @@ -969,6 +972,7 @@ void nsCString::do_InsertFromReadable( const nsAReadableCString& aReadable, PRUi else nsAWritableCString::do_InsertFromReadable(aReadable, atPosition); } +#endif diff --git a/mozilla/xpcom/string/obsolete/nsString.h b/mozilla/xpcom/string/obsolete/nsString.h index 5c90e1e12f3..eb9928fa893 100644 --- a/mozilla/xpcom/string/obsolete/nsString.h +++ b/mozilla/xpcom/string/obsolete/nsString.h @@ -57,11 +57,10 @@ class NS_COM nsSubsumeCStr; class NS_COM nsCString : - public nsAWritableCString, + public nsAFlatCString, public nsStr { protected: - virtual const void* Implementation() const { return "nsCString"; } virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); @@ -306,7 +305,7 @@ public: nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; } nsCString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsCString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsCString& operator=( char aChar ) { Assign(aChar); return *this; } @@ -333,12 +332,14 @@ public: void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16 void AppendFloat( double aFloat ); - virtual void do_AppendFromReadable( const nsAReadableCString& ); void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset); // Why no |InsertWithConversion(PRUnichar*)|? +#if 0 + virtual void do_AppendFromReadable( const nsAReadableCString& ); virtual void do_InsertFromReadable( const nsAReadableCString&, PRUint32 ); +#endif /********************************************************************** @@ -490,7 +491,7 @@ public: void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED public: nsCAutoString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +// nsCAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; } @@ -574,7 +575,7 @@ public: nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); return *this; } nsSubsumeCStr& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeCStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsSubsumeCStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsSubsumeCStr& operator=( const char* aPtr ) { Assign(aPtr); return *this; } nsSubsumeCStr& operator=( char aChar ) { Assign(aChar); return *this; } private: diff --git a/mozilla/xpcom/string/obsolete/nsString2.h b/mozilla/xpcom/string/obsolete/nsString2.h index be4a9698aaa..798c13802b1 100644 --- a/mozilla/xpcom/string/obsolete/nsString2.h +++ b/mozilla/xpcom/string/obsolete/nsString2.h @@ -55,6 +55,10 @@ #include "nsAWritableString.h" #include "nsLiteralString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" +#endif + #ifdef STANDALONE_MI_STRING_TESTS class nsAReadableString { public: virtual ~nsAReadableString() { } }; class nsAWritableString : public nsAReadableString { public: virtual ~nsAWritableString() { } }; @@ -69,7 +73,7 @@ class nsISizeOfHandler; class NS_COM nsSubsumeStr; class NS_COM nsString : - public nsAWritableString, + public nsAFlatString, public nsStr { protected: @@ -343,7 +347,7 @@ public: nsString& operator=( const nsString& aString ) { Assign(aString); return *this; } nsString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } @@ -563,7 +567,7 @@ public: void operator=( char ); // NOT TO BE IMPLEMENTED public: nsAutoString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +// nsAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsAutoString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsAutoString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } @@ -596,7 +600,7 @@ class NS_COM NS_ConvertASCIItoUCS2 return GetUnicode(); } - operator nsLiteralString() const + operator const nsLiteralString() const { return nsLiteralString(mUStr, mLength); } @@ -685,7 +689,7 @@ public: nsSubsumeStr& operator=( const nsSubsumeStr& aReadable ) { Assign(aReadable); return *this; } nsSubsumeStr& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } +//nsSubsumeStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } nsSubsumeStr& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } nsSubsumeStr& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } private: diff --git a/mozilla/xpcom/string/public/MANIFEST b/mozilla/xpcom/string/public/MANIFEST index 6742f976d7e..cb9a692fd76 100644 --- a/mozilla/xpcom/string/public/MANIFEST +++ b/mozilla/xpcom/string/public/MANIFEST @@ -21,21 +21,29 @@ # +nsAFlatString.h nsAlgorithm.h -nsAString.h +nsAPromiseString.h nsAReadableString.h +nsAString.h nsAWritableString.h nsBufferHandle.h nsBufferHandleUtils.h nsCharTraits.h +nsCommonString.h nsFragmentedString.h nsLiteralString.h nsLocalString.h nsPrintfCString.h nsPrivateSharableString.h +nsPromiseConcatenation.h +nsPromiseFlatString.h +nsPromiseSubstring.h nsReadableUtils.h nsSharedBufferList.h nsSlidingString.h nsStringFragment.h +nsStringFwd.h nsStringIterator.h nsStringIteratorUtils.h +nsStringTraits.h diff --git a/mozilla/xpcom/string/public/Makefile.in b/mozilla/xpcom/string/public/Makefile.in index 394a6c8043b..8d13477a3b6 100644 --- a/mozilla/xpcom/string/public/Makefile.in +++ b/mozilla/xpcom/string/public/Makefile.in @@ -31,24 +31,32 @@ include $(DEPTH)/config/autoconf.mk MODULE = string EXPORTS = \ + nsAFlatString.h \ nsAlgorithm.h \ + nsAPromiseString.h \ + nsAReadableString.h \ nsAString.h \ - nsBufferHandle.h \ - nsBufferHandleUtils.h \ - nsPrivateSharableString.h \ + nsAWritableString.h \ + nsBufferHandle.h \ + nsBufferHandleUtils.h \ nsCharTraits.h \ - nsAReadableString.h \ - nsAWritableString.h \ - nsReadableUtils.h \ - nsSharedBufferList.h \ - nsSlidingString.h \ - nsFragmentedString.h \ - nsLiteralString.h \ - nsLocalString.h \ - nsPrintfCString.h \ - nsStringFragment.h \ - nsStringIterator.h \ - nsStringIteratorUtils.h \ + nsCommonString.h \ + nsFragmentedString.h \ + nsLiteralString.h \ + nsLocalString.h \ + nsPrintfCString.h \ + nsPrivateSharableString.h \ + nsPromiseConcatenation.h \ + nsPromiseFlatString.h \ + nsPromiseSubstring.h \ + nsReadableUtils.h \ + nsSharedBufferList.h \ + nsSlidingString.h \ + nsStringFragment.h \ + nsStringFwd.h \ + nsStringIterator.h \ + nsStringIteratorUtils.h \ + nsStringTraits.h \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/mozilla/xpcom/string/public/makefile.win b/mozilla/xpcom/string/public/makefile.win index ae1d7a2e561..37f2222ac6c 100644 --- a/mozilla/xpcom/string/public/makefile.win +++ b/mozilla/xpcom/string/public/makefile.win @@ -25,24 +25,32 @@ DEPTH=..\.. EXPORTS = \ + nsAFlatString.h \ nsAlgorithm.h \ - nsAString.h \ + nsAPromiseString.h \ nsAReadableString.h \ + nsAString.h \ nsAWritableString.h \ nsBufferHandle.h \ nsBufferHandleUtils.h \ nsCharTraits.h \ + nsCommonString.h \ nsFragmentedString.h \ nsLiteralString.h \ nsLocalString.h \ nsPrintfCString.h \ nsPrivateSharableString.h \ + nsPromiseConcatenation.h \ + nsPromiseFlatString.h \ + nsPromiseSubstring.h \ nsReadableUtils.h \ nsSharedBufferList.h \ nsSlidingString.h \ nsStringFragment.h \ + nsStringFwd.h \ nsStringIterator.h \ nsStringIteratorUtils.h \ + nsStringTraits.h \ $(NULL) include <$(DEPTH)\config\rules.mak> diff --git a/mozilla/xpcom/string/public/nsAReadableString.h b/mozilla/xpcom/string/public/nsAReadableString.h index 3b76ccce3f5..5133bc7d35b 100644 --- a/mozilla/xpcom/string/public/nsAReadableString.h +++ b/mozilla/xpcom/string/public/nsAReadableString.h @@ -24,1111 +24,25 @@ #ifndef nsAReadableString_h___ #define nsAReadableString_h___ -#ifndef nscore_h___ -#include "nscore.h" - // for |PRUnichar| +#ifndef nsAString_h___ +#include "nsAString.h" #endif -#ifndef nsCharTraits_h___ -#include "nsCharTraits.h" +typedef const nsAString nsAReadableString; +typedef const nsACString nsAReadableCString; + // what about the |const|? + +#ifndef nsPromiseSubstring_h___ +#include "nsPromiseSubstring.h" #endif -#ifndef nsPrivateSharableString_h___ -#include "nsPrivateSharableString.h" +#ifndef nsPromiseConcatenation_h___ +#include "nsPromiseConcatenation.h" #endif -#ifndef nsStringIterator_h___ -#include "nsStringIterator.h" +#ifndef nsPromiseFlatString_h___ +#include "nsPromiseFlatString.h" #endif -#include "nsMemory.h" - -/* - This file defines the abstract interfaces |nsAReadableString| and - |nsAReadableCString| (the 'A' is for 'abstract', as opposed to the 'I' in - [XP]COM interface names). - - These types are intended to be as source compatible as possible with the original - definitions of |const nsString&| and |const nsCString&|, respectively. In otherwords, - these interfaces provide only non-mutating access to the underlying strings. We - split the these interfaces out from the mutating parts (see - "nsAWritableString.h") because tests showed that we could exploit specialized - implementations in some areas; we need an abstract interface to bring the whole - family of strings together. - - |nsAReadableString| is a string of |PRUnichar|s. |nsAReadableCString| (note the - 'C') is a string of |char|s. -*/ - -template class basic_nsAReadableString; - -template class basic_nsAWritableString; - // ...because we sometimes use them as `out' params - -#ifdef _MSC_VER - // Under VC++, at the highest warning level, we are overwhelmed with warnings - // about a possible error when |operator->()| is used against something that - // doesn't have members, e.g., a |PRUnichar|. This is to be expected with - // templates, so we disable the warning. - #pragma warning( disable: 4284 ) -#endif - - - // - // nsAReadable[C]String - // - -template -class basic_nsAReadableString - : public nsPrivateSharableString - { - public: -// typedef CharT char_type; -// typedef PRUint32 size_type; -// typedef PRUint32 index_type; - - typedef nsReadingIterator const_iterator; - - - // basic_nsAReadableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAReadableString( const basic_nsAReadableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - private: - // NOT TO BE IMPLEMENTED - void operator=( const basic_nsAReadableString& ); // but assignment is _not_ OK (we're immutable) so make it impossible - - public: - virtual ~basic_nsAReadableString() { } - // ...yes, I expect to be sub-classed. - - nsReadingIterator& BeginReading( nsReadingIterator& ) const; - nsReadingIterator& EndReading( nsReadingIterator& ) const; - - virtual PRUint32 Length() const = 0; - PRBool IsEmpty() const; - - /** - * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. - * These signatures should be pushed down into interfaces that guarantee flat allocation. - * Clients at _this_ level should always use iterators. - */ - CharT CharAt( PRUint32 ) const; - CharT operator[]( PRUint32 ) const; - CharT First() const; - CharT Last() const; - - PRUint32 CountChar( CharT ) const; - - - /* - |Left|, |Mid|, and |Right| are annoying signatures that seem better almost - any _other_ way than they are now. Consider these alternatives - - aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| - aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| - Left(aReadable, 17, aWritable); // ...a global function that does the assignment - - as opposed to the current signature - - aReadable.Left(aWritable, 17); // ...a member function that does the assignment - - or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality - - aWritable = Substring(aReadable, 0, 17); - */ - - PRUint32 Left( basic_nsAWritableString&, PRUint32 ) const; - PRUint32 Mid( basic_nsAWritableString&, PRUint32, PRUint32 ) const; - PRUint32 Right( basic_nsAWritableString&, PRUint32 ) const; - - // Find( ... ) const; - PRInt32 FindChar( CharT, PRUint32 aOffset = 0 ) const; - // FindCharInSet( ... ) const; - // RFind( ... ) const; - // RFindChar( ... ) const; - // RFindCharInSet( ... ) const; - - - int Compare( const basic_nsAReadableString& rhs ) const; - int Compare( const CharT* ) const; -// int Compare( const CharT*, PRUint32 ) const; -// int Compare( CharT ) const; - - // |Equals()| is a synonym for |Compare()| - PRBool Equals( const basic_nsAReadableString& rhs ) const; - PRBool Equals( const CharT* ) const; -// PRBool Equals( const CharT*, PRUint32 ) const; -// PRBool Equals( CharT ) const; - - // Comparison operators are all synonyms for |Compare()| - PRBool operator!=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)!=0; } - PRBool operator< ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)< 0; } - PRBool operator<=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)<=0; } - PRBool operator==( const basic_nsAReadableString& rhs ) const { return Compare(rhs)==0; } - PRBool operator>=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)>=0; } - PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } - - - /* - Shouldn't be implemented because they're i18n sensitive. - Let's leave them in |nsString| for now. - */ - - // ToLowerCase - // ToUpperCase - // EqualsIgnoreCase - // IsASCII - // IsSpace - // IsAlpha - // IsDigit - // ToFloat - // ToInteger - - // char* ToNewCString() const; - // char* ToNewUTF8String() const; - // PRUnichar* ToNewUnicode() const; - // char* ToCString( char*, PRUint32, PRUint32 ) const; - - - /* - Shouldn't be implemented because it's wrong duplication. - Let's leave it in |nsString| for now. - */ - - // nsString* ToNewString() const; - // NO! The right way to say this is |new nsString( fromAReadableString )| - - - /* - Shouldn't be implemented because they're not generally applicable. - Let's leave them in |nsString| for now. - */ - - // IsOrdered - // BinarySearch - - // protected: - virtual const void* Implementation() const; - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return &aString == this; } -// virtual PRBool PromisesExactly( const basic_nsAReadableString& aString ) const { return false; } - - private: - // NOT TO BE IMPLEMENTED - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - PRUint32 CountChar( incompatible_char_type ) const; -// in Compare( incompatible_char_type ) const; -// PRBool Equals( incompatible_char_type ) const; - }; - - /* - The following macro defines a cast that helps us solve type-unification error problems on compilers - with poor template support. String clients probably _never_ need to use it. String implementors - sometimes will. - */ - -#ifdef NEED_CPP_TEMPLATE_CAST_TO_BASE -#define NS_READABLE_CAST(CharT, expr) (NS_STATIC_CAST(const basic_nsAReadableString&, (expr))) -#else -#define NS_READABLE_CAST(CharT, expr) (expr) -#endif - - /** - * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? - */ -template -inline -nsReadingIterator& -basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - -template -inline -nsReadingIterator& -basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - -template -inline -PRBool -basic_nsAReadableString::IsEmpty() const - { - return Length() == 0; - } - -template -inline -PRBool -basic_nsAReadableString::Equals( const basic_nsAReadableString& rhs ) const - { - return Length() == rhs.Length() && Compare(rhs) == 0; - } - -template -inline -PRBool -operator==( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() == rhs.get(); - } - -template -inline -PRBool -operator!=( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() != rhs.get(); - } - - -#define NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _CharT* rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), rhs) comp 0); \ - } - -#define NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _CharT* lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(lhs, NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - template NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - template NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_3_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - -#define NS_DEF_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - - -NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsAReadableString, CharT) - - - -template -const void* -basic_nsAReadableString::Implementation() const - { - return 0; - } - - - -template -CharT -basic_nsAReadableString::CharAt( PRUint32 aIndex ) const - { - NS_ASSERTION(aIndex iter; - return *(BeginReading(iter).advance(PRInt32(aIndex))); - } - -template -inline -CharT -basic_nsAReadableString::operator[]( PRUint32 aIndex ) const - { - return CharAt(aIndex); - } - -template -CharT -basic_nsAReadableString::First() const - { - NS_ASSERTION(Length()>0, "|First()| on an empty string"); - - nsReadingIterator iter; - return *BeginReading(iter); - } - -template -CharT -basic_nsAReadableString::Last() const - { - NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - - nsReadingIterator iter; - EndReading(iter); - - if ( !IsEmpty() ) - iter.advance(-1); - - return *iter; // Note: this has undefined results if |IsEmpty()| - } - -template -PRUint32 -basic_nsAReadableString::CountChar( CharT c ) const - { -#if 0 - nsReadingIterator countBegin, countEnd; - return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); -#else - PRUint32 result = 0; - PRUint32 lengthToExamine = Length(); - - nsReadingIterator iter; - for ( BeginReading(iter); ; ) - { - PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - const CharT* fromBegin = iter.get(); - result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); - if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) - return result; - iter.advance(lengthToExamineInThisFragment); - } - // never reached; quiets warnings - return 0; -#endif - } - -#if 0 - // had to move these definitions into "nsAWritableString.h" -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } -#endif - -template -PRInt32 -basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const - { - nsReadingIterator iter, done_searching; - BeginReading(iter).advance( PRInt32(aOffset) ); - EndReading(done_searching); - - PRUint32 lengthSearched = 0; - while ( iter != done_searching ) - { - PRInt32 fragmentLength = iter.size_forward(); - const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); - if ( charFoundAt ) - return lengthSearched + (charFoundAt-iter.get()) + aOffset; - - lengthSearched += fragmentLength; - iter.advance(fragmentLength); - } - - return -1; - } - - - - - - - - -#if 0 -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs, PRUint32 rhs_length ) const - { - return Compare(literal_string(rhs, rhs_length)) == 0; - } -#endif - -#if 0 -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs, PRUint32 rhs_length ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, literal_string(rhs, rhs_length))); - } -#endif - - - - // - // nsPromiseConcatenation - // - -template class nsPromiseReadable : public basic_nsAReadableString { }; - -template -class nsPromiseConcatenation - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS - - Instances of this class only exist as anonymous temporary results from |operator+()|. - This is the machinery that makes string concatenation efficient. No allocations or - character copies are required unless and until a final assignment is made. It works - its magic by overriding and forwarding calls to |GetReadableFragment()|. - - Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|. - - no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33| - - left to right evaluation is required ... do not use parentheses to override this - - In practice, neither of these is onerous. Parentheses do not change the semantics of the - concatenation, only the order in which the result is assembled ... so there's no reason - for a user to need to control it. Too many strings summed together can easily be worked - around with an intermediate assignment. I wouldn't have the parentheses limitation if I - assigned the identifier mask starting at the top, the first time anybody called - |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - enum { kLeftString, kRightString }; - - int - GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const - { - return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString; - } - - int - SetLeftStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask); - return kLeftString; - } - - int - SetRightStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask); - return kRightString; - } - - public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) - : mFragmentIdentifierMask(aMask) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - nsPromiseConcatenation( const nsPromiseConcatenation& aLeftString, const basic_nsAReadableString& aRightString ) - : mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - // nsPromiseConcatenation( const nsPromiseConcatenation& ); // auto-generated copy-constructor should be OK - // ~nsPromiseConcatenation(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseConcatenation& ); // we're immutable, you can't assign into a concatenation - - public: - - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& ) const; -// virtual PRBool PromisesExactly( const basic_nsAReadableString& ) const; - -// nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; - - PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; } - - private: - void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED - // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| - // which would break the algorithm for distributing bits in the fragment identifier - - private: - const basic_nsAReadableString* mStrings[2]; - PRUint32 mFragmentIdentifierMask; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseConcatenation, CharT) - -template -PRUint32 -nsPromiseConcatenation::Length() const - { - return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); - } - -template -PRBool -nsPromiseConcatenation::Promises( const basic_nsAReadableString& aString ) const - { - return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString); - } - -#if 0 -PRBool -nsPromiseConcatenation::PromisesExactly( const basic_nsAReadableString& aString ) const - { - // Not really like this, test for the empty string, etc - return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString; - } -#endif - -template -const CharT* -nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - int whichString; - - // based on the request, pick which string we will forward the |GetReadableFragment()| call into - - switch ( aRequest ) - { - case kPrevFragment: - case kNextFragment: - whichString = GetCurrentStringFromFragment(aFragment); - break; - - case kFirstFragment: - whichString = SetLeftStringInFragment(aFragment); - break; - - case kLastFragment: - whichString = SetRightStringInFragment(aFragment); - break; - - case kFragmentAt: - PRUint32 leftLength = mStrings[kLeftString]->Length(); - if ( aPosition < leftLength ) - whichString = SetLeftStringInFragment(aFragment); - else - { - whichString = SetRightStringInFragment(aFragment); - aPosition -= leftLength; - } - break; - - } - - const CharT* result; - PRBool done; - do - { - done = PR_TRUE; - result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition); - - if ( !result ) - { - done = PR_FALSE; - if ( aRequest == kNextFragment && whichString == kLeftString ) - { - aRequest = kFirstFragment; - whichString = SetRightStringInFragment(aFragment); - } - else if ( aRequest == kPrevFragment && whichString == kRightString ) - { - aRequest = kLastFragment; - whichString = SetLeftStringInFragment(aFragment); - } - else - done = PR_TRUE; - } - } - while ( !done ); - return result; - } - -#if 0 -template -inline -nsPromiseConcatenation -nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const - { - return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); - } -#endif - - - - - - // - // nsPromiseSubstring - // - -template -class nsPromiseSubstring - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS (mostly) - - ...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous - temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only - holds a pointer, no string data of its own. It does its magic by overriding and forwarding - calls to |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - public: - nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsPromiseSubstring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - : mString(aStart.string()) - { - nsReadingIterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } - - // nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK - // ~nsPromiseSubstring(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring - - public: - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return mString.Promises(aString); } - - private: - const basic_nsAReadableString& mString; - PRUint32 mStartPos; - PRUint32 mLength; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseSubstring, CharT) - -template -PRUint32 -nsPromiseSubstring::Length() const - { - return mLength; - } - -template -const CharT* -nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - // Offset any request for a specific position (First, Last, At) by our - // substrings startpos within the owning string - - if ( aRequest == kFirstFragment ) - { - aPosition = mStartPos; - aRequest = kFragmentAt; - } - else if ( aRequest == kLastFragment ) - { - aPosition = mStartPos + mLength; - aRequest = kFragmentAt; - } - else if ( aRequest == kFragmentAt ) - aPosition += mStartPos; - - // requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing - - const CharT* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition); - - // If |GetReadableFragment| returns |0|, then we are off the string, the contents of the - // fragment are garbage. - - // Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null - if ( position_ptr ) - { - // if there's more physical data in the returned fragment than I logically have left... - size_t logical_size_backward = aPosition - mStartPos; - if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward ) - aFragment.mStart = position_ptr - logical_size_backward; - - size_t logical_size_forward = mLength - logical_size_backward; - if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward ) - aFragment.mEnd = position_ptr + logical_size_forward; - } - - return position_ptr; - } - - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - #define NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T) \ - template \ - inline \ - nsPromiseConcatenation \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation(lhs, rhs); \ - } - - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring, nsPromiseSubstring) - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation, nsPromiseSubstring) - -#endif // NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - - // - // Global functions - // - -template -inline -PRBool -SameImplementation( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - const void* imp_tag = lhs.Implementation(); - return imp_tag && (imp_tag==rhs.Implementation()); - } - -inline -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) - { - return nsPromiseSubstring(aString, aStartPos, aSubstringLength); - } - -inline -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) - { - return nsPromiseSubstring(aString, aStartPos, aSubstringLength); - } - -inline -nsPromiseSubstring -Substring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return nsPromiseSubstring(aStart, aEnd); - } - -inline -nsPromiseSubstring -Substring( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return nsPromiseSubstring(aStart, aEnd); - } - -template -int -Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - if ( &lhs == &rhs ) - return 0; - - PRUint32 lLength = lhs.Length(); - PRUint32 rLength = rhs.Length(); - PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - - nsReadingIterator leftIter, rightIter; - lhs.BeginReading(leftIter); - rhs.BeginReading(rightIter); - - int result; - - for (;;) - { - PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) ); - - if ( lengthAvailable > lengthToCompare ) - lengthAvailable = lengthToCompare; - - // Note: |result| should be declared in this |if| expression, but some compilers don't like that - if ( (result = nsCharTraits::compare(leftIter.get(), rightIter.get(), lengthAvailable)) != 0 ) - return result; - - if ( !(lengthToCompare -= lengthAvailable) ) - break; - - leftIter.advance( PRInt32(lengthAvailable) ); - rightIter.advance( PRInt32(lengthAvailable) ); - } - - if ( lLength < rLength ) - return -1; - else if ( rLength < lLength ) - return 1; - else - return 0; - } - -template -inline -int -Compare( const basic_nsAReadableString& lhs, const CharT* rhs ) - { - return Compare(lhs, NS_READABLE_CAST(CharT, literal_string(rhs))); - } - -template -inline -int -Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) - { - return Compare(NS_READABLE_CAST(CharT, literal_string(lhs)), rhs); - } - -// XXX Note that these are located here because some compilers are -// sensitive to the ordering of declarations with regard to templates. -template -inline -int -basic_nsAReadableString::Compare( const basic_nsAReadableString& rhs ) const - { - return ::Compare(*this, rhs); - } - -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs ) const - { - return Compare(literal_string(rhs)) == 0; - } - -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, literal_string(rhs))); - } - - - - /* - How shall we provide |operator+()|? - - What would it return? It has to return a stack based object, because the client will - not be given an opportunity to handle memory management in an expression like - - myWritableString = stringA + stringB + stringC; - - ...so the `obvious' answer of returning a new |nsSharedString| is no good. We could - return an |nsString|, if that name were in scope here, though there's no telling what the client - will really want to do with the result. What might be better, though, - is to return a `promise' to concatenate some strings... - - By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle - assignment and other interesting uses within writable strings, plus we drastically reduce - the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings - in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work - to implement the virtual functions of readables. - */ - -template -inline -nsPromiseConcatenation -operator+( const nsPromiseConcatenation& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1); - } - -template -inline -nsPromiseConcatenation -operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs); - } - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - #define NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - inline \ - nsPromiseConcatenation<_CharT> \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation<_CharT>(lhs, rhs); \ - } - - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring<_CharT>, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, nsPromiseSubstring<_CharT>, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation<_CharT>, _StringT, _CharT) - - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String2T, _String1T, _CharT) - -#else - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) -#endif - - -#define kDefaultFlatStringSize 64 - -template -class basic_nsPromiseFlatString - : public basic_nsAReadableString - { - public: - explicit basic_nsPromiseFlatString( const basic_nsAReadableString& ); - - virtual - ~basic_nsPromiseFlatString( ) - { - if (mOwnsBuffer) - nsMemory::Free((void*)mBuffer); - } - - virtual PRUint32 Length() const { return mLength; } - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const; - - const CharT* get() const { return mBuffer; } - operator const CharT*() const { return get(); } // to be deprecated, prefer |get()| - - protected: - PRUint32 mLength; - const CharT* mBuffer; - PRBool mOwnsBuffer; - CharT mInlineBuffer[kDefaultFlatStringSize]; - }; - -template -basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsAReadableString& aString ) - : mLength(aString.Length()), - mOwnsBuffer(PR_FALSE) - { - typedef nsReadingIterator iterator; - - iterator start; - iterator end; - - aString.BeginReading(start); - aString.EndReading(end); - - // First count the number of buffers - PRInt32 buffer_count = 0; - while ( start != end ) - { - buffer_count++; - start.advance(start.size_forward()); - } - - // Now figure out what we want to do with the string - aString.BeginReading(start); - // XXX Not guaranteed null-termination in the first case - // If it's a single buffer, we just use the implementation's buffer - if ( buffer_count == 1 ) - mBuffer = start.get(); - // If it's too big for our inline buffer, we allocate a new one - else if ( mLength > kDefaultFlatStringSize-1 ) - { - CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - CharT* toBegin = result; - *copy_string(start, end, toBegin) = CharT(0); - - mBuffer = result; - mOwnsBuffer = PR_TRUE; - } - // Otherwise copy into our internal buffer - else - { - mBuffer = mInlineBuffer; - CharT* toBegin = &mInlineBuffer[0]; - copy_string( start, end, toBegin); - mInlineBuffer[mLength] = 0; - } - } - - -template -const CharT* -basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment& aFragment, - nsFragmentRequest aRequest, - PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mBuffer) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - - -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; - -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; - #endif // !defined(nsAReadableString_h___) diff --git a/mozilla/xpcom/string/public/nsAString.h b/mozilla/xpcom/string/public/nsAString.h index c9e909d007b..e63ebf7becb 100644 --- a/mozilla/xpcom/string/public/nsAString.h +++ b/mozilla/xpcom/string/public/nsAString.h @@ -23,6 +23,10 @@ #ifndef nsAString_h___ #define nsAString_h___ +#ifndef nsStringFwd_h___ +#include "nsStringFwd.h" +#endif + #ifndef nsPrivateSharableString_h___ #include "nsPrivateSharableString.h" #endif @@ -36,61 +40,723 @@ * */ -class nsAString +class NS_COM nsAString : public nsPrivateSharableString { public: - typedef PRUint32 size_type; + typedef nsAString self_type; + typedef nsAPromiseString promise_type; + typedef PRUnichar char_type; + typedef char incompatible_char_type; + + + typedef nsReadingIterator const_iterator; + typedef nsWritingIterator iterator; + + typedef PRUint32 size_type; + typedef PRUint32 index_type; + + - typedef nsReadingIterator const_iterator; - typedef nsWritingIterator iterator; // nsAString(); // auto-generated default constructor OK (we're abstract anyway) - // nsAString( const nsAString& ); // auto-generated copy-constructor OK (again, only because we're abstract) + // nsAString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract) virtual ~nsAString() { } // ...yes, I expect to be sub-classed - const_iterator& BeginReading( const_iterator& ) const; - const_iterator& EndReading( const_iterator& ) const; + inline const_iterator& BeginReading( const_iterator& ) const; + inline const_iterator& EndReading( const_iterator& ) const; - iterator& BeginWriting( iterator& ); - iterator& EndWriting( iterator& ); + inline iterator& BeginWriting( iterator& ); + inline iterator& EndWriting( iterator& ); virtual size_type Length() const = 0; - PRBool IsEmpty() const; + PRBool IsEmpty() const { return Length() == 0; } + + inline PRBool Equals( const self_type& ) const; - // ... + /** + * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. + * These signatures should be pushed down into interfaces that guarantee flat allocation. + * Clients at _this_ level should always use iterators. + */ + char_type First() const; + char_type Last() const; + + size_type CountChar( char_type ) const; + + + /* + |Left|, |Mid|, and |Right| are annoying signatures that seem better almost + any _other_ way than they are now. Consider these alternatives + + aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| + aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| + Left(aReadable, 17, aWritable); // ...a global function that does the assignment + + as opposed to the current signature + + aReadable.Left(aWritable, 17); // ...a member function that does the assignment + + or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality + + aWritable = Substring(aReadable, 0, 17); + */ + + size_type Left( self_type&, size_type ) const; + size_type Mid( self_type&, PRUint32, PRUint32 ) const; + size_type Right( self_type&, size_type ) const; + + // Find( ... ) const; + PRInt32 FindChar( char_type, index_type aOffset = 0 ) const; + // FindCharInSet( ... ) const; + // RFind( ... ) const; + // RFindChar( ... ) const; + // RFindCharInSet( ... ) const; + + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( size_type ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ + virtual void SetLength( size_type ) = 0; + + + void + Truncate( size_type aNewLength=0 ) + { + NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); + + if ( aNewLength < this->Length() ) + SetLength(aNewLength); + } + + + // PRBool SetCharAt( char_type, index_type ) = 0; + + + + // void ToLowerCase(); + // void ToUpperCase(); + + // void StripChars( const char_type* aSet ); + // void StripChar( ... ); + // void StripWhitespace(); + // void ReplaceChar( ... ); + // void ReplaceSubstring( ... ); + // void Trim( ... ); + // void CompressSet( ... ); + // void CompressWhitespace( ... ); + + + + // + // |Assign()|, |operator=()| + // + + void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); } + inline void Assign( const promise_type& aReadable ); + void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } + void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } + void Assign( char_type aChar ) { do_AssignFromElement(aChar); } + + // copy-assignment operator. I must define my own if I don't want the compiler to make me one + self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; } + + self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; } + self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; } + self_type& operator=( char_type aChar ) { Assign(aChar); return *this; } + + + + // + // |Append()|, |operator+=()| + // + + void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); } + inline void Append( const promise_type& aReadable ); + void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } + void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } + void Append( char_type aChar ) { do_AppendFromElement(aChar); } + + self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; } + self_type& operator+=( char_type aChar ) { Append(aChar); return *this; } + + + + /** + * The following index based routines need to be recast with iterators. + */ + + // + // |Insert()| + // Note: I would really like to move the |atPosition| parameter to the front of the argument list + // + + void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); } + inline void Insert( const promise_type& aReadable, index_type atPosition ); + void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } + void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } + void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); } + + + + virtual void Cut( index_type cutStart, size_type cutLength ); + + + + void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } +// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } + + private: + // NOT TO BE IMPLEMENTED + index_type CountChar( incompatible_char_type ) const; + void operator= ( incompatible_char_type ); + void Assign ( incompatible_char_type ); + void operator+= ( incompatible_char_type ); + void Append ( incompatible_char_type ); + void Insert ( incompatible_char_type, index_type ); + + + protected: + void AssignFromReadable( const self_type& ); + void AssignFromPromise( const self_type& ); + virtual void do_AssignFromReadable( const self_type& ); + virtual void do_AssignFromElementPtr( const char_type* ); + virtual void do_AssignFromElementPtrLength( const char_type*, size_type ); + virtual void do_AssignFromElement( char_type ); + + void AppendFromReadable( const self_type& ); + void AppendFromPromise( const self_type& ); + virtual void do_AppendFromReadable( const self_type& ); + virtual void do_AppendFromElementPtr( const char_type* ); + virtual void do_AppendFromElementPtrLength( const char_type*, size_type ); + virtual void do_AppendFromElement( char_type ); + + void InsertFromReadable( const self_type&, index_type ); + void InsertFromPromise( const self_type&, index_type ); + virtual void do_InsertFromReadable( const self_type&, index_type ); + virtual void do_InsertFromElementPtr( const char_type*, index_type ); + virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type ); + virtual void do_InsertFromElement( char_type, index_type ); + + void ReplaceFromReadable( index_type, size_type, const self_type& ); + void ReplaceFromPromise( index_type, size_type, const self_type& ); + virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& ); + + +// protected: + public: + virtual const char_type* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; + virtual char_type* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + virtual PRBool Promises( const self_type& aString ) const { return &aString == this; } }; +class NS_COM nsACString + : public nsPrivateSharableString + { + public: + typedef nsACString self_type; + typedef nsAPromiseCString promise_type; + typedef char char_type; + typedef PRUnichar incompatible_char_type; + + + typedef nsReadingIterator const_iterator; + typedef nsWritingIterator iterator; + + typedef PRUint32 size_type; + typedef PRUint32 index_type; + + + + + // nsACString(); // auto-generated default constructor OK (we're abstract anyway) + // nsACString( const self_type& ); // auto-generated copy-constructor OK (again, only because we're abstract) + virtual ~nsACString() { } // ...yes, I expect to be sub-classed + + inline const_iterator& BeginReading( const_iterator& ) const; + inline const_iterator& EndReading( const_iterator& ) const; + + inline iterator& BeginWriting( iterator& ); + inline iterator& EndWriting( iterator& ); + + virtual size_type Length() const = 0; + PRBool IsEmpty() const { return Length() == 0; } + + inline PRBool Equals( const self_type& ) const; + + + /** + * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. + * These signatures should be pushed down into interfaces that guarantee flat allocation. + * Clients at _this_ level should always use iterators. + */ + char_type First() const; + char_type Last() const; + + size_type CountChar( char_type ) const; + + + /* + |Left|, |Mid|, and |Right| are annoying signatures that seem better almost + any _other_ way than they are now. Consider these alternatives + + aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| + aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| + Left(aReadable, 17, aWritable); // ...a global function that does the assignment + + as opposed to the current signature + + aReadable.Left(aWritable, 17); // ...a member function that does the assignment + + or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality + + aWritable = Substring(aReadable, 0, 17); + */ + + size_type Left( self_type&, size_type ) const; + size_type Mid( self_type&, PRUint32, PRUint32 ) const; + size_type Right( self_type&, size_type ) const; + + // Find( ... ) const; + PRInt32 FindChar( char_type, PRUint32 aOffset = 0 ) const; + // FindCharInSet( ... ) const; + // RFind( ... ) const; + // RFindChar( ... ) const; + // RFindCharInSet( ... ) const; + + /** + * |SetCapacity| is not required to do anything; however, it can be used + * as a hint to the implementation to reduce allocations. + * |SetCapacity(0)| is a suggestion to discard all associated storage. + */ + virtual void SetCapacity( size_type ) { } + + /** + * |SetLength| is used in two ways: + * 1) to |Cut| a suffix of the string; + * 2) to prepare to |Append| or move characters around. + * + * External callers are not allowed to use |SetLength| is this latter capacity. + * Should this really be a public operation? + * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you + * override the |do_...| routines to not need this facility. + * + * This distinction makes me think the two different uses should be split into + * two distinct functions. + */ + virtual void SetLength( size_type ) = 0; + + + void + Truncate( size_type aNewLength=0 ) + { + NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); + + if ( aNewLength < this->Length() ) + SetLength(aNewLength); + } + + + // PRBool SetCharAt( char_type, index_type ) = 0; + + + + // void ToLowerCase(); + // void ToUpperCase(); + + // void StripChars( const char_type* aSet ); + // void StripChar( ... ); + // void StripWhitespace(); + // void ReplaceChar( ... ); + // void ReplaceSubstring( ... ); + // void Trim( ... ); + // void CompressSet( ... ); + // void CompressWhitespace( ... ); + + + + // + // |Assign()|, |operator=()| + // + + void Assign( const self_type& aReadable ) { AssignFromReadable(aReadable); } + inline void Assign( const promise_type& aReadable ); + void Assign( const char_type* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } + void Assign( const char_type* aPtr, size_type aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } + void Assign( char_type aChar ) { do_AssignFromElement(aChar); } + + // copy-assignment operator. I must define my own if I don't want the compiler to make me one + self_type& operator=( const self_type& aReadable ) { Assign(aReadable); return *this; } + + self_type& operator=( const promise_type& aReadable ) { Assign(aReadable); return *this; } + self_type& operator=( const char_type* aPtr ) { Assign(aPtr); return *this; } + self_type& operator=( char_type aChar ) { Assign(aChar); return *this; } + + + + // + // |Append()|, |operator+=()| + // + + void Append( const self_type& aReadable ) { AppendFromReadable(aReadable); } + inline void Append( const promise_type& aReadable ); + void Append( const char_type* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } + void Append( const char_type* aPtr, size_type aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } + void Append( char_type aChar ) { do_AppendFromElement(aChar); } + + self_type& operator+=( const self_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const promise_type& aReadable ) { Append(aReadable); return *this; } + self_type& operator+=( const char_type* aPtr ) { Append(aPtr); return *this; } + self_type& operator+=( char_type aChar ) { Append(aChar); return *this; } + + + + /** + * The following index based routines need to be recast with iterators. + */ + + // + // |Insert()| + // Note: I would really like to move the |atPosition| parameter to the front of the argument list + // + + void Insert( const self_type& aReadable, index_type atPosition ) { InsertFromReadable(aReadable, atPosition); } + inline void Insert( const promise_type& aReadable, index_type atPosition ); + void Insert( const char_type* aPtr, index_type atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } + void Insert( const char_type* aPtr, index_type atPosition, size_type aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } + void Insert( char_type aChar, index_type atPosition ) { do_InsertFromElement(aChar, atPosition); } + + + + virtual void Cut( index_type cutStart, size_type cutLength ); + + + + void Replace( index_type cutStart, size_type cutLength, const self_type& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } +// void Replace( index_type cutStart, size_type cutLength, const promise_type& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } + + private: + // NOT TO BE IMPLEMENTED + index_type CountChar( incompatible_char_type ) const; + void operator= ( incompatible_char_type ); + void Assign ( incompatible_char_type ); + void operator+= ( incompatible_char_type ); + void Append ( incompatible_char_type ); + void Insert ( incompatible_char_type, index_type ); + + + protected: + void AssignFromReadable( const self_type& ); + void AssignFromPromise( const self_type& ); + virtual void do_AssignFromReadable( const self_type& ); + virtual void do_AssignFromElementPtr( const char_type* ); + virtual void do_AssignFromElementPtrLength( const char_type*, size_type ); + virtual void do_AssignFromElement( char_type ); + + void AppendFromReadable( const self_type& ); + void AppendFromPromise( const self_type& ); + virtual void do_AppendFromReadable( const self_type& ); + virtual void do_AppendFromElementPtr( const char_type* ); + virtual void do_AppendFromElementPtrLength( const char_type*, size_type ); + virtual void do_AppendFromElement( char_type ); + + void InsertFromReadable( const self_type&, index_type ); + void InsertFromPromise( const self_type&, index_type ); + virtual void do_InsertFromReadable( const self_type&, index_type ); + virtual void do_InsertFromElementPtr( const char_type*, index_type ); + virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type ); + virtual void do_InsertFromElement( char_type, index_type ); + + void ReplaceFromReadable( index_type, size_type, const self_type& ); + void ReplaceFromPromise( index_type, size_type, const self_type& ); + virtual void do_ReplaceFromReadable( index_type, size_type, const self_type& ); + + +// protected: + public: + virtual const char_type* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; + virtual char_type* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; + virtual PRBool Promises( const self_type& aString ) const { return &aString == this; } + }; + +#include "nsAPromiseString.h" + +inline +void +nsAString::Assign( const nsAPromiseString& aReadable ) + { + AssignFromPromise(aReadable); + } + +inline +void +nsAString::Append( const nsAPromiseString& aReadable ) + { + AppendFromPromise(aReadable); + } + +inline +void +nsAString::Insert( const nsAPromiseString& aReadable, index_type atPosition ) + { + InsertFromPromise(aReadable, atPosition); + } + +inline +void +nsACString::Assign( const nsAPromiseCString& aReadable ) + { + AssignFromPromise(aReadable); + } + +inline +void +nsACString::Append( const nsAPromiseCString& aReadable ) + { + AppendFromPromise(aReadable); + } + +inline +void +nsACString::Insert( const nsAPromiseCString& aReadable, index_type atPosition ) + { + InsertFromPromise(aReadable, atPosition); + } + + + /** + * Note: measure -- should the |Begin...| and |End...| be |inline|? + */ +inline +nsAString::const_iterator& +nsAString::BeginReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } + +inline +nsAString::const_iterator& +nsAString::EndReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +inline +nsAString::iterator& +nsAString::BeginWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } + + +inline +nsAString::iterator& +nsAString::EndWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +NS_COM int Compare( const nsAString& lhs, const nsAString& rhs ); + +inline +PRBool +nsAString::Equals( const nsAString& rhs ) const + { + return Length()==rhs.Length() && Compare(*this, rhs)==0; + } + +inline +PRBool +operator!=( const nsAString& lhs, const nsAString& rhs ) + { + return !lhs.Equals(rhs); + } + +inline +PRBool +operator< ( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)< 0; + } + +inline +PRBool +operator<=( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)<=0; + } + +inline +PRBool +operator==( const nsAString& lhs, const nsAString& rhs ) + { + return lhs.Equals(rhs); + } + +inline +PRBool +operator>=( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)>=0; + } + +inline +PRBool +operator> ( const nsAString& lhs, const nsAString& rhs ) + { + return Compare(lhs, rhs)> 0; + } + +inline +nsAString::size_type +nsAString::Left( nsAString& aResult, size_type aLengthToCopy ) const + { + return Mid(aResult, 0, aLengthToCopy); + } + /** * */ -class nsACString - : public nsPrivateSharableString +inline +nsACString::const_iterator& +nsACString::BeginReading( const_iterator& aResult ) const { - public: - typedef PRUint32 size_type; + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } - typedef nsReadingIterator const_iterator; - typedef nsWritingIterator iterator; +inline +nsACString::const_iterator& +nsACString::EndReading( const_iterator& aResult ) const + { + aResult.mOwningString = this; + GetReadableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } - // nsACString(); // auto-generated default constructor OK (we're abstract anyway) - // nsACString( const nsACString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - virtual ~nsACString() { } // ...yes, I expect to be sub-classed +inline +nsACString::iterator& +nsACString::BeginWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kFirstFragment); + aResult.mPosition = aResult.mFragment.mStart; + aResult.normalize_forward(); + return aResult; + } - const_iterator& BeginReading( const_iterator& ) const; - const_iterator& EndReading( const_iterator& ) const; - iterator& BeginWriting( iterator& ); - iterator& EndWriting( iterator& ); +inline +nsACString::iterator& +nsACString::EndWriting( iterator& aResult ) + { + aResult.mOwningString = this; + GetWritableFragment(aResult.mFragment, kLastFragment); + aResult.mPosition = aResult.mFragment.mEnd; + // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| + return aResult; + } + +NS_COM int Compare( const nsACString& lhs, const nsACString& rhs ); + +inline +PRBool +nsACString::Equals( const self_type& rhs ) const + { + return Length()==rhs.Length() && Compare(*this, rhs)==0; + } + +inline +PRBool +operator!=( const nsACString& lhs, const nsACString& rhs ) + { + return !lhs.Equals(rhs); + } + +inline +PRBool +operator< ( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)< 0; + } + +inline +PRBool +operator<=( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)<=0; + } + +inline +PRBool +operator==( const nsACString& lhs, const nsACString& rhs ) + { + return lhs.Equals(rhs); + } + +inline +PRBool +operator>=( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)>=0; + } + +inline +PRBool +operator> ( const nsACString& lhs, const nsACString& rhs ) + { + return Compare(lhs, rhs)> 0; + } + +inline +nsACString::size_type +nsACString::Left( nsACString& aResult, size_type aLengthToCopy ) const + { + return Mid(aResult, 0, aLengthToCopy); + } - virtual size_type Length() const = 0; - PRBool IsEmpty() const; - - // ... - }; #endif // !defined(nsAString_h___) diff --git a/mozilla/xpcom/string/public/nsAWritableString.h b/mozilla/xpcom/string/public/nsAWritableString.h index b123dce5dbc..e8cd01cd33d 100644 --- a/mozilla/xpcom/string/public/nsAWritableString.h +++ b/mozilla/xpcom/string/public/nsAWritableString.h @@ -24,590 +24,11 @@ #ifndef nsAWritableString_h___ #define nsAWritableString_h___ - // See also... #ifndef nsAReadableString_h___ #include "nsAReadableString.h" #endif -#ifndef nsLiteralString_h___ -#include "nsLiteralString.h" -#endif - - -template class basic_nsAWritableString; - -/* - This file defines the abstract interfaces |nsAWritableString| and - |nsAWritableCString|. - - |nsAWritableString| is a string of |PRUnichar|s. |nsAWritableCString| (note the - 'C') is a string of |char|s. -*/ - -template -class basic_nsAWritableString - : public basic_nsAReadableString - /* - ... - */ - { - // friend class nsWritingIterator; - - public: - typedef CharT char_type; - typedef PRUint32 size_type; - typedef PRUint32 index_type; - - typedef nsWritingIterator iterator; - - // basic_nsAWritableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAWritableString( const basic_nsAWritableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - // ~basic_nsAWritableString(); // auto-generated destructor OK - // see below for copy-assignment operator - - virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - - /** - * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? - */ - nsWritingIterator& - BeginWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - - - nsWritingIterator& - EndWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - - - /** - * |SetCapacity| is not required to do anything; however, it can be used - * as a hint to the implementation to reduce allocations. - * |SetCapacity(0)| is a suggestion to discard all associated storage. - */ - virtual void SetCapacity( PRUint32 ) { } - - /** - * |SetLength| is used in two ways: - * 1) to |Cut| a suffix of the string; - * 2) to prepare to |Append| or move characters around. - * - * External callers are not allowed to use |SetLength| is this latter capacity. - * Should this really be a public operation? - * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you - * override the |do_...| routines to not need this facility. - * - * This distinction makes me think the two different uses should be split into - * two distinct functions. - */ - virtual void SetLength( PRUint32 ) = 0; - - - void - Truncate( PRUint32 aNewLength=0 ) - { - NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); - - if ( aNewLength < this->Length() ) - SetLength(aNewLength); - } - - - // PRBool SetCharAt( char_type, index_type ) = 0; - - - - // void ToLowerCase(); - // void ToUpperCase(); - - // void StripChars( const CharT* aSet ); - // void StripChar( ... ); - // void StripWhitespace(); - // void ReplaceChar( ... ); - // void ReplaceSubstring( ... ); - // void Trim( ... ); - // void CompressSet( ... ); - // void CompressWhitespace( ... ); - - - - // - // |Assign()|, |operator=()| - // - - void Assign( const basic_nsAReadableString& aReadable ) { AssignFromReadable(aReadable); } - void Assign( const nsPromiseReadable& aReadable ) { AssignFromPromise(aReadable); } - void Assign( const CharT* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } - void Assign( const CharT* aPtr, PRUint32 aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } - void Assign( CharT aChar ) { do_AssignFromElement(aChar); } - - // copy-assignment operator. I must define my own if I don't want the compiler to make me one - basic_nsAWritableString& operator=( const basic_nsAWritableString& aWritable ) { Assign(aWritable); return *this; } - - basic_nsAWritableString& operator=( const basic_nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const CharT* aPtr ) { Assign(aPtr); return *this; } - basic_nsAWritableString& operator=( CharT aChar ) { Assign(aChar); return *this; } - - - - // - // |Append()|, |operator+=()| - // - - void Append( const basic_nsAReadableString& aReadable ) { AppendFromReadable(aReadable); } - void Append( const nsPromiseReadable& aReadable ) { AppendFromPromise(aReadable); } - void Append( const CharT* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } - void Append( const CharT* aPtr, PRUint32 aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } - void Append( CharT aChar ) { do_AppendFromElement(aChar); } - - basic_nsAWritableString& operator+=( const basic_nsAReadableString& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const nsPromiseReadable& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const CharT* aPtr ) { Append(aPtr); return *this; } - basic_nsAWritableString& operator+=( CharT aChar ) { Append(aChar); return *this; } - - - - /** - * The following index based routines need to be recast with iterators. - */ - - // - // |Insert()| - // Note: I would really like to move the |atPosition| parameter to the front of the argument list - // - - void Insert( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) { InsertFromReadable(aReadable, atPosition); } - void Insert( const nsPromiseReadable& aReadable, PRUint32 atPosition ) { InsertFromPromise(aReadable, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } - void Insert( CharT aChar, PRUint32 atPosition ) { do_InsertFromElement(aChar, atPosition); } - - - - virtual void Cut( PRUint32 cutStart, PRUint32 cutLength ); - - - - void Replace( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } - void Replace( PRUint32 cutStart, PRUint32 cutLength, const nsPromiseReadable& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } - - private: - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - - // NOT TO BE IMPLEMENTED - void operator= ( incompatible_char_type ); - void Assign ( incompatible_char_type ); - void operator+= ( incompatible_char_type ); - void Append ( incompatible_char_type ); - void Insert ( incompatible_char_type, PRUint32 ); - - - protected: - void AssignFromReadable( const basic_nsAReadableString& ); - void AssignFromPromise( const basic_nsAReadableString& ); - virtual void do_AssignFromReadable( const basic_nsAReadableString& ); - virtual void do_AssignFromElementPtr( const CharT* ); - virtual void do_AssignFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AssignFromElement( CharT ); - - void AppendFromReadable( const basic_nsAReadableString& ); - void AppendFromPromise( const basic_nsAReadableString& ); - virtual void do_AppendFromReadable( const basic_nsAReadableString& ); - virtual void do_AppendFromElementPtr( const CharT* ); - virtual void do_AppendFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AppendFromElement( CharT ); - - void InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - void InsertFromPromise( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromElementPtr( const CharT*, PRUint32 ); - virtual void do_InsertFromElementPtrLength( const CharT*, PRUint32, PRUint32 ); - virtual void do_InsertFromElement( CharT, PRUint32 ); - - void ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - void ReplaceFromPromise( PRUint32, PRUint32, const basic_nsAReadableString& ); - virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - }; - - - - - - // - // |Assign()| - // - -template -void -basic_nsAWritableString::AssignFromReadable( const basic_nsAReadableString& rhs ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &rhs ) - do_AssignFromReadable(rhs); - // else, self-assign is a no-op - } - -template -void -basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString& aReadable ) - /* - ...this function is only called when a promise that somehow references |this| is assigned _into_ |this|. - E.g., - - ... writable& w ... - ... readable& r ... - - w = r + w; - - In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before - anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents - of |r| before being retrieved to be appended. - - We could have a really tricky solution where we tell the promise to resolve _just_ the data promised - by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g., - in the case above, |Insert| could have special behavior with significantly better performance. Since - it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the - entire promise. If we measure and this turns out to show up on performance radar, we then have the - option to fix either the callers or this mechanism. - */ - { - if ( !aReadable.Promises(*this) ) - do_AssignFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - // Note: not exception safe. We need something to manage temporary buffers like this - - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AssignFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableString& aReadable ) - { - SetLength(0); - SetLength(aReadable.Length()); - // first setting the length to |0| avoids copying characters only to be overwritten later - // in the case where the implementation decides to re-allocate - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtr( const CharT* aPtr ) - { - do_AssignFromReadable(literal_string(aPtr)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtrLength( const CharT* aPtr, PRUint32 aLength ) - { - do_AssignFromReadable(literal_string(aPtr, aLength)); - } - -template -void -basic_nsAWritableString::do_AssignFromElement( CharT aChar ) - { - do_AssignFromReadable(literal_string(&aChar, 1)); - } - - - - // - // |Append()| - // - -template -void -basic_nsAWritableString::AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_AppendFromReadable(aReadable); - else - AppendFromPromise(aReadable); - } - -template -void -basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_AppendFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AppendFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtr( const CharT* aChar ) - { - do_AppendFromReadable(literal_string(aChar)); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtrLength( const CharT* aChar, PRUint32 aLength ) - { - do_AppendFromReadable(literal_string(aChar, aLength)); - } - -template -void -basic_nsAWritableString::do_AppendFromElement( CharT aChar ) - { - do_AppendFromReadable(literal_string(&aChar, 1)); - } - - - - // - // |Insert()| - // - -template -void -basic_nsAWritableString::InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_InsertFromReadable(aReadable, atPosition); - else - InsertFromPromise(aReadable, atPosition); - } - -template -void -basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( !aReadable.Promises(*this) ) - do_InsertFromReadable(aReadable, atPosition); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_InsertFromElementPtrLength(buffer, atPosition, length); - delete buffer; - } - // else assert - } - } - -template -void -basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); - else - atPosition = oldLength; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtr( const CharT* aPtr, PRUint32 atPosition ) - { - do_InsertFromReadable(literal_string(aPtr), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtrLength( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) - { - do_InsertFromReadable(literal_string(aPtr, aLength), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElement( CharT aChar, PRUint32 atPosition ) - { - do_InsertFromReadable(literal_string(&aChar, 1), atPosition); - } - - - - // - // |Cut()| - // - -template -void -basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) - { - PRUint32 myLength = this->Length(); - cutLength = NS_MIN(cutLength, myLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutEnd < myLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - SetLength(myLength-cutLength); - } - - - - // - // |Replace()| - // - -template -void -basic_nsAWritableString::ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReplacement ) - do_ReplaceFromReadable(cutStart, cutLength, aReplacement); - else - ReplaceFromPromise(cutStart, cutLength, aReplacement); - } - -template -void -basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_ReplaceFromReadable(cutStart, cutLength, aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_ReplaceFromReadable(cutStart, cutLength, literal_string(buffer, length)); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - PRUint32 oldLength = this->Length(); - - cutStart = NS_MIN(cutStart, oldLength); - cutLength = NS_MIN(cutLength, oldLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - PRUint32 replacementLength = aReplacement.Length(); - PRUint32 replacementEnd = cutStart + replacementLength; - - PRUint32 newLength = oldLength - cutLength + replacementLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutLength > replacementLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - SetLength(newLength); - if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - - copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - } - - -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } - - - - - // - // Types - // - -typedef basic_nsAWritableString nsAWritableString; -typedef basic_nsAWritableString nsAWritableCString; +typedef nsAString nsAWritableString; +typedef nsACString nsAWritableCString; #endif // !defined(nsAWritableString_h___) diff --git a/mozilla/xpcom/string/public/nsBufferHandleUtils.h b/mozilla/xpcom/string/public/nsBufferHandleUtils.h index 6f05fabe22a..06e37e94b10 100644 --- a/mozilla/xpcom/string/public/nsBufferHandleUtils.h +++ b/mozilla/xpcom/string/public/nsBufferHandleUtils.h @@ -25,9 +25,12 @@ #ifndef nsBufferHandleUtils_h___ #define nsBufferHandleUtils_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |basic_nsAReadableString|... +#ifndef nsAString_h___ +#include "nsAString.h" +#endif + +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" #endif #include @@ -62,21 +65,22 @@ NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr ) return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr)); } -template +template HandleT* -NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic_nsAReadableString& aDataSource, PRUint32 aAdditionalCapacity ) +NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const StringT& aDataSource, PRUint32 aAdditionalCapacity ) { - typedef CharT* CharT_ptr; + typedef typename StringT::char_type char_type; + typedef char_type* char_ptr; // figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part - size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, CharT_ptr(0)); + size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, char_ptr(0)); - // figure out how many |CharT|s wee need to fit in the data part + // figure out how many |char_type|s wee need to fit in the data part size_t data_length = aDataSource.Length(); size_t buffer_length = data_length + aAdditionalCapacity; // how many bytes is that (including a zero-terminator so we can claim to be flat)? - size_t buffer_size = buffer_length * sizeof(CharT); + size_t buffer_size = buffer_length * sizeof(char_type); HandleT* result = 0; @@ -84,17 +88,17 @@ NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic if ( handle_ptr ) { - CharT* data_start_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); - CharT* data_end_ptr = data_start_ptr + data_length; - CharT* buffer_end_ptr = data_start_ptr + buffer_length; + char_ptr data_start_ptr = char_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); + char_ptr data_end_ptr = data_start_ptr + data_length; + char_ptr buffer_end_ptr = data_start_ptr + buffer_length; - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = data_start_ptr; + StringT::const_iterator fromBegin, fromEnd; + char_ptr toBegin = data_start_ptr; copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin); // and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate if ( aAdditionalCapacity > 0 ) - *toBegin = CharT(0); + *toBegin = char_type(0); result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, data_start_ptr, buffer_end_ptr, PR_TRUE); } diff --git a/mozilla/xpcom/string/public/nsCharTraits.h b/mozilla/xpcom/string/public/nsCharTraits.h index 964c6be8646..bcebf129a78 100644 --- a/mozilla/xpcom/string/public/nsCharTraits.h +++ b/mozilla/xpcom/string/public/nsCharTraits.h @@ -39,6 +39,8 @@ #include "nsStringIteratorUtils.h" #endif +class nsAString; +class nsACString; #ifdef HAVE_CPP_BOOL typedef bool nsCharTraits_bool; @@ -49,8 +51,8 @@ template struct nsCharTraits { - typedef CharT char_type; - typedef char incompatible_char_type; + typedef CharT char_type; + typedef char incompatible_char_type; static void @@ -214,8 +216,8 @@ struct nsCharTraits NS_SPECIALIZE_TEMPLATE struct nsCharTraits { - typedef char char_type; - typedef PRUnichar incompatible_char_type; + typedef char char_type; + typedef PRUnichar incompatible_char_type; static void @@ -341,7 +343,7 @@ struct nsCharTraits NS_SPECIALIZE_TEMPLATE struct nsCharTraits { - typedef wchar_t char_type; + typedef wchar_t char_type; static void diff --git a/mozilla/xpcom/string/public/nsDependentString.h b/mozilla/xpcom/string/public/nsDependentString.h index 6e44379e262..e380a36c9c3 100644 --- a/mozilla/xpcom/string/public/nsDependentString.h +++ b/mozilla/xpcom/string/public/nsDependentString.h @@ -23,8 +23,8 @@ #ifndef nsLocalString_h___ #define nsLocalString_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" #endif /* @@ -46,10 +46,11 @@ */ class NS_COM nsLocalString - : public basic_nsAReadableString + : public nsAFlatString { protected: virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -84,10 +85,7 @@ class NS_COM nsLocalString public: virtual PRUint32 Length() const; - - - const PRUnichar* get() const { return mStart; } - operator const PRUnichar*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const PRUnichar* mStart; @@ -97,10 +95,11 @@ class NS_COM nsLocalString class NS_COM nsLocalCString - : public basic_nsAReadableString + : public nsAFlatCString { protected: virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -135,10 +134,7 @@ class NS_COM nsLocalCString public: virtual PRUint32 Length() const; - - - const char* get() const { return mStart; } - operator const char*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const char* mStart; diff --git a/mozilla/xpcom/string/public/nsFragmentedString.h b/mozilla/xpcom/string/public/nsFragmentedString.h index e5348b42f48..0dd1ca183cd 100644 --- a/mozilla/xpcom/string/public/nsFragmentedString.h +++ b/mozilla/xpcom/string/public/nsFragmentedString.h @@ -27,8 +27,8 @@ // WORK IN PROGRESS -#ifndef nsAWritableString_h___ -#include "nsAWritableString.h" +#ifndef nsAString_h___ +#include "nsAString.h" #endif #ifndef nsSharedBufferList_h___ @@ -37,7 +37,7 @@ class nsFragmentedString - : public basic_nsAWritableString + : public nsAString /* ... */ diff --git a/mozilla/xpcom/string/public/nsLiteralString.h b/mozilla/xpcom/string/public/nsLiteralString.h index 53a735ba4f1..7f772b8d9b5 100644 --- a/mozilla/xpcom/string/public/nsLiteralString.h +++ b/mozilla/xpcom/string/public/nsLiteralString.h @@ -34,37 +34,24 @@ typedef const nsLocalString nsLiteralString; typedef const nsLocalCString nsLiteralCString; -template -struct nsLiteralStringTraits - { - }; - -NS_SPECIALIZE_TEMPLATE -struct nsLiteralStringTraits - { - typedef nsLiteralString literal_string_type; - }; - -NS_SPECIALIZE_TEMPLATE -struct nsLiteralStringTraits - { - typedef nsLiteralCString literal_string_type; - }; +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif template inline -const typename nsLiteralStringTraits::literal_string_type +const typename nsStringTraits::literal_string_type literal_string( const CharT* aPtr ) { - return nsLiteralStringTraits::literal_string_type(aPtr); + return nsStringTraits::literal_string_type(aPtr); } template inline -const typename nsLiteralStringTraits::literal_string_type +const typename nsStringTraits::literal_string_type literal_string( const CharT* aPtr, PRUint32 aLength ) { - return nsLiteralStringTraits::literal_string_type(aPtr, aLength); + return nsStringTraits::literal_string_type(aPtr, aLength); } #ifdef HAVE_CPP_2BYTE_WCHAR_T diff --git a/mozilla/xpcom/string/public/nsLocalString.h b/mozilla/xpcom/string/public/nsLocalString.h index 6e44379e262..e380a36c9c3 100644 --- a/mozilla/xpcom/string/public/nsLocalString.h +++ b/mozilla/xpcom/string/public/nsLocalString.h @@ -23,8 +23,8 @@ #ifndef nsLocalString_h___ #define nsLocalString_h___ -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" +#ifndef nsAFlatString_h___ +#include "nsAFlatString.h" #endif /* @@ -46,10 +46,11 @@ */ class NS_COM nsLocalString - : public basic_nsAReadableString + : public nsAFlatString { protected: virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -84,10 +85,7 @@ class NS_COM nsLocalString public: virtual PRUint32 Length() const; - - - const PRUnichar* get() const { return mStart; } - operator const PRUnichar*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const PRUnichar* mStart; @@ -97,10 +95,11 @@ class NS_COM nsLocalString class NS_COM nsLocalCString - : public basic_nsAReadableString + : public nsAFlatCString { protected: virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; + virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ) { } public: @@ -135,10 +134,7 @@ class NS_COM nsLocalCString public: virtual PRUint32 Length() const; - - - const char* get() const { return mStart; } - operator const char*() const { return get(); } // to be deprecated, prefer |get()| + virtual void SetLength( size_type ) { } private: const char* mStart; diff --git a/mozilla/xpcom/string/public/nsSharedBufferList.h b/mozilla/xpcom/string/public/nsSharedBufferList.h index 5a5ad9330c5..4fda3118cb8 100755 --- a/mozilla/xpcom/string/public/nsSharedBufferList.h +++ b/mozilla/xpcom/string/public/nsSharedBufferList.h @@ -35,13 +35,12 @@ // for |PRUnichar| #endif -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |nsReadingIterator| +#ifndef nsAString_h___ +#include "nsAString.h" #endif -#ifndef nsLiteralString_h___ -#include "nsLiteralString.h" +#ifndef nsLocalString_h___ +#include "nsLocalString.h" #endif #ifndef nsBufferHandleUtils_h___ @@ -184,12 +183,12 @@ class NS_COM nsSharedBufferList NewSingleAllocationBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalCapacity = 1 ) { typedef Buffer* Buffer_ptr; - return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), NS_READABLE_CAST(PRUnichar, literal_string(aData, aDataLength)), aAdditionalCapacity); + return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), nsLocalString(aData, aDataLength), aAdditionalCapacity); } static Buffer* - NewSingleAllocationBuffer( const nsAReadableString& aReadable, PRUint32 aAdditionalCapacity = 1 ) + NewSingleAllocationBuffer( const nsAString& aReadable, PRUint32 aAdditionalCapacity = 1 ) { typedef Buffer* Buffer_ptr; return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), aReadable, aAdditionalCapacity); diff --git a/mozilla/xpcom/string/public/nsSlidingString.h b/mozilla/xpcom/string/public/nsSlidingString.h index 079e7e2f1eb..4c0d24f1797 100755 --- a/mozilla/xpcom/string/public/nsSlidingString.h +++ b/mozilla/xpcom/string/public/nsSlidingString.h @@ -69,7 +69,7 @@ class nsSlidingString; * a substring over a buffer list, this */ class NS_COM nsSlidingSubstring - : virtual public nsPromiseReadable + : virtual public nsAPromiseString { friend class nsSlidingString; @@ -154,7 +154,7 @@ class NS_COM nsSlidingSubstring * */ class NS_COM nsSlidingString - : virtual public nsPromiseReadable, + : virtual public nsAPromiseString, private nsSlidingSubstring { friend class nsSlidingSubstring; diff --git a/mozilla/xpcom/string/public/nsStringIterator.h b/mozilla/xpcom/string/public/nsStringIterator.h index 316bd540465..4f777635cdd 100644 --- a/mozilla/xpcom/string/public/nsStringIterator.h +++ b/mozilla/xpcom/string/public/nsStringIterator.h @@ -27,14 +27,21 @@ #include "nsStringFragment.h" #endif +#ifndef nsCharTraits_h___ +#include "nsCharTraits.h" +#endif + +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif + #ifndef nsAlgorithm_h___ #include "nsAlgorithm.h" // for |NS_MIN|, |NS_MAX|, and |NS_COUNT|... #endif -template class basic_nsAReadableString; -template class basic_nsAWritableString; + @@ -56,11 +63,13 @@ class nsReadingIterator // typedef bidirectional_iterator_tag iterator_category; private: - friend class basic_nsAReadableString; + friend class nsAString; + friend class nsACString; + typedef typename nsStringTraits::abstract_string_type string_type; - nsReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; + nsReadableFragment mFragment; + const CharT* mPosition; + const string_type* mOwningString; public: nsReadingIterator() { } @@ -132,7 +141,7 @@ class nsReadingIterator return mFragment; } - const basic_nsAReadableString& + const string_type& string() const { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); @@ -155,8 +164,8 @@ class nsReadingIterator advance( difference_type n ) { while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); + { + difference_type one_hop = NS_MIN(n, size_forward()); NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); // perhaps I should |break| if |!one_hop|? @@ -194,11 +203,13 @@ class nsWritingIterator // typedef bidirectional_iterator_tag iterator_category; private: - friend class basic_nsAWritableString; + friend class nsAString; + friend class nsACString; + typedef typename nsStringTraits::abstract_string_type string_type; - nsWritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; + nsWritableFragment mFragment; + CharT* mPosition; + string_type* mOwningString; public: nsWritingIterator() { } @@ -276,14 +287,14 @@ class nsWritingIterator return mFragment; } - const basic_nsAWritableString& + const string_type& string() const { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); return *mOwningString; } - basic_nsAWritableString& + string_type& string() { NS_ASSERTION(mOwningString, "iterator not attached to a string (|mOwningString| == 0)"); @@ -364,6 +375,22 @@ nsReadingIterator::normalize_backward() mPosition = mFragment.mEnd; } +template +inline +PRBool +operator==( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) + { + return lhs.get() == rhs.get(); + } + +template +inline +PRBool +operator!=( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) + { + return lhs.get() != rhs.get(); + } + // // |nsWritingIterator|s diff --git a/mozilla/xpcom/string/src/Makefile.in b/mozilla/xpcom/string/src/Makefile.in index 16189711271..95adc2aa6f0 100644 --- a/mozilla/xpcom/string/src/Makefile.in +++ b/mozilla/xpcom/string/src/Makefile.in @@ -34,6 +34,8 @@ LIBRARY_NAME = string_s REQUIRES = xpcom CPPSRCS = \ + nsAString.cpp \ + nsCommonString.cpp \ nsLocalString.cpp \ nsFragmentedString.cpp \ nsPrintfCString.cpp \ diff --git a/mozilla/xpcom/string/src/makefile.win b/mozilla/xpcom/string/src/makefile.win index d4cd1a950d1..fa8056981e9 100644 --- a/mozilla/xpcom/string/src/makefile.win +++ b/mozilla/xpcom/string/src/makefile.win @@ -29,6 +29,8 @@ LIBRARY_NAME=string_s LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN CPP_OBJS = \ + .\$(OBJDIR)\nsAString.obj \ + .\$(OBJDIR)\nsCommonString.obj \ .\$(OBJDIR)\nsLocalString.obj \ .\$(OBJDIR)\nsFragmentedString.obj \ .\$(OBJDIR)\nsPrintfCString.obj \ diff --git a/mozilla/xpcom/string/src/nsReadableUtils.cpp b/mozilla/xpcom/string/src/nsReadableUtils.cpp index 4ffde71a5b6..8e2f50892f6 100755 --- a/mozilla/xpcom/string/src/nsReadableUtils.cpp +++ b/mozilla/xpcom/string/src/nsReadableUtils.cpp @@ -26,6 +26,11 @@ #include "nsString.h" #include "nsCRT.h" +#ifndef nsStringTraits_h___ +#include "nsStringTraits.h" +#endif + + template class CalculateLength { @@ -106,7 +111,7 @@ class LossyConvertEncoding NS_COM void -CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) +CopyUCS2toASCII( const nsAString& aSource, nsAWritableCString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); @@ -121,7 +126,7 @@ CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) NS_COM void -CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) +CopyASCIItoUCS2( const nsACString& aSource, nsAWritableString& aDest ) { // right now, this won't work on multi-fragment destinations aDest.SetLength(aSource.Length()); @@ -142,10 +147,10 @@ CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) * @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|. * */ -template +template inline ToCharT* -AllocateStringCopy( const basic_nsAReadableString& aSource, ToCharT* ) +AllocateStringCopy( const FromStringT& aSource, ToCharT* ) { return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT))); } @@ -153,7 +158,7 @@ AllocateStringCopy( const basic_nsAReadableString& aSource, ToCharT* NS_COM char* -ToNewCString( const nsAReadableString& aSource ) +ToNewCString( const nsAString& aSource ) { char* result = AllocateStringCopy(aSource, (char*)0); @@ -165,7 +170,7 @@ ToNewCString( const nsAReadableString& aSource ) NS_COM char* -ToNewUTF8String( const nsAReadableString& aSource ) +ToNewUTF8String( const nsAString& aSource ) { NS_ConvertUCS2toUTF8 temp(aSource); @@ -189,7 +194,7 @@ ToNewUTF8String( const nsAReadableString& aSource ) NS_COM char* -ToNewCString( const nsAReadableCString& aSource ) +ToNewCString( const nsACString& aSource ) { // no conversion needed, just allocate a buffer of the correct length and copy into it @@ -203,7 +208,7 @@ ToNewCString( const nsAReadableCString& aSource ) NS_COM PRUnichar* -ToNewUnicode( const nsAReadableString& aSource ) +ToNewUnicode( const nsAString& aSource ) { // no conversion needed, just allocate a buffer of the correct length and copy into it @@ -217,7 +222,7 @@ ToNewUnicode( const nsAReadableString& aSource ) NS_COM PRUnichar* -ToNewUnicode( const nsAReadableCString& aSource ) +ToNewUnicode( const nsACString& aSource ) { PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); @@ -229,7 +234,7 @@ ToNewUnicode( const nsAReadableCString& aSource ) NS_COM PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength ) +CopyUnicodeTo( const nsAString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength ) { nsReadingIterator fromBegin, fromEnd; PRUnichar* toBegin = aDest; @@ -268,7 +273,7 @@ AppendUnicodeTo( const nsReadingIterator& aSrcStart, NS_COM PRBool -IsASCII( const nsAReadableString& aString ) +IsASCII( const nsAString& aString ) { static const PRUnichar NOT_ASCII = PRUnichar(~0x007F); @@ -375,7 +380,7 @@ ToLowerCase( nsAWritableCString& aCString ) template inline // probably wishful thinking PRBool -FindInReadable_Impl( const basic_nsAReadableString& aPattern, +FindInReadable_Impl( const typename nsStringTraits::abstract_string_type& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { @@ -443,14 +448,14 @@ FindInReadable_Impl( const basic_nsAReadableString& aPattern, NS_COM PRBool -FindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +FindInReadable( const nsAString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } NS_COM PRBool -FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +FindInReadable( const nsACString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } @@ -463,7 +468,7 @@ FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSe template inline // probably wishful thinking PRBool -RFindInReadable_Impl( const basic_nsAReadableString& aPattern, +RFindInReadable_Impl( const typename nsStringTraits::abstract_string_type& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { @@ -499,14 +504,14 @@ RFindInReadable_Impl( const basic_nsAReadableString& aPattern, NS_COM PRBool -RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +RFindInReadable( const nsAString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } NS_COM PRBool -RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) +RFindInReadable( const nsACString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) { return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); } @@ -557,7 +562,7 @@ FindCharInReadable( char aChar, nsReadingIterator& aSearchStart, const nsR template PRUint32 -CountCharInReadable_Impl( const basic_nsAReadableString& aStr, +CountCharInReadable_Impl( const typename nsStringTraits::abstract_string_type& aStr, CharT aChar ) { PRUint32 count = 0; @@ -578,7 +583,7 @@ CountCharInReadable_Impl( const basic_nsAReadableString& aStr, NS_COM PRUint32 -CountCharInReadable( const nsAReadableString& aStr, +CountCharInReadable( const nsAString& aStr, PRUnichar aChar ) { return CountCharInReadable_Impl(aStr, aChar); @@ -586,7 +591,7 @@ CountCharInReadable( const nsAReadableString& aStr, NS_COM PRUint32 -CountCharInReadable( const nsAReadableCString& aStr, +CountCharInReadable( const nsACString& aStr, char aChar ) { return CountCharInReadable_Impl(aStr, aChar);