/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #include #include #include #include #include "nsString.h" #include "nsCRT.h" #include "nsDebug.h" #include "prprf.h" #include "prdtoa.h" #include "nsISizeOfHandler.h" const PRInt32 kGrowthDelta = 8; const PRInt32 kNotFound = -1; PRUnichar gBadChar = 0; const char* kOutOfBoundsError = "Error: out of bounds"; const char* kNullPointerError = "Error: unexpected null ptr"; //********************************************** //NOTE: Our buffer always hold capacity+1 bytes. //********************************************** /** * Default constructor. We assume that this string will have * a bunch of Append's or SetString's done to it, therefore * we start with a mid sized buffer. */ nsString::nsString() { mLength = mCapacity = 0; mStr = 0; // Size to 4*kGrowthDelta (EnsureCapacityFor adds in kGrowthDelta so // subtract it before calling) EnsureCapacityFor(4*kGrowthDelta - kGrowthDelta); } nsString::nsString(const char* anISOLatin1) { mLength=mCapacity=0; mStr=0; PRInt32 len=strlen(anISOLatin1); EnsureCapacityFor(len); this->SetString(anISOLatin1,len); } /*------------------------------------------------------- * constructor from string * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString::nsString(const nsString &aString) { mLength=mCapacity=0; mStr=0; EnsureCapacityFor(aString.mLength); this->SetString(aString.mStr,aString.mLength); } /*------------------------------------------------------- * constructor from unicode string * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString::nsString(const PRUnichar* aUnicodeStr){ mLength=mCapacity=0; mStr=0; PRInt32 len=(aUnicodeStr) ? nsCRT::strlen(aUnicodeStr) : 0; EnsureCapacityFor(len); this->SetString(aUnicodeStr,len); } /*------------------------------------------------------- * special subclas constructor * this will optionally not allocate a buffer * but the subclass must * @update psl 4/16/98 * @param * @return *------------------------------------------------------*/ nsString::nsString(PRBool aSubclassBuffer) { mLength=mCapacity=0; mStr=0; if (PR_FALSE == aSubclassBuffer) { EnsureCapacityFor(1); this->SetString(""); } } /*------------------------------------------------------- * standard destructor * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString::~nsString() { delete [] mStr; mStr=0; mCapacity=mLength=0; } void nsString::SizeOf(nsISizeOfHandler* aHandler) const { aHandler->Add(sizeof(*this)); aHandler->Add(mCapacity * sizeof(chartype)); } /*------------------------------------------------------- * This method gets called when the internal buffer needs * to grow to a given size. * @update gess 3/30/98 * @param aNewLength -- new capacity of string * @return void *------------------------------------------------------*/ void nsString::EnsureCapacityFor(PRInt32 aNewLength) { PRInt32 newCapacity; if (mCapacity > 64) { // When the string starts getting large, double the capacity as we // grow. newCapacity = mCapacity * 2; if (newCapacity < aNewLength) { newCapacity = mCapacity + aNewLength; } } else { // When the string is small, keep it's capacity a multiple of // kGrowthDelta PRInt32 size =aNewLength+kGrowthDelta; newCapacity=size-(size % kGrowthDelta); } if(mCapacity 0) { nsCRT::memcpy(temp, mStr, mLength * sizeof(chartype)); } if(mStr) delete [] mStr; mStr = temp; mStr[mLength]=0; } } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::SetLength(PRInt32 aLength) { // NS_WARNING("Depricated method -- not longer required with dynamic strings. Use Truncate() instead."); EnsureCapacityFor(aLength); if (aLength > mLength) { nsCRT::zero(mStr + mLength, (aLength - mLength) * sizeof(chartype)); } mLength=aLength; } /*------------------------------------------------------- * This method truncates this string to given length. * * @update gess 3/27/98 * @param anIndex -- new length of string * @return nada *------------------------------------------------------*/ void nsString::Truncate(PRInt32 anIndex) { if((anIndex>-1) && (anIndex= 'A') && (ch <= 'Z')) { *cp = 'a' + (ch - 'A'); } cp++; } } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::ToUpperCase() { chartype* cp = mStr; chartype* end = cp + mLength; while (cp < end) { chartype ch = *cp; if ((ch >= 'a') && (ch <= 'z')) { *cp = 'A' + (ch - 'a'); } cp++; } } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::ToLowerCase(nsString& aOut) const { aOut.EnsureCapacityFor(mLength); aOut.mLength = mLength; chartype* to = aOut.mStr; chartype* from = mStr; chartype* end = from + mLength; while (from < end) { chartype ch = *from++; if ((ch >= 'A') && (ch <= 'Z')) { ch = 'a' + (ch - 'A'); } *to++ = ch; } *to = 0; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::ToUpperCase(nsString& aOut) const { aOut.EnsureCapacityFor(mLength); aOut.mLength = mLength; chartype* to = aOut.mStr; chartype* from = mStr; chartype* end = from + mLength; while (from < end) { chartype ch = *from++; if ((ch >= 'a') && (ch <= 'z')) { ch = 'A' + (ch - 'a'); } *to++ = ch; } *to = 0; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString* nsString::ToNewString() const { return new nsString(mStr); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ char* nsString::ToNewCString() const { char* rv = new char[mLength + 1]; return ToCString(rv,mLength+1); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRUnichar* nsString::ToNewUnicode() const { PRInt32 len = mLength; chartype* rv = new chartype[len + 1]; chartype* to = rv; chartype* from = mStr; while (--len >= 0) { *to++ = *from++; } *to++ = 0; return rv; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::ToString(nsString& aString) const { aString.mLength = 0; aString.Append(mStr, mLength); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ char* nsString::ToCString(char* aBuf, PRInt32 aBufLength) const { aBufLength--; // leave room for the \0 PRInt32 len = mLength; if (len > aBufLength) { len = aBufLength; } char* to = aBuf; chartype* from = mStr; while (--len >= 0) { *to++ = char(*from++); } *to++ = '\0'; return aBuf; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ float nsString::ToFloat(PRInt32* aErrorCode) const { char buf[40]; if (mLength > sizeof(buf)-1) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; return 0.0f; } char* cp = ToCString(buf, sizeof(buf)); float f = (float) PR_strtod(cp, &cp); if (*cp != 0) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; } *aErrorCode = (PRInt32) NS_OK; return f; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::ToInteger(PRInt32* aErrorCode) const { PRInt32 rv = 0; PRUnichar* cp = mStr; PRUnichar* end = mStr + mLength; // Skip leading whitespace while (cp < end) { PRUnichar ch = *cp; if (!IsSpace(ch)) { break; } cp++; } if (cp == end) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; return rv; } // Check for sign PRUnichar sign = '+'; if ((*cp == '+') || (*cp == '-')) { sign = *cp++; } if (cp == end) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; return rv; } // Convert the number while (cp < end) { PRUnichar ch = *cp++; if ((ch < '0') || (ch > '9')) { *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; break; } rv = rv * 10 + (ch - '0'); } if (sign == '-') { rv = -rv; } *aErrorCode = NS_OK; return rv; } /*------------------------------------------------------- * assign given string to this one * @update gess 3/27/98 * @param aString: string to be added to this * @return this *------------------------------------------------------*/ nsString& nsString::operator=(const nsString& aString) { return this->SetString(aString.mStr,aString.mLength); } /*------------------------------------------------------- * assign given char* to this string * @update gess 3/27/98 * @param anISOLatin1: buffer to be assigned to this * @return this *------------------------------------------------------*/ nsString& nsString::operator=(const char* anISOLatin1) { return SetString(anISOLatin1); } /*------------------------------------------------------- * assign given char to this string * @update gess 3/27/98 * @param aChar: char to be assignd to this * @return this *------------------------------------------------------*/ nsString& nsString::operator=(char aChar) { return Append(PRUnichar(aChar)); } /*------------------------------------------------------- * assign given PRUnichar* to this string * @update gess 3/27/98 * @param anISOLatin1: buffer to be assigned to this * @return this *------------------------------------------------------*/ nsString& nsString::SetString(const PRUnichar* aStr,PRInt32 aLength) { if(aStr!=0) { PRInt32 len=(kNotFound==aLength) ? nsCRT::strlen(aStr) : aLength; if(mCapacity< len ) EnsureCapacityFor(len); nsCRT::memcpy(mStr,aStr,len*sizeof(chartype)); mLength=len; mStr[mLength]=0; } else { mLength=0; //This little bit of code handles the case mStr[0]=0; //where some blockhead hands us a null string } return *this; } /*------------------------------------------------------- * assign given char* to this string * @update gess 3/27/98 * @param anISOLatin1: buffer to be assigned to this * @return this *------------------------------------------------------*/ nsString& nsString::SetString(const char* anISOLatin1,PRInt32 aLength) { if(anISOLatin1!=0) { PRInt32 len=(kNotFound==aLength) ? nsCRT::strlen(anISOLatin1) : aLength; if(mCapacitySetString(aStr); } /*------------------------------------------------------- * assign given char to this string * @update gess 3/27/98 * @param aChar: char to be assignd to this * @return this *------------------------------------------------------*/ nsString& nsString::operator=(PRUnichar aChar) { mLength=1; if(mCapacity<1) EnsureCapacityFor(kGrowthDelta); mStr[0]=aChar; mStr[1]=0; return *this; } /*------------------------------------------------------- * append given string to this string * @update gess 3/27/98 * @param aString : string to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::Append(const nsString& aString,PRInt32 aLength) { return Append(aString.mStr,aString.mLength); } /*------------------------------------------------------- * append given string to this string * @update gess 3/27/98 * @param aString : string to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::Append(const char* anISOLatin1,PRInt32 aLength) { if(anISOLatin1!=0) { PRInt32 len=(kNotFound==aLength) ? strlen(anISOLatin1) : aLength; if(mLength+len > mCapacity) { EnsureCapacityFor(mLength+len); } for(int i=0;i mCapacity) { EnsureCapacityFor(mLength+len); } if(len>0) nsCRT::memcpy(&mStr[mLength],aString,len*sizeof(chartype)); mLength+=len; mStr[mLength]=0; } return *this; } /*------------------------------------------------------- * append given string to this string * @update gess 3/27/98 * @param aString : string to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::Append(PRUnichar aChar) { if(mLength < mCapacity) { mStr[mLength++]=aChar; // the new string len < capacity, so just copy mStr[mLength]=0; } else { // The new string exceeds our capacity EnsureCapacityFor(mLength+1); mStr[mLength++]=aChar; mStr[mLength]=0; } return *this; } /*------------------------------------------------------- * append given string to this string * @update gess 3/27/98 * @param aString : string to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::operator+=(const nsString &aString) { return this->Append(aString.mStr,aString.mLength); } /*------------------------------------------------------- * append given buffer to this string * @update gess 3/27/98 * @param anISOLatin1: buffer to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::operator+=(const char* anISOLatin1) { return Append(anISOLatin1); } /*------------------------------------------------------- * append given buffer to this string * @update gess 3/27/98 * @param aBuffer: buffer to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::operator+=(const PRUnichar* aBuffer) { return Append(aBuffer); } /*------------------------------------------------------- * append given char to this string * @update gess 3/27/98 * @param aChar: char to be appended to this * @return this *------------------------------------------------------*/ nsString& nsString::operator+=(PRUnichar aChar) { return Append(aChar); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString& nsString::Append(PRInt32 aInteger,PRInt32 aRadix) { char* fmt = "%d"; if (8 == aRadix) { fmt = "%o"; } else if (16 == aRadix) { fmt = "%x"; } char buf[40]; PR_snprintf(buf, sizeof(buf), fmt, aInteger); Append(buf); return *this; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsString& nsString::Append(float aFloat){ char buf[40]; PR_snprintf(buf, sizeof(buf), "%g", aFloat); Append(buf); return *this; } /**------------------------------------------------------- * Copies n characters from this string to given string, * starting at the leftmost offset. * * * @update gess 4/1/98 * @param aCopy -- Receiving string * @param aCount -- number of chars to copy * @return number of chars copied *------------------------------------------------------*/ PRInt32 nsString::Left(nsString& aCopy,PRInt32 aCount) { return Mid(aCopy,0,aCount); } /**------------------------------------------------------- * Copies n characters from this string to given string, * starting at the given offset. * * * @update gess 4/1/98 * @param aCopy -- Receiving string * @param aCount -- number of chars to copy * @param anOffset -- position where copying begins * @return number of chars copied *------------------------------------------------------*/ PRInt32 nsString::Mid(nsString& aCopy,PRInt32 anOffset,PRInt32 aCount) { if(anOffsetaCopy.mLength) ? aCopy.mLength : aCount; //don't try to copy more than you are given if(aCount>0) { //1st optimization: If you're inserting at end, then simply append! if(anOffset>=mLength){ Append(aCopy,aCopy.mLength); return aCopy.mLength; } if(mLength+aCount > mCapacity) { EnsureCapacityFor(mLength+aCount); } PRUnichar* last = mStr + mLength; PRUnichar* first = mStr + anOffset-1; PRUnichar* next = mStr + mLength + aCount; //Copy rightmost chars, up to offset+aCount... while(first mCapacity) { EnsureCapacityFor(mLength+1); } PRUnichar* last = mStr + mLength; PRUnichar* first = mStr + anOffset-1; PRUnichar* next = mStr + mLength + 1; //Copy rightmost chars, up to offset+aCount... while(first= 'A') && (ch <= 'Z')) || ((ch >= 'a') && (ch <= 'z'))) { return PR_TRUE; } return PR_FALSE; } /**------------------------------------------------------- * * * @update gess 3/31/98 * @param * @return *------------------------------------------------------*/ PRBool nsString::IsSpace(PRUnichar ch) { // XXX i18n if ((ch == ' ') || (ch == '\r') || (ch == '\n') || (ch == '\t')) { return PR_TRUE; } return PR_FALSE; } /**------------------------------------------------------- * * * @update gess 3/31/98 * @param * @return isalpha *------------------------------------------------------*/ PRBool nsString::IsDigit(PRUnichar ch) { // XXX i18n return PRBool((ch >= '0') && (ch <= '9')); } /**------------------------------------------------------- * This method trims characters found in aTrimSet from * either end of the underlying string. * * @update gess 3/31/98 * @param aTrimSet -- contains chars to be trimmed from * both ends * @return this *------------------------------------------------------*/ nsString& nsString::Trim(const char* aTrimSet, PRBool aEliminateLeading, PRBool aEliminateTrailing) { PRUnichar* from = mStr; PRUnichar* end = mStr + mLength-1; PRUnichar* to = mStr; //begin by find the first char not in aTrimSet if(aEliminateLeading) { while (from < end) { PRUnichar ch = *from; if(!strchr(aTrimSet,char(ch))) { break; } from++; } } //Now, find last char not in aTrimSet if(aEliminateTrailing) { while(end> from) { PRUnichar ch = *end; if(!strchr(aTrimSet,char(ch))) { break; } end--; } } //now rewrite your string without unwanted //leading or trailing characters. while (from <= end) { *to++ = *from++; } *to = '\0'; mLength = to - mStr; return *this; } /**------------------------------------------------------- * * * @update gess 3/31/98 * @param * @return *------------------------------------------------------*/ nsString& nsString::CompressWhitespace( PRBool aEliminateLeading, PRBool aEliminateTrailing) { PRUnichar* from = mStr; PRUnichar* end = mStr + mLength; PRUnichar* to = from; Trim(" \r\n\t",aEliminateLeading,aEliminateTrailing); //this code converts /n, /t, /r into normal space ' '; //it also eliminates runs of whitespace... while (from < end) { PRUnichar ch = *from++; if (IsSpace(ch)) { *to++ = ' '; while (from < end) { ch = *from++; if (!IsSpace(ch)) { *to++ = ch; break; } } } else { *to++ = ch; } } *to = '\0'; mLength = to - mStr; return *this; } /**------------------------------------------------------- * XXX This is used by bina all over the place; not sure * it belongs here though * * @update gess 3/31/98 * @param * @return *------------------------------------------------------*/ nsString& nsString::StripWhitespace() { Trim(" \r\n\t"); return StripChars("\r\t\n"); } /**------------------------------------------------------- * Search for given buffer within this string * * @update gess 3/25/98 * @param anISOLatin1Buf - charstr to be found * @return offset in string, or -1 (kNotFound) *------------------------------------------------------*/ PRInt32 nsString::Find(const char* anISOLatin1Buf) const{ NS_ASSERTION(0!=anISOLatin1Buf,kNullPointerError); PRInt32 result=-1; if(anISOLatin1Buf) { PRInt32 len=strlen(anISOLatin1Buf); if(len<=mLength) { //only enter if abuffer length is <= mStr length. for(PRInt32 offset=0;offset0;i--){ char* pos=strchr(anISOLatin1Set,char(mStr[i])); if(pos) return i; } } return kNotFound; } /**------------------------------------------------------- * * * @update gess 3/25/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::FindLastCharInSet(nsString& aSet,PRInt32 anOffset) const{ if(aSet.Length()) { for(PRInt32 i=mLength-1;i>0;i--){ PRInt32 pos=aSet.Find(mStr[i]); if(kNotFound!=pos) return i; } } return kNotFound; } /**------------------------------------------------------- * * * @update gess 3/25/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::RFind(const PRUnichar* aString,PRBool aIgnoreCase) const{ NS_ASSERTION(0!=aString,kNullPointerError); if(aString) { PRInt32 len=nsCRT::strlen(aString); if((len) && (len<=mLength)) { //only enter if abuffer length is <= mStr length. for(PRInt32 offset=mLength-len;offset>=0;offset--) { PRInt32 result=0; if(aIgnoreCase) result=nsCRT::strncasecmp(&mStr[offset],aString,len); else result=nsCRT::strncmp(&mStr[offset],aString,len); if(0==result) return offset; //in this case, 0 means they match } } } return kNotFound; } /**------------------------------------------------------- * * * @update gess 3/25/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::RFind(const nsString& aString,PRBool aIgnoreCase) const{ PRInt32 len=aString.mLength; if((len) && (len<=mLength)) { //only enter if abuffer length is <= mStr length. for(PRInt32 offset=mLength-len;offset>=0;offset--) { PRInt32 result=0; if(aIgnoreCase) result=nsCRT::strncasecmp(&mStr[offset],aString.mStr,len); else result=nsCRT::strncmp(&mStr[offset],aString.mStr,len); if(0==result) return offset; //in this case, 0 means they match } } return kNotFound; } /**------------------------------------------------------- * * * @update gess 3/25/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::RFind(const char* anISOLatin1Set,PRBool aIgnoreCase) const{ NS_ASSERTION(0!=anISOLatin1Set,kNullPointerError); if(anISOLatin1Set) { PRInt32 len=strlen(anISOLatin1Set); if((len) && (len<=mLength)) { //only enter if abuffer length is <= mStr length. for(PRInt32 offset=mLength-len;offset>=0;offset--) { PRInt32 result=0; if(aIgnoreCase) result=nsCRT::strncasecmp(&mStr[offset],anISOLatin1Set,len); else result=nsCRT::strncmp(&mStr[offset],anISOLatin1Set,len); if(0==result) return offset; //in this case, 0 means they match } } } return kNotFound; } /**------------------------------------------------------- * Scans this string backwards for first occurance of * the given char. * * @update gess 3/25/98 * @param * @return offset of char in string, or -1 (kNotFound) *------------------------------------------------------*/ PRInt32 nsString::RFind(PRUnichar aChar,PRBool aIgnoreCase) const{ chartype uc=nsCRT::ToUpper(aChar); for(PRInt32 offset=mLength-1;offset>0;offset--) if(aIgnoreCase) { if(nsCRT::ToUpper(mStr[offset])==uc) return offset; } else if(mStr[offset]==aChar) return offset; //in this case, 0 means they match return kNotFound; } //****** comparision methods... ******* /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::Compare(const char *anISOLatin1,PRBool aIgnoreCase) const { if (aIgnoreCase) { return nsCRT::strcasecmp(mStr,anISOLatin1); } return nsCRT::strcmp(mStr,anISOLatin1); } /*------------------------------------------------------- * LAST MODS: gess * * @param * @return *------------------------------------------------------*/ PRInt32 nsString::Compare(const nsString &S,PRBool aIgnoreCase) const { if (aIgnoreCase) { return nsCRT::strcasecmp(mStr,S.mStr); } return nsCRT::strcmp(mStr,S.mStr); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRInt32 nsString::Compare(const PRUnichar* aString,PRBool aIgnoreCase) const { if (aIgnoreCase) { return nsCRT::strcasecmp(mStr,aString); } return nsCRT::strcmp(mStr,aString); } PRInt32 nsString::operator==(const nsString &S) const {return Compare(S)==0;} PRInt32 nsString::operator==(const char *s) const {return Compare(s)==0;} PRInt32 nsString::operator==(const PRUnichar *s) const {return Compare(s)==0;} PRInt32 nsString::operator!=(const nsString &S) const {return Compare(S)!=0;} PRInt32 nsString::operator!=(const char *s ) const {return Compare(s)!=0;} PRInt32 nsString::operator!=(const PRUnichar *s) const {return Compare(s)==0;} PRInt32 nsString::operator<(const nsString &S) const {return Compare(S)<0;} PRInt32 nsString::operator<(const char *s) const {return Compare(s)<0;} PRInt32 nsString::operator<(const PRUnichar *s) const {return Compare(s)==0;} PRInt32 nsString::operator>(const nsString &S) const {return Compare(S)>0;} PRInt32 nsString::operator>(const char *s) const {return Compare(s)>0;} PRInt32 nsString::operator>(const PRUnichar *s) const {return Compare(s)==0;} PRInt32 nsString::operator<=(const nsString &S) const {return Compare(S)<=0;} PRInt32 nsString::operator<=(const char *s) const {return Compare(s)<=0;} PRInt32 nsString::operator<=(const PRUnichar *s) const {return Compare(s)==0;} PRInt32 nsString::operator>=(const nsString &S) const {return Compare(S)>=0;} PRInt32 nsString::operator>=(const char *s) const {return Compare(s)>=0;} PRInt32 nsString::operator>=(const PRUnichar *s) const {return Compare(s)==0;} /*------------------------------------------------------- * Compare this to given string * @update gess 3/27/98 * @param aString -- string to compare to this * @return TRUE if equal *------------------------------------------------------*/ PRBool nsString::Equals(const nsString& aString) const { PRInt32 result=nsCRT::strcmp(mStr,aString.mStr); return PRBool(0==result); } /*------------------------------------------------------- * Compare this to given string * @update gess 3/27/98 * @param aCString -- Cstr to compare to this * @return TRUE if equal *------------------------------------------------------*/ PRBool nsString::Equals(const char* aCString) const{ NS_ASSERTION(0!=aCString,kNullPointerError); PRInt32 result=nsCRT::strcmp(mStr,aCString); return PRBool(0==result); } /*------------------------------------------------------- * Compare this to given atom * @update gess 3/27/98 * @param aAtom -- atom to compare to this * @return TRUE if equal *------------------------------------------------------*/ PRBool nsString::Equals(const nsIAtom* aAtom) const { NS_ASSERTION(0!=aAtom,kNullPointerError); PRInt32 result=nsCRT::strcmp(mStr,aAtom->GetUnicode()); return PRBool(0==result); } /*------------------------------------------------------- * Compare given strings * @update gess 3/27/98 * @param s1 -- first string to be compared * @param s2 -- second string to be compared * @return TRUE if equal *------------------------------------------------------*/ PRBool nsString::Equals(const PRUnichar* s1, const PRUnichar* s2) const { NS_ASSERTION(0!=s1,kNullPointerError); NS_ASSERTION(0!=s2,kNullPointerError); PRBool result=PR_FALSE; if((s1) && (s2)){ PRInt32 cmp=nsCRT::strcmp(s1,s2); result=PRBool(0==cmp); } return result; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRBool nsString::EqualsIgnoreCase(const nsString& aString) const{ PRInt32 result=nsCRT::strcasecmp(mStr,aString.mStr); return PRBool(0==result); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRBool nsString::EqualsIgnoreCase(const nsIAtom *aAtom) const{ NS_ASSERTION(0!=aAtom,kNullPointerError); PRBool result=PR_FALSE; if(aAtom){ PRInt32 cmp=nsCRT::strcasecmp(mStr,aAtom->GetUnicode()); result=PRBool(0==cmp); } return result; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRBool nsString::EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const { NS_ASSERTION(0!=s1,kNullPointerError); NS_ASSERTION(0!=s2,kNullPointerError); PRBool result=PR_FALSE; if((s1) && (s2)){ PRInt32 cmp=nsCRT::strcasecmp(s1,s2); result=PRBool(0==cmp); } return result; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ PRBool nsString::EqualsIgnoreCase(const char* aCString) const { NS_ASSERTION(0!=aCString,kNullPointerError); PRBool result=PR_FALSE; if(aCString){ PRInt32 cmp=nsCRT::strcasecmp(mStr,aCString); result=PRBool(0==cmp); } return result; } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ void nsString::DebugDump(ostream& aStream) const { for(int i=0;itemp3.Length(),"constructor error!"); //should be char longer nsString* es1=temp2.ToNewString(); //this should make us a new string char* es2=temp2.ToNewCString(); for(i=0;itemp8,"Error: Comparision (>) routine"); NS_ASSERTION(temp9>aaaa,"Error: Comparision (>) routine"); NS_ASSERTION(temp8<=temp8,"Error: Comparision (<=) routine"); NS_ASSERTION(temp8<=temp9,"Error: Comparision (<=) routine"); NS_ASSERTION(temp8<=bbbb,"Error: Comparision (<=) routine"); NS_ASSERTION(temp9>=temp9,"Error: Comparision (<=) routine"); NS_ASSERTION(temp9>=temp8,"Error: Comparision (<=) routine"); NS_ASSERTION(temp9>=aaaa,"Error: Comparision (<=) routine"); NS_ASSERTION(temp8.Equals(temp8),"Equals error"); NS_ASSERTION(temp8.Equals(aaaa),"Equals error"); nsString temp10(temp8); temp10.ToUpperCase(); NS_ASSERTION(temp8.EqualsIgnoreCase(temp10),"Equals error"); NS_ASSERTION(temp8.EqualsIgnoreCase("AAAA"),"Equals error"); //********************************************** //Now let's test a few string MANIPULATORS... //********************************************** nsAutoString ab("ab"); nsString abcde("cde"); abcde.Insert(ab,0,2); nsAutoString xxx("xxx"); abcde.Insert(xxx,2,3); temp2.ToUpperCase(); for(i=0;i mCapacity) { PRInt32 size = mCapacity * 2; if (size < aNewLength) { size = mCapacity + aNewLength; } mCapacity=size; chartype* temp = new chartype[mCapacity+1]; if (mLength > 0) { nsCRT::memcpy(temp, mStr, mLength * sizeof(chartype)); } if ((mStr != mBuf) && (0 != mStr)) { delete [] mStr; } mStr = temp; } } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsAutoString::nsAutoString(const PRUnichar* unicode, PRInt32 uslen) : nsString(PR_TRUE) { mStr = mBuf; mCapacity = sizeof(mBuf) / sizeof(chartype); if (0 == uslen) { uslen = nsCRT::strlen(unicode); } Append(unicode, uslen); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ nsAutoString::~nsAutoString() { if (mStr == mBuf) { // Force to null so that baseclass dtor doesn't do damage mStr = nsnull; } } void nsAutoString::SizeOf(nsISizeOfHandler* aHandler) const { aHandler->Add(sizeof(*this)); if (mStr != mBuf) { aHandler->Add(mCapacity * sizeof(chartype)); } } /**------------------------------------------------------- * * * @update gess 3/31/98 * @param * @return *------------------------------------------------------*/ void nsAutoString::SelfTest(){ nsAutoString xas("Hello there"); xas.Append("this string exceeds the max size"); xas.DebugDump(cout); } /*------------------------------------------------------- * * @update gess 3/27/98 * @param * @return *------------------------------------------------------*/ NS_BASE int fputs(const nsString& aString, FILE* out) { char buf[100]; char* cp = buf; PRInt32 len = aString.Length(); if (len >= sizeof(buf)) { cp = aString.ToNewCString(); } else { aString.ToCString(cp, len + 1); } ::fwrite(cp, 1, len, out); if (cp != buf) { delete cp; } return (int) len; }