diff --git a/base/src/nsStr.cpp b/base/src/nsStr.cpp index e4b976254248..79e7afc99107 100644 --- a/base/src/nsStr.cpp +++ b/base/src/nsStr.cpp @@ -31,101 +31,9 @@ #include "nsStr.h" #include "bufferRoutines.h" #include "stdio.h" //only used for printf -#include "nsDeque.h" -#include "nsCRT.h" static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer."; -//---------------------------------------------------------------------------------------- -// The following is a memory agent who knows how to recycled (pool) freed memory... -//---------------------------------------------------------------------------------------- - -/************************************************************** - Define the char* (pooled) deallocator class... - **************************************************************/ -class nsBufferDeallocator: public nsDequeFunctor{ -public: - virtual void* operator()(void* anObject) { - char* aCString= (char*)anObject; - delete [] aCString; - return 0; - } -}; - -/** - * - * @update gess10/30/98 - * @param - * @return - */ -class nsPoolingMemoryAgent : public nsMemoryAgent{ -public: - nsPoolingMemoryAgent() { - memset(mPools,0,sizeof(mPools)); - } - - ~nsPoolingMemoryAgent() { - nsBufferDeallocator theDeallocator; - int i=0; - for(i=0;i<10;i++){ - if(mPools[i]){ - mPools[i]->ForEach(theDeallocator); //now delete the buffers - } - delete mPools[i]; - mPools[i]=0; - } - } - - virtual PRBool Alloc(nsStr& aDest,PRInt32 aCount) { - - //we're given the acount value in charunits; we have to scale up by the charsize. - int theShift=4; - PRInt32 theNewCapacity=eDefaultSize; - while(theNewCapacityPop(); - } - if(!aDest.mStr) { - //we're given the acount value in charunits; we have to scale up by the charsize. - size_t theSize=(theNewCapacity<Push(aDest.mStr); - } - else delete [] aDest.mStr; //it's too big. Just delete it. - } - aDest.mStr=0; - aDest.mOwnsBuffer=0; - return PR_TRUE; - } - return PR_FALSE; - } - nsDeque* mPools[16]; -}; //---------------------------------------------------------------------------------------- @@ -166,21 +74,6 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { NS_ASSERTION(aDest.mStr[0]==0,kFoolMsg); } -/** - * - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){ - aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer(); - aDest.mLength=aLength; - aDest.mCapacity=aCapacity; - aDest.mMultibyte=aCharSize; - aDest.mOwnsBuffer=aOwnsBuffer; - aDest.mUnused=0; -} - /** * * @update gess10/30/98 @@ -188,9 +81,13 @@ void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 a * @return */ nsIMemoryAgent* GetDefaultAgent(void){ -// static nsPoolingMemoryAgent gDefaultAgent; - static nsMemoryAgent gDefaultAgent; - return (nsIMemoryAgent*)&gDefaultAgent; + static nsIMemoryAgent* gDefaultAgent=0; + if(!gDefaultAgent) + gDefaultAgent=new nsMemoryAgent(); + + NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); + + return gDefaultAgent; } /** @@ -213,6 +110,20 @@ void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) { } } +/** + * + * @update gess11/12/98 + * @param + * @return + */ +PRUnichar nsStr::GetCharAt(const nsStr& aDest,PRUint32 anIndex) { + PRUnichar result=0; + if((anIndex>=0) && (anIndexFree(aDest); aDest.mStr = theTempStr.mStr; @@ -271,13 +182,14 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a /** * This method appends the given nsStr to this one. Note that we have to * pay attention to the underlying char-size of both structs. - * @update gess10/30/98 + * @update gess 04/04/99 * @param aDest is the nsStr to be manipulated * @param aSource is where char are copied from * @aCount is the number of bytes to be copied */ void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){ - if(anOffset0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(++index<=theMax) { PRInt32 theSubIndex=-1; PRBool matches=PR_TRUE; while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -472,8 +384,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnor * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -503,12 +415,12 @@ PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnore **************************************************************/ -PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) { +PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgnoreCase*/,PRUint32 anOffset) { PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1); if((aDest.mLength>0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -517,16 +429,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -547,8 +459,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -560,11 +472,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnor * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRUint32 offset=aDest.mLength-anOffset; + PRInt32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,offset); + PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -579,7 +491,7 @@ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnor * @param * @return aDestaSource=1 */ -PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) { +PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 /*aCount*/,PRBool aIgnoreCase) { int minlen=(aSource.mLength>mMultibyte)-1; + mOwnsBuffer=aOwnsBuffer; + } + + PRUint32 mCapacity; + PRBool mOwnsBuffer; + eCharSize mMultibyte; +// UStrPtr mStr; + union { + char* mStr; + PRUnichar* mUStr; + }; +}; + + class nsIMemoryAgent; //---------------------------------------------------------------------------------------- @@ -66,15 +97,6 @@ struct nsStr { */ static void Initialize(nsStr& aDest,eCharSize aCharSize); - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer); - /** * This method destroys the given nsStr, and *MAY* * deallocate it's memory depending on the setting @@ -144,7 +166,7 @@ struct nsStr { * @param aCount tells us the (max) # of chars to delete * @param anAgent is the allocator to be used for alloc/free operations */ - static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -232,20 +254,21 @@ struct nsStr { static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset); static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset); + /** + * This method is used to access a given char in the given string + * + * @update gess 01/04/99 + * @param aDest is the nsStr to be appended to + * @param anIndex tells us where in dest to get the char from + * @return the given char, or 0 if anIndex is out of range + */ + static PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex); -#ifdef NS_DEBUG - PRUint32 mLength; - eCharSize mMultibyte; - PRUint32 mCapacity; - PRUint32 mOwnsBuffer; - PRUint32 mUnused; -#else - PRUint32 mLength: 30; - eCharSize mMultibyte: 2; + PRUint32 mLength : 30; + eCharSize mMultibyte : 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; -#endif + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; union { char* mStr; PRUnichar* mUStr; @@ -284,21 +307,6 @@ inline void AddNullTerminator(nsStr& aDest) { else aDest.mStr[aDest.mLength]=0; } -/** -* This method is used to access a given char in the given string -* -* @update gess 01/04/99 -* @param aDest is the nsStr to be appended to -* @param anIndex tells us where in dest to get the char from -* @return the given char, or 0 if anIndex is out of range -*/ -inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){ - if(anIndex 64) { + // When the string starts getting large, double the capacity as we grow. + theNewCapacity = aDest.mCapacity * 2; + if (theNewCapacity < aCount) { + theNewCapacity = aDest.mCapacity + aCount; + } + } else { + // When the string is small, keep it's capacity a multiple of kGrowthDelta + PRInt32 unitDelta=(aCount/eGrowthDelta)+1; + theNewCapacity=unitDelta*eGrowthDelta; } - + aDest.mCapacity=theNewCapacity++; size_t theSize=(theNewCapacity<1) { PRUint32 theIndex; PRUnichar c1=0; - PRUnichar c2=nsStr::GetCharAt(*this,0); + PRUnichar c2=GetCharAt(*this,0); for(theIndex=1;theIndexc2) { result=PR_FALSE; break; @@ -315,19 +315,19 @@ PRUnichar* nsString2::GetUnicode(void) const { * Get nth character. */ PRUnichar nsString2::operator[](int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::CharAt(int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::First(void) const{ - return nsStr::GetCharAt(*this,0); + return GetCharAt(*this,0); } PRUnichar nsString2::Last(void) const{ - return nsStr::GetCharAt(*this,mLength-1); + return GetCharAt(*this,mLength-1); } PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ @@ -1130,7 +1130,7 @@ PRInt32 nsString2::BinarySearch(PRUnichar aChar) const{ while (low <= high) { int middle = (low + high) >> 1; - PRUnichar theChar=nsStr::GetCharAt(*this,middle); + PRUnichar theChar=GetCharAt(*this,middle); if (theChar==aChar) return middle; if (theChar>aChar) diff --git a/string/obsolete/nsStr.cpp b/string/obsolete/nsStr.cpp index e4b976254248..79e7afc99107 100644 --- a/string/obsolete/nsStr.cpp +++ b/string/obsolete/nsStr.cpp @@ -31,101 +31,9 @@ #include "nsStr.h" #include "bufferRoutines.h" #include "stdio.h" //only used for printf -#include "nsDeque.h" -#include "nsCRT.h" static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer."; -//---------------------------------------------------------------------------------------- -// The following is a memory agent who knows how to recycled (pool) freed memory... -//---------------------------------------------------------------------------------------- - -/************************************************************** - Define the char* (pooled) deallocator class... - **************************************************************/ -class nsBufferDeallocator: public nsDequeFunctor{ -public: - virtual void* operator()(void* anObject) { - char* aCString= (char*)anObject; - delete [] aCString; - return 0; - } -}; - -/** - * - * @update gess10/30/98 - * @param - * @return - */ -class nsPoolingMemoryAgent : public nsMemoryAgent{ -public: - nsPoolingMemoryAgent() { - memset(mPools,0,sizeof(mPools)); - } - - ~nsPoolingMemoryAgent() { - nsBufferDeallocator theDeallocator; - int i=0; - for(i=0;i<10;i++){ - if(mPools[i]){ - mPools[i]->ForEach(theDeallocator); //now delete the buffers - } - delete mPools[i]; - mPools[i]=0; - } - } - - virtual PRBool Alloc(nsStr& aDest,PRInt32 aCount) { - - //we're given the acount value in charunits; we have to scale up by the charsize. - int theShift=4; - PRInt32 theNewCapacity=eDefaultSize; - while(theNewCapacityPop(); - } - if(!aDest.mStr) { - //we're given the acount value in charunits; we have to scale up by the charsize. - size_t theSize=(theNewCapacity<Push(aDest.mStr); - } - else delete [] aDest.mStr; //it's too big. Just delete it. - } - aDest.mStr=0; - aDest.mOwnsBuffer=0; - return PR_TRUE; - } - return PR_FALSE; - } - nsDeque* mPools[16]; -}; //---------------------------------------------------------------------------------------- @@ -166,21 +74,6 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { NS_ASSERTION(aDest.mStr[0]==0,kFoolMsg); } -/** - * - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){ - aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer(); - aDest.mLength=aLength; - aDest.mCapacity=aCapacity; - aDest.mMultibyte=aCharSize; - aDest.mOwnsBuffer=aOwnsBuffer; - aDest.mUnused=0; -} - /** * * @update gess10/30/98 @@ -188,9 +81,13 @@ void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 a * @return */ nsIMemoryAgent* GetDefaultAgent(void){ -// static nsPoolingMemoryAgent gDefaultAgent; - static nsMemoryAgent gDefaultAgent; - return (nsIMemoryAgent*)&gDefaultAgent; + static nsIMemoryAgent* gDefaultAgent=0; + if(!gDefaultAgent) + gDefaultAgent=new nsMemoryAgent(); + + NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); + + return gDefaultAgent; } /** @@ -213,6 +110,20 @@ void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) { } } +/** + * + * @update gess11/12/98 + * @param + * @return + */ +PRUnichar nsStr::GetCharAt(const nsStr& aDest,PRUint32 anIndex) { + PRUnichar result=0; + if((anIndex>=0) && (anIndexFree(aDest); aDest.mStr = theTempStr.mStr; @@ -271,13 +182,14 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a /** * This method appends the given nsStr to this one. Note that we have to * pay attention to the underlying char-size of both structs. - * @update gess10/30/98 + * @update gess 04/04/99 * @param aDest is the nsStr to be manipulated * @param aSource is where char are copied from * @aCount is the number of bytes to be copied */ void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){ - if(anOffset0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(++index<=theMax) { PRInt32 theSubIndex=-1; PRBool matches=PR_TRUE; while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -472,8 +384,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnor * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -503,12 +415,12 @@ PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnore **************************************************************/ -PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) { +PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgnoreCase*/,PRUint32 anOffset) { PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1); if((aDest.mLength>0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -517,16 +429,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -547,8 +459,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -560,11 +472,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnor * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRUint32 offset=aDest.mLength-anOffset; + PRInt32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,offset); + PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -579,7 +491,7 @@ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnor * @param * @return aDestaSource=1 */ -PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) { +PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 /*aCount*/,PRBool aIgnoreCase) { int minlen=(aSource.mLength>mMultibyte)-1; + mOwnsBuffer=aOwnsBuffer; + } + + PRUint32 mCapacity; + PRBool mOwnsBuffer; + eCharSize mMultibyte; +// UStrPtr mStr; + union { + char* mStr; + PRUnichar* mUStr; + }; +}; + + class nsIMemoryAgent; //---------------------------------------------------------------------------------------- @@ -66,15 +97,6 @@ struct nsStr { */ static void Initialize(nsStr& aDest,eCharSize aCharSize); - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer); - /** * This method destroys the given nsStr, and *MAY* * deallocate it's memory depending on the setting @@ -144,7 +166,7 @@ struct nsStr { * @param aCount tells us the (max) # of chars to delete * @param anAgent is the allocator to be used for alloc/free operations */ - static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -232,20 +254,21 @@ struct nsStr { static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset); static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset); + /** + * This method is used to access a given char in the given string + * + * @update gess 01/04/99 + * @param aDest is the nsStr to be appended to + * @param anIndex tells us where in dest to get the char from + * @return the given char, or 0 if anIndex is out of range + */ + static PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex); -#ifdef NS_DEBUG - PRUint32 mLength; - eCharSize mMultibyte; - PRUint32 mCapacity; - PRUint32 mOwnsBuffer; - PRUint32 mUnused; -#else - PRUint32 mLength: 30; - eCharSize mMultibyte: 2; + PRUint32 mLength : 30; + eCharSize mMultibyte : 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; -#endif + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; union { char* mStr; PRUnichar* mUStr; @@ -284,21 +307,6 @@ inline void AddNullTerminator(nsStr& aDest) { else aDest.mStr[aDest.mLength]=0; } -/** -* This method is used to access a given char in the given string -* -* @update gess 01/04/99 -* @param aDest is the nsStr to be appended to -* @param anIndex tells us where in dest to get the char from -* @return the given char, or 0 if anIndex is out of range -*/ -inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){ - if(anIndex 64) { + // When the string starts getting large, double the capacity as we grow. + theNewCapacity = aDest.mCapacity * 2; + if (theNewCapacity < aCount) { + theNewCapacity = aDest.mCapacity + aCount; + } + } else { + // When the string is small, keep it's capacity a multiple of kGrowthDelta + PRInt32 unitDelta=(aCount/eGrowthDelta)+1; + theNewCapacity=unitDelta*eGrowthDelta; } - + aDest.mCapacity=theNewCapacity++; size_t theSize=(theNewCapacity<1) { PRUint32 theIndex; PRUnichar c1=0; - PRUnichar c2=nsStr::GetCharAt(*this,0); + PRUnichar c2=GetCharAt(*this,0); for(theIndex=1;theIndexc2) { result=PR_FALSE; break; @@ -315,19 +315,19 @@ PRUnichar* nsString2::GetUnicode(void) const { * Get nth character. */ PRUnichar nsString2::operator[](int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::CharAt(int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::First(void) const{ - return nsStr::GetCharAt(*this,0); + return GetCharAt(*this,0); } PRUnichar nsString2::Last(void) const{ - return nsStr::GetCharAt(*this,mLength-1); + return GetCharAt(*this,mLength-1); } PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ @@ -1130,7 +1130,7 @@ PRInt32 nsString2::BinarySearch(PRUnichar aChar) const{ while (low <= high) { int middle = (low + high) >> 1; - PRUnichar theChar=nsStr::GetCharAt(*this,middle); + PRUnichar theChar=GetCharAt(*this,middle); if (theChar==aChar) return middle; if (theChar>aChar) diff --git a/xpcom/ds/nsStr.cpp b/xpcom/ds/nsStr.cpp index e4b976254248..79e7afc99107 100644 --- a/xpcom/ds/nsStr.cpp +++ b/xpcom/ds/nsStr.cpp @@ -31,101 +31,9 @@ #include "nsStr.h" #include "bufferRoutines.h" #include "stdio.h" //only used for printf -#include "nsDeque.h" -#include "nsCRT.h" static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer."; -//---------------------------------------------------------------------------------------- -// The following is a memory agent who knows how to recycled (pool) freed memory... -//---------------------------------------------------------------------------------------- - -/************************************************************** - Define the char* (pooled) deallocator class... - **************************************************************/ -class nsBufferDeallocator: public nsDequeFunctor{ -public: - virtual void* operator()(void* anObject) { - char* aCString= (char*)anObject; - delete [] aCString; - return 0; - } -}; - -/** - * - * @update gess10/30/98 - * @param - * @return - */ -class nsPoolingMemoryAgent : public nsMemoryAgent{ -public: - nsPoolingMemoryAgent() { - memset(mPools,0,sizeof(mPools)); - } - - ~nsPoolingMemoryAgent() { - nsBufferDeallocator theDeallocator; - int i=0; - for(i=0;i<10;i++){ - if(mPools[i]){ - mPools[i]->ForEach(theDeallocator); //now delete the buffers - } - delete mPools[i]; - mPools[i]=0; - } - } - - virtual PRBool Alloc(nsStr& aDest,PRInt32 aCount) { - - //we're given the acount value in charunits; we have to scale up by the charsize. - int theShift=4; - PRInt32 theNewCapacity=eDefaultSize; - while(theNewCapacityPop(); - } - if(!aDest.mStr) { - //we're given the acount value in charunits; we have to scale up by the charsize. - size_t theSize=(theNewCapacity<Push(aDest.mStr); - } - else delete [] aDest.mStr; //it's too big. Just delete it. - } - aDest.mStr=0; - aDest.mOwnsBuffer=0; - return PR_TRUE; - } - return PR_FALSE; - } - nsDeque* mPools[16]; -}; //---------------------------------------------------------------------------------------- @@ -166,21 +74,6 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { NS_ASSERTION(aDest.mStr[0]==0,kFoolMsg); } -/** - * - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){ - aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer(); - aDest.mLength=aLength; - aDest.mCapacity=aCapacity; - aDest.mMultibyte=aCharSize; - aDest.mOwnsBuffer=aOwnsBuffer; - aDest.mUnused=0; -} - /** * * @update gess10/30/98 @@ -188,9 +81,13 @@ void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 a * @return */ nsIMemoryAgent* GetDefaultAgent(void){ -// static nsPoolingMemoryAgent gDefaultAgent; - static nsMemoryAgent gDefaultAgent; - return (nsIMemoryAgent*)&gDefaultAgent; + static nsIMemoryAgent* gDefaultAgent=0; + if(!gDefaultAgent) + gDefaultAgent=new nsMemoryAgent(); + + NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); + + return gDefaultAgent; } /** @@ -213,6 +110,20 @@ void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) { } } +/** + * + * @update gess11/12/98 + * @param + * @return + */ +PRUnichar nsStr::GetCharAt(const nsStr& aDest,PRUint32 anIndex) { + PRUnichar result=0; + if((anIndex>=0) && (anIndexFree(aDest); aDest.mStr = theTempStr.mStr; @@ -271,13 +182,14 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a /** * This method appends the given nsStr to this one. Note that we have to * pay attention to the underlying char-size of both structs. - * @update gess10/30/98 + * @update gess 04/04/99 * @param aDest is the nsStr to be manipulated * @param aSource is where char are copied from * @aCount is the number of bytes to be copied */ void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){ - if(anOffset0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(++index<=theMax) { PRInt32 theSubIndex=-1; PRBool matches=PR_TRUE; while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -472,8 +384,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnor * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -503,12 +415,12 @@ PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnore **************************************************************/ -PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) { +PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgnoreCase*/,PRUint32 anOffset) { PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1); if((aDest.mLength>0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -517,16 +429,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -547,8 +459,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -560,11 +472,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnor * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRUint32 offset=aDest.mLength-anOffset; + PRInt32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,offset); + PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -579,7 +491,7 @@ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnor * @param * @return aDestaSource=1 */ -PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) { +PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 /*aCount*/,PRBool aIgnoreCase) { int minlen=(aSource.mLength>mMultibyte)-1; + mOwnsBuffer=aOwnsBuffer; + } + + PRUint32 mCapacity; + PRBool mOwnsBuffer; + eCharSize mMultibyte; +// UStrPtr mStr; + union { + char* mStr; + PRUnichar* mUStr; + }; +}; + + class nsIMemoryAgent; //---------------------------------------------------------------------------------------- @@ -66,15 +97,6 @@ struct nsStr { */ static void Initialize(nsStr& aDest,eCharSize aCharSize); - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer); - /** * This method destroys the given nsStr, and *MAY* * deallocate it's memory depending on the setting @@ -144,7 +166,7 @@ struct nsStr { * @param aCount tells us the (max) # of chars to delete * @param anAgent is the allocator to be used for alloc/free operations */ - static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -232,20 +254,21 @@ struct nsStr { static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset); static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset); + /** + * This method is used to access a given char in the given string + * + * @update gess 01/04/99 + * @param aDest is the nsStr to be appended to + * @param anIndex tells us where in dest to get the char from + * @return the given char, or 0 if anIndex is out of range + */ + static PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex); -#ifdef NS_DEBUG - PRUint32 mLength; - eCharSize mMultibyte; - PRUint32 mCapacity; - PRUint32 mOwnsBuffer; - PRUint32 mUnused; -#else - PRUint32 mLength: 30; - eCharSize mMultibyte: 2; + PRUint32 mLength : 30; + eCharSize mMultibyte : 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; -#endif + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; union { char* mStr; PRUnichar* mUStr; @@ -284,21 +307,6 @@ inline void AddNullTerminator(nsStr& aDest) { else aDest.mStr[aDest.mLength]=0; } -/** -* This method is used to access a given char in the given string -* -* @update gess 01/04/99 -* @param aDest is the nsStr to be appended to -* @param anIndex tells us where in dest to get the char from -* @return the given char, or 0 if anIndex is out of range -*/ -inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){ - if(anIndex 64) { + // When the string starts getting large, double the capacity as we grow. + theNewCapacity = aDest.mCapacity * 2; + if (theNewCapacity < aCount) { + theNewCapacity = aDest.mCapacity + aCount; + } + } else { + // When the string is small, keep it's capacity a multiple of kGrowthDelta + PRInt32 unitDelta=(aCount/eGrowthDelta)+1; + theNewCapacity=unitDelta*eGrowthDelta; } - + aDest.mCapacity=theNewCapacity++; size_t theSize=(theNewCapacity<1) { PRUint32 theIndex; PRUnichar c1=0; - PRUnichar c2=nsStr::GetCharAt(*this,0); + PRUnichar c2=GetCharAt(*this,0); for(theIndex=1;theIndexc2) { result=PR_FALSE; break; @@ -315,19 +315,19 @@ PRUnichar* nsString2::GetUnicode(void) const { * Get nth character. */ PRUnichar nsString2::operator[](int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::CharAt(int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::First(void) const{ - return nsStr::GetCharAt(*this,0); + return GetCharAt(*this,0); } PRUnichar nsString2::Last(void) const{ - return nsStr::GetCharAt(*this,mLength-1); + return GetCharAt(*this,mLength-1); } PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ @@ -1130,7 +1130,7 @@ PRInt32 nsString2::BinarySearch(PRUnichar aChar) const{ while (low <= high) { int middle = (low + high) >> 1; - PRUnichar theChar=nsStr::GetCharAt(*this,middle); + PRUnichar theChar=GetCharAt(*this,middle); if (theChar==aChar) return middle; if (theChar>aChar) diff --git a/xpcom/string/obsolete/nsStr.cpp b/xpcom/string/obsolete/nsStr.cpp index e4b976254248..79e7afc99107 100644 --- a/xpcom/string/obsolete/nsStr.cpp +++ b/xpcom/string/obsolete/nsStr.cpp @@ -31,101 +31,9 @@ #include "nsStr.h" #include "bufferRoutines.h" #include "stdio.h" //only used for printf -#include "nsDeque.h" -#include "nsCRT.h" static const char* kFoolMsg = "Error: Some fool overwrote the shared buffer."; -//---------------------------------------------------------------------------------------- -// The following is a memory agent who knows how to recycled (pool) freed memory... -//---------------------------------------------------------------------------------------- - -/************************************************************** - Define the char* (pooled) deallocator class... - **************************************************************/ -class nsBufferDeallocator: public nsDequeFunctor{ -public: - virtual void* operator()(void* anObject) { - char* aCString= (char*)anObject; - delete [] aCString; - return 0; - } -}; - -/** - * - * @update gess10/30/98 - * @param - * @return - */ -class nsPoolingMemoryAgent : public nsMemoryAgent{ -public: - nsPoolingMemoryAgent() { - memset(mPools,0,sizeof(mPools)); - } - - ~nsPoolingMemoryAgent() { - nsBufferDeallocator theDeallocator; - int i=0; - for(i=0;i<10;i++){ - if(mPools[i]){ - mPools[i]->ForEach(theDeallocator); //now delete the buffers - } - delete mPools[i]; - mPools[i]=0; - } - } - - virtual PRBool Alloc(nsStr& aDest,PRInt32 aCount) { - - //we're given the acount value in charunits; we have to scale up by the charsize. - int theShift=4; - PRInt32 theNewCapacity=eDefaultSize; - while(theNewCapacityPop(); - } - if(!aDest.mStr) { - //we're given the acount value in charunits; we have to scale up by the charsize. - size_t theSize=(theNewCapacity<Push(aDest.mStr); - } - else delete [] aDest.mStr; //it's too big. Just delete it. - } - aDest.mStr=0; - aDest.mOwnsBuffer=0; - return PR_TRUE; - } - return PR_FALSE; - } - nsDeque* mPools[16]; -}; //---------------------------------------------------------------------------------------- @@ -166,21 +74,6 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { NS_ASSERTION(aDest.mStr[0]==0,kFoolMsg); } -/** - * - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){ - aDest.mStr=(aCString) ? aCString : GetSharedEmptyBuffer(); - aDest.mLength=aLength; - aDest.mCapacity=aCapacity; - aDest.mMultibyte=aCharSize; - aDest.mOwnsBuffer=aOwnsBuffer; - aDest.mUnused=0; -} - /** * * @update gess10/30/98 @@ -188,9 +81,13 @@ void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 a * @return */ nsIMemoryAgent* GetDefaultAgent(void){ -// static nsPoolingMemoryAgent gDefaultAgent; - static nsMemoryAgent gDefaultAgent; - return (nsIMemoryAgent*)&gDefaultAgent; + static nsIMemoryAgent* gDefaultAgent=0; + if(!gDefaultAgent) + gDefaultAgent=new nsMemoryAgent(); + + NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); + + return gDefaultAgent; } /** @@ -213,6 +110,20 @@ void nsStr::Destroy(nsStr& aDest,nsIMemoryAgent* anAgent) { } } +/** + * + * @update gess11/12/98 + * @param + * @return + */ +PRUnichar nsStr::GetCharAt(const nsStr& aDest,PRUint32 anIndex) { + PRUnichar result=0; + if((anIndex>=0) && (anIndexFree(aDest); aDest.mStr = theTempStr.mStr; @@ -271,13 +182,14 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a /** * This method appends the given nsStr to this one. Note that we have to * pay attention to the underlying char-size of both structs. - * @update gess10/30/98 + * @update gess 04/04/99 * @param aDest is the nsStr to be manipulated * @param aSource is where char are copied from * @aCount is the number of bytes to be copied */ void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){ - if(anOffset0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(++index<=theMax) { PRInt32 theSubIndex=-1; PRBool matches=PR_TRUE; while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -472,8 +384,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnor * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -503,12 +415,12 @@ PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnore **************************************************************/ -PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) { +PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgnoreCase*/,PRUint32 anOffset) { PRInt32 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1); if((aDest.mLength>0) && (aTarget.mLength>0)){ PRInt32 theNewStartPos=-1; - PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=nsStr::GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -517,16 +429,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -547,8 +459,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgno * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,0,aChar,aIgnoreCase); +PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { + PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); return result; } @@ -560,11 +472,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,const PRUnichar aChar, PRBool aIgnor * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRUint32 offset=aDest.mLength-anOffset; + PRInt32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,offset); + PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -579,7 +491,7 @@ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnor * @param * @return aDestaSource=1 */ -PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) { +PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 /*aCount*/,PRBool aIgnoreCase) { int minlen=(aSource.mLength>mMultibyte)-1; + mOwnsBuffer=aOwnsBuffer; + } + + PRUint32 mCapacity; + PRBool mOwnsBuffer; + eCharSize mMultibyte; +// UStrPtr mStr; + union { + char* mStr; + PRUnichar* mUStr; + }; +}; + + class nsIMemoryAgent; //---------------------------------------------------------------------------------------- @@ -66,15 +97,6 @@ struct nsStr { */ static void Initialize(nsStr& aDest,eCharSize aCharSize); - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer); - /** * This method destroys the given nsStr, and *MAY* * deallocate it's memory depending on the setting @@ -144,7 +166,7 @@ struct nsStr { * @param aCount tells us the (max) # of chars to delete * @param anAgent is the allocator to be used for alloc/free operations */ - static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRInt32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -232,20 +254,21 @@ struct nsStr { static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset); static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset); + /** + * This method is used to access a given char in the given string + * + * @update gess 01/04/99 + * @param aDest is the nsStr to be appended to + * @param anIndex tells us where in dest to get the char from + * @return the given char, or 0 if anIndex is out of range + */ + static PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex); -#ifdef NS_DEBUG - PRUint32 mLength; - eCharSize mMultibyte; - PRUint32 mCapacity; - PRUint32 mOwnsBuffer; - PRUint32 mUnused; -#else - PRUint32 mLength: 30; - eCharSize mMultibyte: 2; + PRUint32 mLength : 30; + eCharSize mMultibyte : 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; -#endif + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; union { char* mStr; PRUnichar* mUStr; @@ -284,21 +307,6 @@ inline void AddNullTerminator(nsStr& aDest) { else aDest.mStr[aDest.mLength]=0; } -/** -* This method is used to access a given char in the given string -* -* @update gess 01/04/99 -* @param aDest is the nsStr to be appended to -* @param anIndex tells us where in dest to get the char from -* @return the given char, or 0 if anIndex is out of range -*/ -inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){ - if(anIndex 64) { + // When the string starts getting large, double the capacity as we grow. + theNewCapacity = aDest.mCapacity * 2; + if (theNewCapacity < aCount) { + theNewCapacity = aDest.mCapacity + aCount; + } + } else { + // When the string is small, keep it's capacity a multiple of kGrowthDelta + PRInt32 unitDelta=(aCount/eGrowthDelta)+1; + theNewCapacity=unitDelta*eGrowthDelta; } - + aDest.mCapacity=theNewCapacity++; size_t theSize=(theNewCapacity<1) { PRUint32 theIndex; PRUnichar c1=0; - PRUnichar c2=nsStr::GetCharAt(*this,0); + PRUnichar c2=GetCharAt(*this,0); for(theIndex=1;theIndexc2) { result=PR_FALSE; break; @@ -315,19 +315,19 @@ PRUnichar* nsString2::GetUnicode(void) const { * Get nth character. */ PRUnichar nsString2::operator[](int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::CharAt(int anIndex) const { - return nsStr::GetCharAt(*this,anIndex); + return GetCharAt(*this,anIndex); } PRUnichar nsString2::First(void) const{ - return nsStr::GetCharAt(*this,0); + return GetCharAt(*this,0); } PRUnichar nsString2::Last(void) const{ - return nsStr::GetCharAt(*this,mLength-1); + return GetCharAt(*this,mLength-1); } PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ @@ -1130,7 +1130,7 @@ PRInt32 nsString2::BinarySearch(PRUnichar aChar) const{ while (low <= high) { int middle = (low + high) >> 1; - PRUnichar theChar=nsStr::GetCharAt(*this,middle); + PRUnichar theChar=GetCharAt(*this,middle); if (theChar==aChar) return middle; if (theChar>aChar)