From 640480851f7e75908447b3bc4fc555d111adfc79 Mon Sep 17 00:00:00 2001 From: "rickg%netscape.com" Date: Mon, 5 Apr 1999 21:28:55 +0000 Subject: [PATCH] fixed bug found by DavidBienvenu -- I owe him a beer --- base/src/nsStr.cpp | 236 ++++++++++++++++++++++---------- base/src/nsStr.h | 108 +++++++-------- string/obsolete/nsStr.cpp | 236 ++++++++++++++++++++++---------- string/obsolete/nsStr.h | 108 +++++++-------- xpcom/ds/nsStr.cpp | 236 ++++++++++++++++++++++---------- xpcom/ds/nsStr.h | 108 +++++++-------- xpcom/string/obsolete/nsStr.cpp | 236 ++++++++++++++++++++++---------- xpcom/string/obsolete/nsStr.h | 108 +++++++-------- 8 files changed, 832 insertions(+), 544 deletions(-) diff --git a/base/src/nsStr.cpp b/base/src/nsStr.cpp index ae4bc49e69f4..e4b976254248 100644 --- a/base/src/nsStr.cpp +++ b/base/src/nsStr.cpp @@ -31,9 +31,101 @@ #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]; +}; //---------------------------------------------------------------------------------------- @@ -80,14 +172,25 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { * @param * @return */ -nsIMemoryAgent* GetDefaultAgent(void){ - static nsIMemoryAgent* gDefaultAgent=0; - if(!gDefaultAgent) - gDefaultAgent=new nsMemoryAgent(); - - NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); +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; +} - return gDefaultAgent; +/** + * + * @update gess10/30/98 + * @param + * @return + */ +nsIMemoryAgent* GetDefaultAgent(void){ +// static nsPoolingMemoryAgent gDefaultAgent; + static nsMemoryAgent gDefaultAgent; + return (nsIMemoryAgent*)&gDefaultAgent; } /** @@ -110,20 +213,6 @@ 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; @@ -188,8 +277,7 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a * @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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=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=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -384,8 +472,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgn * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -415,12 +503,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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -429,16 +517,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -459,8 +547,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -472,11 +560,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase, * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 offset=aDest.mLength-anOffset; + PRUint32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); + PRUnichar theChar=GetCharAt(aDest,offset); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -491,7 +579,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; //---------------------------------------------------------------------------------------- @@ -97,6 +66,15 @@ 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 @@ -166,7 +144,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,PRInt32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -254,21 +232,20 @@ 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); - PRUint32 mLength : 30; - eCharSize mMultibyte : 2; +#ifdef NS_DEBUG + PRUint32 mLength; + eCharSize mMultibyte; + PRUint32 mCapacity; + PRUint32 mOwnsBuffer; + PRUint32 mUnused; +#else + PRUint32 mLength: 30; + eCharSize mMultibyte: 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; +#endif union { char* mStr; PRUnichar* mUStr; @@ -307,6 +284,21 @@ 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; + //we're given the acount value in charunits; now scale up to next multiple. + PRInt32 theNewCapacity=eDefaultSize; + while(theNewCapacityForEach(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]; +}; //---------------------------------------------------------------------------------------- @@ -80,14 +172,25 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { * @param * @return */ -nsIMemoryAgent* GetDefaultAgent(void){ - static nsIMemoryAgent* gDefaultAgent=0; - if(!gDefaultAgent) - gDefaultAgent=new nsMemoryAgent(); - - NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); +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; +} - return gDefaultAgent; +/** + * + * @update gess10/30/98 + * @param + * @return + */ +nsIMemoryAgent* GetDefaultAgent(void){ +// static nsPoolingMemoryAgent gDefaultAgent; + static nsMemoryAgent gDefaultAgent; + return (nsIMemoryAgent*)&gDefaultAgent; } /** @@ -110,20 +213,6 @@ 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; @@ -188,8 +277,7 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a * @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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=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=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -384,8 +472,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgn * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -415,12 +503,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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -429,16 +517,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -459,8 +547,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -472,11 +560,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase, * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 offset=aDest.mLength-anOffset; + PRUint32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); + PRUnichar theChar=GetCharAt(aDest,offset); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -491,7 +579,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; //---------------------------------------------------------------------------------------- @@ -97,6 +66,15 @@ 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 @@ -166,7 +144,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,PRInt32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -254,21 +232,20 @@ 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); - PRUint32 mLength : 30; - eCharSize mMultibyte : 2; +#ifdef NS_DEBUG + PRUint32 mLength; + eCharSize mMultibyte; + PRUint32 mCapacity; + PRUint32 mOwnsBuffer; + PRUint32 mUnused; +#else + PRUint32 mLength: 30; + eCharSize mMultibyte: 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; +#endif union { char* mStr; PRUnichar* mUStr; @@ -307,6 +284,21 @@ 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; + //we're given the acount value in charunits; now scale up to next multiple. + PRInt32 theNewCapacity=eDefaultSize; + while(theNewCapacityForEach(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]; +}; //---------------------------------------------------------------------------------------- @@ -80,14 +172,25 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { * @param * @return */ -nsIMemoryAgent* GetDefaultAgent(void){ - static nsIMemoryAgent* gDefaultAgent=0; - if(!gDefaultAgent) - gDefaultAgent=new nsMemoryAgent(); - - NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); +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; +} - return gDefaultAgent; +/** + * + * @update gess10/30/98 + * @param + * @return + */ +nsIMemoryAgent* GetDefaultAgent(void){ +// static nsPoolingMemoryAgent gDefaultAgent; + static nsMemoryAgent gDefaultAgent; + return (nsIMemoryAgent*)&gDefaultAgent; } /** @@ -110,20 +213,6 @@ 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; @@ -188,8 +277,7 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a * @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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=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=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -384,8 +472,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgn * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -415,12 +503,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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -429,16 +517,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -459,8 +547,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -472,11 +560,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase, * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 offset=aDest.mLength-anOffset; + PRUint32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); + PRUnichar theChar=GetCharAt(aDest,offset); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -491,7 +579,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; //---------------------------------------------------------------------------------------- @@ -97,6 +66,15 @@ 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 @@ -166,7 +144,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,PRInt32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -254,21 +232,20 @@ 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); - PRUint32 mLength : 30; - eCharSize mMultibyte : 2; +#ifdef NS_DEBUG + PRUint32 mLength; + eCharSize mMultibyte; + PRUint32 mCapacity; + PRUint32 mOwnsBuffer; + PRUint32 mUnused; +#else + PRUint32 mLength: 30; + eCharSize mMultibyte: 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; +#endif union { char* mStr; PRUnichar* mUStr; @@ -307,6 +284,21 @@ 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; + //we're given the acount value in charunits; now scale up to next multiple. + PRInt32 theNewCapacity=eDefaultSize; + while(theNewCapacityForEach(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]; +}; //---------------------------------------------------------------------------------------- @@ -80,14 +172,25 @@ void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { * @param * @return */ -nsIMemoryAgent* GetDefaultAgent(void){ - static nsIMemoryAgent* gDefaultAgent=0; - if(!gDefaultAgent) - gDefaultAgent=new nsMemoryAgent(); - - NS_ASSERTION(gDefaultAgent,"You MUST always have an allocator!"); +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; +} - return gDefaultAgent; +/** + * + * @update gess10/30/98 + * @param + * @return + */ +nsIMemoryAgent* GetDefaultAgent(void){ +// static nsPoolingMemoryAgent gDefaultAgent; + static nsMemoryAgent gDefaultAgent; + return (nsIMemoryAgent*)&gDefaultAgent; } /** @@ -110,20 +213,6 @@ 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; @@ -188,8 +277,7 @@ void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 a * @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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=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=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } if(matches) @@ -384,8 +472,8 @@ PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIgn * @param * @return */ -PRInt32 nsStr::FindChar(const nsStr& aDest, PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -415,12 +503,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=nsStr::GetCharAt(aTarget,0); - PRUnichar theLastTargetChar=nsStr::GetCharAt(aTarget,aTarget.mLength-1); + PRUnichar theFirstTargetChar=GetCharAt(aTarget,0); + PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1); PRInt32 theTargetMax=aTarget.mLength; while(index--) { @@ -429,16 +517,16 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg if(anOffset+aTarget.mLength<=aDest.mLength) { while((++theSubIndex0) { if(theFirstTargetChar==theChar){ - PRUnichar theDestJumpChar=nsStr::GetCharAt(aDest,index+theTargetMax); + PRUnichar theDestJumpChar=GetCharAt(aDest,index+theTargetMax); if(theDestJumpChar==theLastTargetChar) { theNewStartPos=index; //this lets us jump ahead during our search where possible. }//if }//if }//if - PRUnichar theTargetChar=nsStr::GetCharAt(aTarget,theSubIndex); + PRUnichar theTargetChar=GetCharAt(aTarget,theSubIndex); matches=PRBool(theChar==theTargetChar); } //while } //if @@ -459,8 +547,8 @@ PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool /*aIg * @param * @return */ -PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 result=gRFindChars[aDest.mMultibyte](aDest.mStr,aDest.mLength,anOffset,aChar,aIgnoreCase); +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); return result; } @@ -472,11 +560,11 @@ PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase, * @return */ PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRUint32 anOffset) { - PRInt32 offset=aDest.mLength-anOffset; + PRUint32 offset=aDest.mLength-anOffset; PRInt32 thePos; while(--offset>=0) { - PRUnichar theChar=GetCharAt(aDest,PRUint32(offset)); + PRUnichar theChar=GetCharAt(aDest,offset); thePos=gRFindChars[aSet.mMultibyte](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase); if(kNotFound!=thePos) return offset; @@ -491,7 +579,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; //---------------------------------------------------------------------------------------- @@ -97,6 +66,15 @@ 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 @@ -166,7 +144,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,PRInt32 aCount,nsIMemoryAgent* anAgent=0); + static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAgent* anAgent=0); /** * This method is used to truncate the given string. @@ -254,21 +232,20 @@ 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); - PRUint32 mLength : 30; - eCharSize mMultibyte : 2; +#ifdef NS_DEBUG + PRUint32 mLength; + eCharSize mMultibyte; + PRUint32 mCapacity; + PRUint32 mOwnsBuffer; + PRUint32 mUnused; +#else + PRUint32 mLength: 30; + eCharSize mMultibyte: 2; PRUint32 mCapacity: 30; - PRUint32 mOwnsBuffer: 1; - PRUint32 mUnused: 1; + PRUint32 mOwnsBuffer: 1; + PRUint32 mUnused: 1; +#endif union { char* mStr; PRUnichar* mUStr; @@ -307,6 +284,21 @@ 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; + //we're given the acount value in charunits; now scale up to next multiple. + PRInt32 theNewCapacity=eDefaultSize; + while(theNewCapacity