#include "nsString.h" #include "nsBufferManager.h" #include #include #include "nsMemory.h" static const char* kNullPointerError = "Unexpected null pointer"; static const char* kWhitespace="\b\t\r\n "; //****************************************** // Ctor's //****************************************** void Subsume(nsStringValueImpl &aDest,nsStringValueImpl &aSource){ if(aSource.mBuffer && aSource.mLength) { #if 0 if(aSource.mOwnsBuffer){ nsStr::Destroy(aDest); aDest.mStr=aSource.mStr; aDest.mLength=aSource.mLength; aDest.mCapacity=aSource.mCapacity; aDest.mOwnsBuffer=aSource.mOwnsBuffer; aSource.mOwnsBuffer=PR_FALSE; aSource.mStr=0; } else{ nsStr::StrAssign(aDest,aSource,0,aSource.mLength); } #endif } else SVTruncate(aDest,0); } nsString::nsString() : mStringValue() { } //call this version for nsString,nsString and the autostrings nsString::nsString(const nsString& aString,PRInt32 aLength) : mStringValue() { SVAppend(mStringValue,aString.mStringValue,aLength,0); } //call this version with nsCString nsString::nsString(const nsCString &aString,PRInt32 aLength) : mStringValue() { SVAppend(mStringValue,aString.mStringValue,aLength,0); } //call this version for a single char of type char... nsString::nsString(nsSubsumeStr &aSubsumeString) : mStringValue() { mStringValue=aSubsumeString.mStringValue; memset(&aSubsumeString.mStringValue,0,sizeof(mStringValue)); } //call this version for char*'s.... nsString::nsString(const PRUnichar* aString,PRInt32 aLength) : mStringValue() { Append(aString,aLength,0); } //call this version for a single char of type char... nsString::nsString(const char aChar) : mStringValue() { Append(aChar); } //call this version for PRUnichar*'s.... nsString::nsString(const char* aString,PRInt32 aLength) : mStringValue() { nsStringValueImpl theString(NS_CONST_CAST(char*,aString),aLength); SVAppend(mStringValue,theString,theString.mLength,0); } //call this version for all other ABT versions of readable strings nsString::nsString(const nsAReadableString &aString) : mStringValue() { Assign(aString); } nsString::~nsString() { SVFree(mStringValue); } void nsString::Reinitialize(PRUnichar* aBuffer,PRUint32 aCapacity,PRInt32 aLength) { mStringValue.mBuffer=aBuffer; mStringValue.mCapacity=aCapacity; mStringValue.mLength=aLength; mStringValue.mRefCount=1; } //****************************************** // Assigment operators //****************************************** nsString& nsString::operator=(const nsString& aString) { if(aString.mStringValue.mBuffer!=mStringValue.mBuffer) { Assign(aString); } return *this; } nsString& nsString::operator=(const nsCString &aString) { Assign(aString); return *this; } nsString& nsString::operator=(const nsSubsumeStr &aSubsumeString) { mStringValue=aSubsumeString.mStringValue; memset((void*)&aSubsumeString.mStringValue,0,sizeof(mStringValue)); return *this; } nsString& nsString::operator=(const PRUnichar *aString) { if(mStringValue.mBuffer!=aString) { nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString)); Assign(aString); } return *this; } nsString& nsString::operator=(const char *aString) { nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString)); SVAssign(mStringValue,theStringValue,theStringValue.mLength,0); return *this; } nsString& nsString::operator=(const char aChar) { Assign(aChar); return *this; } nsString& nsString::operator=(const PRUnichar aChar) { Assign(aChar); return *this; } //****************************************** // Here are the accessor methods... //****************************************** nsresult nsString::SetCapacity(PRUint32 aCapacity) { if(aCapacity>mStringValue.mCapacity) { SVRealloc(mStringValue,aCapacity); } return NS_OK; } PRBool nsString::SetCharAt(PRUnichar aChar,PRUint32 anIndex) { PRBool result=PR_FALSE; if(anIndex theStringValue(NS_CONST_CAST(char*,aString),aLength); result=SVAppend(mStringValue,theStringValue,aLength,aSrcOffset); } return result; } //append from alternative type string pointer nsresult nsString::Append(const char aChar) { if(mStringValue.mLength==mStringValue.mCapacity) { SVRealloc(mStringValue,mStringValue.mCapacity+5); } if(mStringValue.mLength theStringValue(NS_CONST_CAST(PRUnichar*,aString),aLength); result=SVAppend (mStringValue,theStringValue,aLength,aSrcOffset); } return result; } //append from an nsCString nsresult nsString::Append(const nsCString &aString,PRInt32 aLength,PRUint32 aSrcOffset) { aLength = (aLength<0) ? aString.mStringValue.mLength : (aLength<(PRInt32)aString.mStringValue.mLength) ? aLength: aString.mStringValue.mLength; return SVAppend (mStringValue,aString.mStringValue,aLength,aSrcOffset); } //append from an nsAReadableString (the ABT) nsresult nsString::Append(const nsAReadableString &aString,PRInt32 aLength,PRUint32 aSrcOffset) { aLength = (aLength<0) ? aString.Length() : MinInt(aLength,aString.Length()); return SVAppendReadable(mStringValue,aString,aLength,aSrcOffset); } //append an integer nsresult nsString::Append(PRInt32 anInteger,PRInt32 aRadix) { nsresult result=NS_OK; PRUint32 theInt=(PRUint32)anInteger; char buf[]={'0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; PRInt32 radices[] = {1000000000,268435456}; PRInt32 mask1=radices[16==aRadix]; PRInt32 charpos=0; if(anInteger<0) { theInt*=-1; if(10==aRadix) { buf[charpos++]='-'; } else theInt=(int)~(theInt-1); } PRBool isfirst=PR_TRUE; while(mask1>=1) { PRInt32 theDiv=theInt/mask1; if((theDiv) || (!isfirst)) { buf[charpos++]="0123456789abcdef"[theDiv]; isfirst=PR_FALSE; } theInt-=theDiv*mask1; mask1/=aRadix; } return Append(buf); return result; } //Append a float nsresult nsString::Append(float aFloat) { nsresult result=NS_OK; char buf[40]; sprintf(buf,"%g",aFloat); nsStringValueImpl theStringValue(buf); Append(theStringValue); return result; } //*************************************** // Here come a few deletion methods... //*************************************** nsresult nsString::Cut(PRUint32 anOffset,PRInt32 aCount) { return (0 theStringValue(NS_CONST_CAST(char*,aString),aLength); if(0 theStringValue(NS_CONST_CAST(PRUnichar*,aString),aLength); if(0 theStringValue(theBuffer,1); return SVInsert(mStringValue,anOffset,theStringValue,1,0); } //******************************************* // Here come inplace replacement methods... //******************************************* /** * swaps occurence of 1 char for another * * @return this */ nsresult nsString::ReplaceChar(char anOldChar,char aNewChar){ PRUnichar *root_cp=mStringValue.mBuffer; PRUnichar *null_cp=root_cp+mStringValue.mLength; while(root_cp theTarget(NS_CONST_CAST(char*,aTarget)); const nsStringValueImpl theNewValue(NS_CONST_CAST(char*,aNewValue)); return SVReplace(mStringValue,theTarget,theNewValue,mStringValue.mLength,0); } //******************************************* // Here come the stripchar methods... //******************************************* /** * This method is used to remove all occurances of the * given character from this string. * * @update rickg 03.01.2000 * @param aChar -- char to be stripped * @param anOffset -- where in this string to start stripping chars * @return *this */ nsresult nsString::StripChar(PRUnichar aChar,PRUint32 anOffset){ return SVStripChar(mStringValue,aChar,mStringValue.mLength,anOffset); } /** * This method is used to remove all occurances of the * given character from this string. * * @update rickg 03.01.2000 * @param aChar -- char to be stripped * @param anOffset -- where in this string to start stripping chars * @return *this */ nsresult nsString::StripChar(PRInt32 anInt,PRUint32 anOffset){ return SVStripChar(mStringValue,(PRUnichar)anInt,mStringValue.mLength,anOffset); } /** * This method is used to remove all occurances of the * characters found in aSet from this string. * * @update rickg 03.01.2000 * @param aSet -- characters to be cut from this * @return *this */ nsresult nsString::StripChars(const char* aSet,PRInt32 aLength){ nsStringValueImpl theSet(NS_CONST_CAST(char*,aSet),aLength); return SVStripCharsInSet(mStringValue,aSet,mStringValue.mLength,0); } /** * This method strips whitespace throughout the string * * @update rickg 03.01.2000 * @return this */ nsresult nsString::StripWhitespace() { static const char* kWhitespace="\b\t\r\n "; return StripChars(kWhitespace); } //************************************************** // Here are some methods that extract substrings... //************************************************** nsresult nsString::Left(nsString& aCopy,PRInt32 aCount) const { aCount = (aCount<0) ? mStringValue.mLength : (aCount<(PRInt32)mStringValue.mLength) ? aCount : mStringValue.mLength; return aCopy.Assign(*this,aCount,0); } nsresult nsString::Mid(nsString& aCopy,PRUint32 anOffset,PRInt32 aCount) const { aCount = (aCount<0) ? mStringValue.mLength : (aCount<(PRInt32)mStringValue.mLength) ? aCount : mStringValue.mLength; return aCopy.Assign(*this,aCount,anOffset); } nsresult nsString::Right(nsString& aCopy,PRInt32 aCount) const { PRUint32 theLen=mStringValue.mLength-aCount; PRInt32 offset=(theLen<0) ? 0 : theLen; return Mid(aCopy,offset,aCount); } //****************************************** // Concatenation operators //****************************************** nsSubsumeStr nsString::operator+(const nsString &aString) { nsString theString(*this); SVAppend(theString.mStringValue,aString.mStringValue); return nsSubsumeStr(theString); } nsSubsumeStr nsString::operator+(const PRUnichar* aString) { nsString theTempString(*this); nsStringValueImpl theTempStrValue(NS_CONST_CAST(PRUnichar*,aString)); SVAppend(theTempString.mStringValue,theTempStrValue); return nsSubsumeStr(theTempString); } nsSubsumeStr nsString::operator+(const char* aString) { nsString theTempString(*this); nsStringValueImpl theTempStrValue(NS_CONST_CAST(char*,aString)); SVAppend(theTempString.mStringValue,theTempStrValue); return nsSubsumeStr(theTempString); } nsSubsumeStr nsString::operator+(PRUnichar aChar) { nsString theTempString(*this); theTempString.Append(aChar); return nsSubsumeStr(theTempString); } //******************************************* // Here come the operator+=() methods... //******************************************* nsString& nsString::operator+=(const nsString& aString){ SVAppend(mStringValue,aString.mStringValue,aString.mStringValue.mLength,0); return *this; } nsString& nsString::operator+=(const char* aString) { Append(aString); return *this; } nsString& nsString::operator+=(const PRUnichar* aString) { Append(aString); return *this; } nsString& nsString::operator+=(const char aChar) { char theBuffer[]={aChar,0}; Append(theBuffer,1); return *this; } nsString& nsString::operator+=(const PRUnichar aChar) { PRUnichar theBuffer[]={aChar,0}; Append(theBuffer,1); return *this; } nsString& nsString::operator+=(const int anInt){ Append(anInt,10); return *this; } void nsString::ToLowerCase() { SVToLowerCase(mStringValue); } void nsString::ToLowerCase(nsString &aString) const { aString=*this; aString.ToLowerCase(); } void nsString::ToUpperCase() { SVToUpperCase(mStringValue); } void nsString::ToUpperCase(nsString &aString) const { aString=*this; aString.ToUpperCase(); } PRInt32 nsString::Compare(const nsString &aString,PRBool aIgnoreCase,PRInt32 aCount) const { return SVCompareChars(mStringValue,aString.mStringValue,aIgnoreCase,aCount); } PRInt32 nsString::Compare(const nsCString &aString,PRBool aIgnoreCase,PRInt32 aCount) const { return SVCompare(mStringValue,aString.mStringValue,aIgnoreCase,aCount); } PRInt32 nsString::Compare(const char* aString,PRBool aIgnoreCase,PRInt32 aCount) const { nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString),aCount); return SVCompare(mStringValue,theStringValue,aIgnoreCase,aCount); } PRInt32 nsString::Compare(const PRUnichar* aString,PRBool aIgnoreCase,PRInt32 aCount) const { nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString),aCount); return SVCompareChars(mStringValue,theStringValue,aIgnoreCase,aCount); } PRBool nsString::Equals(const nsString &aString,PRBool aIgnoreCase,PRInt32 aCount) const { return PRBool(0==SVCompare(mStringValue,aString.mStringValue,aIgnoreCase,aCount)); } PRBool nsString::Equals(const nsCString &aString,PRBool aIgnoreCase,PRInt32 aCount) const { return PRBool(0==SVCompare(mStringValue,aString.mStringValue,aIgnoreCase,aCount)); } PRBool nsString::Equals(const char* aString,PRBool aIgnoreCase,PRInt32 aCount) const { nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString),aCount); return PRBool(0==SVCompare(mStringValue,theStringValue,aIgnoreCase,aCount)); } PRBool nsString::Equals(const PRUnichar* aString,PRBool aIgnoreCase,PRInt32 aCount) const { nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString),aCount); return PRBool(0==SVCompareChars(mStringValue,theStringValue,aIgnoreCase,aCount)); } PRBool nsString::Equals(const PRUnichar* aLHS,const PRUnichar* aRHS,PRBool aIgnoreCase) const { NS_ASSERTION(0!=aLHS,kNullPointerError); NS_ASSERTION(0!=aRHS,kNullPointerError); PRBool result=PR_FALSE; if((aLHS) && (aRHS)){ // PRInt32 cmp=(aIgnoreCase) ? nsCRT::strcasecmp(aLHS,aRHS) : nsCRT::strcmp(aLHS,aRHS); // result=PRBool(0==cmp); } return result; } PRBool nsString::Equals(/*FIX: const */nsIAtom* aAtom,PRBool aIgnoreCase) const{ NS_ASSERTION(0!=aAtom,kNullPointerError); PRBool result=PR_FALSE; #if 0 if(aAtom){ PRInt32 cmp=0; const PRUnichar* unicode; if (aAtom->GetUnicode(&unicode) != NS_OK || unicode == nsnull) return PR_FALSE; if (aIgnoreCase) cmp=nsCRT::strcasecmp(mUStr,unicode); else cmp=nsCRT::strcmp(mUStr,unicode); result=PRBool(0==cmp); } #endif return result; } /*************************************** These are string searching methods... ***************************************/ /** * search for given string within this string * * @update rickg 03.01.2000 * @param aString - substr to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::Find(const nsString& aTarget,PRBool aIgnoreCase,PRUint32 anOffset,PRInt32 aRepCount) const { return SVFind(mStringValue,aTarget.mStringValue,aIgnoreCase,aRepCount,anOffset); } /** * search for given string within this string * * @update rickg 03.01.2000 * @param aString - substr to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::Find(const nsCString &aString,PRBool aIgnoreCase,PRUint32 anOffset,PRInt32 aRepCount) const { return SVFind(mStringValue,aString.mStringValue,aIgnoreCase,aRepCount,anOffset); } /** * search for given string within this char* string * * @update rickg 03.01.2000 * @param aString - substr to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::Find(const char* aString,PRBool aIgnoreCase,PRUint32 anOffset,PRInt32 aRepCount) const { nsStringValueImpl theString(NS_CONST_CAST(char*,aString)); return SVFind(mStringValue,theString,aIgnoreCase,aRepCount,anOffset); } /** * search for given string within this PRUnichar* string * * @update rickg 03.01.2000 * @param aString - substr to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::Find(const PRUnichar* aString,PRBool aIgnoreCase,PRUint32 anOffset,PRInt32 aRepCount) const { nsStringValueImpl theString(NS_CONST_CAST(PRUnichar*,aString)); return SVFind(mStringValue,theString,aIgnoreCase,aRepCount,anOffset); } /** * This method finds the offset of the first char in this string that is * a member of the given charset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::FindCharInSet(const nsString& aString,PRUint32 anOffset) const{ return SVFindCharInSet(mStringValue,aString.mStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /** * This method finds the offset of the first char in this string that is * a member of the given charset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::FindCharInSet(const char *aString,PRUint32 anOffset) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString)); return SVFindCharInSet(mStringValue,theStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /** * This method finds the offset of the first char in this string that is * a member of the given altcharset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::FindCharInSet(const PRUnichar *aString,PRUint32 anOffset) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString)); return SVFindCharInSet(mStringValue,theStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /** * Search for a given char, starting at given offset * * @update rickg 03.01.2000 * @param aChar is the unichar to be sought * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::FindChar(char aChar,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount) const { return SVFindChar(mStringValue,aChar,aIgnoreCase,aCount,anOffset); } /** * Reverse search for given char within this string * * @update gess 3/25/98 * @param aChar - char to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching (-1 means start at end) * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::RFindChar(char aChar,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aRepCount) const{ return SVRFindChar(mStringValue,aChar,aIgnoreCase,aRepCount,anOffset); } /** * Reverse search for given string within this string * * @update gess 3/25/98 * @param aString - substr to be found * @param aIgnoreCase tells us whether or not to do caseless compare * @param anOffset tells us where in this string to start searching * @param aRepCount tells us how many iterations to make starting at the given offset * @return offset in string, or -1 (kNotFound) */ PRInt32 nsString::RFind(const nsString& aString,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aRepCount) const{ PRInt32 theMaxPos = mStringValue.mLength-aString.mStringValue.mLength; //this is the last pos that is feasible for starting the search, with given lengths... PRInt32 result=kNotFound; if(0<=theMaxPos) { result=SVRFind(mStringValue,aString.mStringValue,aIgnoreCase,aRepCount,anOffset); } return result; } PRInt32 nsString::RFind(const char* aString,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aRepCount) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString)); return SVRFind(mStringValue,theStringValue,aIgnoreCase,aRepCount,anOffset); } PRInt32 nsString::RFind(const PRUnichar* aString,PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aRepCount) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString)); return SVRFind(mStringValue,theStringValue,aIgnoreCase,aRepCount,anOffset); } /** * This method finds (in reverse) the offset of the first char in this string that is * a member of the given charset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::RFindCharInSet(const nsString& aString,PRInt32 anOffset) const { return SVRFindCharInSet(mStringValue,aString.mStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /** * This method finds (in reverse) the offset of the first char in this string that is * a member of the given charset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(PRUnichar*,aString)); return SVRFindCharInSet(mStringValue,theStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /** * This method finds (in reverse) the offset of the first char in this string that is * a member of the given charset, starting the search at anOffset * * @update rickg 03.01.2000 * @param aString contains set of chars to be found * @param anOffset -- where in this string to start searching * @return */ PRInt32 nsString::RFindCharInSet(const char* aString,PRInt32 anOffset) const{ nsStringValueImpl theStringValue(NS_CONST_CAST(char*,aString)); return SVRFindCharInSet(mStringValue,theStringValue,PR_FALSE,mStringValue.mLength,anOffset); } /*************************************** These convert to a different type ***************************************/ void nsString::Recycle(nsString* aString) { //NOT IMPLEMENTED } nsString* nsString::CreateString(void) { return 0; //NOT IMPLEMENTED } /** * This method constructs a new nsString is a clone of this string. */ nsString* nsString::ToNewString() const { return 0; //NOT IMPLEMENTED } char* nsString::ToNewCString() const { return 0; //NOT IMPLEMENTED } char* nsString::ToNewUTF8String() const { return 0; //NOT IMPLEMENTED } PRUnichar* nsString::ToNewUnicode() const { return 0; //NOT IMPLEMENTED } char* nsString::ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset) const { int len=(mStringValue.mLength PRInt32(sizeof(buf)-1)) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; return 0.0f; } char* cp = ToCString(buf, sizeof(buf)); float f = (float) strtod(cp, &cp); if (*cp != 0) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; } *aErrorCode = (PRInt32) NS_OK; return f; } /** * Perform string to int conversion. * @param aErrorCode will contain error if one occurs * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. * @return int rep of string value, and possible (out) error code */ PRInt32 nsString::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const{ return SVToInteger(mStringValue,anErrorCode,aRadix); } nsresult nsString::Append(const nsStringValueImpl &aString,PRInt32 aLength,PRUint32 aSrcOffset) { aLength = (aLength<0) ? aString.mLength : (aLength<(PRInt32)aString.mLength) ? aLength: aString.mLength; return SVAppend(mStringValue,aString,aLength,aSrcOffset); } /***************************************************************** Now we define the nsSubsumeStr class *****************************************************************/ nsSubsumeStr::nsSubsumeStr(nsString& aString) : nsString() { Subsume(mStringValue,aString.mStringValue); } nsSubsumeStr::nsSubsumeStr(PRUnichar * aString,PRBool assumeOwnership,PRInt32 aLength) : nsString() { // mStringValue.mBuffer=aString; // mStringValue.mCapacity=mStringValue.mLength=(-1==aLength) ? strlen(aString) : aLength; // mOwnsBuffer=assumeOwnership; } /** * * @update gess 01/04/99 * @param * @return */ NS_COM int fputs(const nsString& aString, FILE* out) { char buf[100]; char* cp = buf; PRInt32 len = aString.Length(); if (len >= PRInt32(sizeof(buf))) { cp = aString.ToNewCString(); } else { aString.ToCString(cp, len + 1); } if(len>0) ::fwrite(cp, 1, len, out); if (cp != buf) { delete[] cp; } return (int) len; } PRUint32 HashCode(const nsString& aDest) { PRUint32 h = 0; PRUint32 n = aDest.Length(); PRUint32 m; const PRUnichar* c=aDest.GetUnicode(); if (n < 16) { /* Hash every char in a short string. */ for(; n; c++, n--) h = (h >> 28) ^ (h << 4) ^ *c; } else { /* Sample a la java.lang.String.hash(). */ for(m = n / 8; n >= m; c += m, n -= m) h = (h >> 28) ^ (h << 4) ^ *c; } return h; } void Recycle( PRUnichar* aBuffer) { nsMemory::Free(aBuffer); } /***************************************************************** Now we declare the nsAutoString class *****************************************************************/ nsAutoString::nsAutoString() : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; } //call this version nsAutoString derivatives... nsAutoString::nsAutoString(const nsAutoString& aString,PRInt32 aLength) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; nsString::Assign(aString,aLength,0); } //call this version for nsString and the autostrings nsAutoString::nsAutoString(const nsString& aString,PRInt32 aLength) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; nsString::Assign(aString,aLength,0); } //call this version with nsCString nsAutoString::nsAutoString(const nsCString& aString) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; nsString::Assign(aString); } //call this version for char*'s.... nsAutoString::nsAutoString(const char* aString,PRInt32 aLength) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2;; //so we don't try to delete our internal buffer nsString::Assign(aString,aLength,0); } //call this version for a single char of type char... nsAutoString::nsAutoString(char aChar) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; //so we don't try to delete our internal buffer nsString::Assign(aChar); } //call this version for a single char of type char... nsAutoString::nsAutoString(PRUnichar aChar) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; //so we don't try to delete our internal buffer nsString::Assign(aChar); } //call this version for PRUnichar*'s.... nsAutoString::nsAutoString(const PRUnichar* aString,PRInt32 aLength) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; //so we don't try to delete our internal buffer nsString::Assign(aString,aLength,0); } //call this version for all other ABT versions of readable strings nsAutoString::nsAutoString(const nsAReadableString &aString) : nsString() { memset(mInternalBuffer,0,sizeof(mInternalBuffer)); mStringValue.mCapacity=kDefaultStringSize; mStringValue.mBuffer=mInternalBuffer; mStringValue.mRefCount=2; //so we don't try to delete our internal buffer nsString::Assign(aString); } nsAutoString::nsAutoString(const UBufDescriptor &aBuffer) : nsString() { mStringValue.mBuffer=aBuffer.mBuffer; mStringValue.mCapacity=aBuffer.mCapacity; mStringValue.mLength=aBuffer.mLength; mStringValue.mRefCount=(aBuffer.mOwnsBuffer) ? 1 : 2; memset(mInternalBuffer,0,sizeof(mInternalBuffer)); } nsAutoString::nsAutoString(const nsSubsumeStr& aSubsumeStringX) : nsString() { } nsAutoString::~nsAutoString() { } nsAutoString& nsAutoString::operator=(const nsAutoString& aString) { nsString::operator=(aString); return *this; } nsAutoString& nsAutoString::operator=(const nsString& aString) { nsString::operator=(aString); return *this; } nsAutoString& nsAutoString::operator=(const nsCString& aString) { nsString::operator=(aString); return *this; } nsAutoString& nsAutoString::operator=(const PRUnichar* aString) { nsString::operator=(aString); return *this; } nsAutoString& nsAutoString::operator=(const char* aString) { nsString::operator=(aString); return *this; } nsAutoString& nsAutoString::operator=(const PRUnichar aChar) { nsString::operator=(aChar); return *this; } nsAutoString& nsAutoString::operator=(const nsSubsumeStr &aSubsumeString) { nsString::operator=(aSubsumeString); return *this; }