зеркало из https://github.com/mozilla/gecko-dev.git
fix searching errors; safeguard assign
This commit is contained in:
Родитель
01c1e0bdc3
Коммит
7d255a1bd9
|
@ -8,14 +8,14 @@
|
|||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
aDest.mStr=new char[theSize];
|
||||
}
|
||||
aDest.mOwnsBuffer=1;
|
||||
return PR_TRUE;
|
||||
return PRBool(aDest.mStr!=0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ void nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* an
|
|||
void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,(eCharSize)aDest.mCharSize);
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
|
||||
EnsureCapacity(theTempStr,aNewLength,theAgent);
|
||||
|
@ -265,8 +265,10 @@ void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgen
|
|||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
if(&aDest!=&aSource){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,7 +325,7 @@ void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUin
|
|||
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
|
||||
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][PR_TRUE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
|
@ -360,7 +362,7 @@ void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAg
|
|||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][PR_FALSE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
}
|
||||
else Truncate(aDest,aDestOffset,anAgent);
|
||||
|
@ -440,31 +442,48 @@ void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEli
|
|||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0) && (anOffset<aTarget.mLength)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
//This little block of code builds up the boyer-moore skip table.
|
||||
//It might be nicer if this could be generated externally as passed in to improve performance.
|
||||
const int theSize=256;
|
||||
int theSkipTable[theSize];
|
||||
PRUint32 theIndex=0;
|
||||
for (theIndex=0;theIndex<theSize;++theIndex) {
|
||||
theSkipTable[theIndex]=aTarget.mLength;
|
||||
theSkipTable[theIndex]=theCopy.mLength;
|
||||
}
|
||||
for (theIndex=0;theIndex<aTarget.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(aTarget,theIndex)]=(aTarget.mLength-theIndex-1);
|
||||
for (theIndex=0;theIndex<theCopy.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(theCopy,theIndex)]=(theCopy.mLength-theIndex-1);
|
||||
}
|
||||
|
||||
//and now we do the actual searching.
|
||||
PRUint32 theMaxIndex=aDest.mLength-anOffset;
|
||||
for (theIndex=aTarget.mLength-1; theIndex< theMaxIndex; theIndex+= theSkipTable[(unsigned char)GetCharAt(aDest,theIndex)]) {
|
||||
int theBufIndex=theIndex;
|
||||
int thePatIndex=aTarget.mLength-1;
|
||||
while((thePatIndex>=0) && (GetCharAt(aDest,theBufIndex)==GetCharAt(aTarget,thePatIndex))){
|
||||
--theBufIndex;
|
||||
--thePatIndex;
|
||||
int iBuf =theIndex;
|
||||
int iPat=aTarget.mLength-1;
|
||||
|
||||
PRBool matches=PR_TRUE;
|
||||
while((iPat>=0) && (matches)){
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,iPat);
|
||||
PRUnichar theDestChar=GetCharAt(aDest,iBuf);
|
||||
if(aIgnoreCase)
|
||||
theDestChar=nsCRT::ToLower(theDestChar);
|
||||
matches=PRBool(theTargetChar==theDestChar);
|
||||
if(matches){
|
||||
--iBuf;
|
||||
--iPat;
|
||||
}
|
||||
}
|
||||
if(-1==thePatIndex){
|
||||
return anOffset+theBufIndex+1;
|
||||
if(-1==iPat){
|
||||
return anOffset+iBuf+1;
|
||||
}
|
||||
}
|
||||
} //for
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
}
|
||||
|
@ -509,41 +528,38 @@ 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 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1);
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
PRInt32 theNewStartPos=-1;
|
||||
PRUnichar theFirstTargetChar=GetCharAt(aTarget,0);
|
||||
PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1);
|
||||
PRInt32 theTargetMax=aTarget.mLength;
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
while(index--) {
|
||||
PRInt32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
if(anOffset+aTarget.mLength<=aDest.mLength) {
|
||||
int32 theTargetMax=theCopy.mLength;
|
||||
while(index--) {
|
||||
int32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if(anOffset+theCopy.mLength<=aDest.mLength) {
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theChar=GetCharAt(aDest,index+theSubIndex);
|
||||
if(theSubIndex>0) {
|
||||
if(theFirstTargetChar==theChar){
|
||||
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=GetCharAt(aTarget,theSubIndex);
|
||||
matches=PRBool(theChar==theTargetChar);
|
||||
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
|
||||
matches=PRBool(theDestChar==theTargetChar);
|
||||
} //while
|
||||
} //if
|
||||
if(matches)
|
||||
return index;
|
||||
if(-1<theNewStartPos){
|
||||
index=theNewStartPos-1;
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //while
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -177,7 +177,7 @@ nsString2::nsString2(const nsStr &aString,eCharSize aCharSize,nsIMemoryAgent* an
|
|||
* @param reference to another nsString2
|
||||
*/
|
||||
nsString2::nsString2(const nsString2& aString) :mAgent(aString.mAgent) {
|
||||
nsStr::Initialize(*this,(eCharSize)aString.mCharSize);
|
||||
nsStr::Initialize(*this,aString.mCharSize);
|
||||
nsStr::Assign(*this,aString,0,aString.mLength,mAgent);
|
||||
}
|
||||
|
||||
|
@ -267,9 +267,8 @@ void nsString2::SetCapacity(PRUint32 aLength) {
|
|||
* @return ptr to internal buffer (if 1-byte), otherwise NULL
|
||||
*/
|
||||
const char* nsString2::GetBuffer(void) const {
|
||||
if(!mCharSize)
|
||||
return mStr;
|
||||
return 0;
|
||||
const char* result=(eOneByte==mCharSize) ? mStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +277,8 @@ const char* nsString2::GetBuffer(void) const {
|
|||
* @return ptr to internal buffer (if 2-byte), otherwise NULL
|
||||
*/
|
||||
const PRUnichar* nsString2::GetUnicode(void) const {
|
||||
if(mCharSize)
|
||||
return (PRUnichar*)mUStr;
|
||||
return 0;
|
||||
const PRUnichar* result=(eTwoByte==mCharSize) ? mUStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,7 +303,7 @@ PRUnichar nsString2::Last(void) const{
|
|||
PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){
|
||||
PRBool result=PR_FALSE;
|
||||
if(anIndex<mLength){
|
||||
if(!mCharSize)
|
||||
if(eOneByte==mCharSize)
|
||||
mStr[anIndex]=char(aChar);
|
||||
else mUStr[anIndex]=aChar;
|
||||
result=PR_TRUE;
|
||||
|
@ -403,7 +401,7 @@ nsSubsumeStr nsString2::operator+(PRUnichar aChar) {
|
|||
void nsString2::ToUCS2(PRUint32 aStartOffset){
|
||||
static CTableConstructor gTableConstructor;
|
||||
if(aStartOffset<mLength){
|
||||
if(mCharSize) {
|
||||
if(eTwoByte==mCharSize) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=aStartOffset;theIndex<mLength;theIndex++){
|
||||
unsigned char ch = (unsigned char)mUStr[theIndex];
|
||||
|
@ -488,14 +486,18 @@ nsString2& nsString2::StripWhitespace() {
|
|||
*/
|
||||
nsString2& nsString2::ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(eTwoByte==mCharSize) {
|
||||
if(mUStr[theIndex]==aSourceChar)
|
||||
if(eTwoByte==mCharSize){
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mUStr[theIndex]==aSourceChar) {
|
||||
mUStr[theIndex]=aDestChar;
|
||||
}//if
|
||||
}
|
||||
else {
|
||||
if(mStr[theIndex]==aSourceChar)
|
||||
}
|
||||
else{
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mStr[theIndex]==(char)aSourceChar) {
|
||||
mStr[theIndex]=(char)aDestChar;
|
||||
}//if
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
@ -570,9 +572,11 @@ nsString2* nsString2::ToNewString() const {
|
|||
char* nsString2::ToNewCString() const {
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
char* result=new char[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -585,9 +589,11 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
PRUnichar* result=new PRUnichar[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -597,15 +603,19 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength) const{
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength,PRUint32 anOffset) const{
|
||||
PRUint32 theLength=0;
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,0,theLength,mAgent);
|
||||
if(0<aBufLength){
|
||||
if(0<aBufLength){
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,anOffset,theLength,mAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
aBuf[theLength]=0;
|
||||
return aBuf;
|
||||
|
@ -711,8 +721,10 @@ PRInt32 nsString2::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -723,8 +735,10 @@ nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsString2& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1704,16 +1718,27 @@ void nsString2::DebugDump(ostream& aStream) const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
ostream& operator<<(ostream& os,nsString2& aString){
|
||||
if(PR_FALSE==aString.mCharSize) {
|
||||
os<<aString.mStr;
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString){
|
||||
if(eOneByte==aString.mCharSize) {
|
||||
aStream<<aString.mStr;
|
||||
}
|
||||
else{
|
||||
char* theStr=aString.ToNewCString();
|
||||
os<<theStr;
|
||||
delete [] theStr;
|
||||
PRUint32 theOffset=0;
|
||||
const PRUint32 theBufSize=300;
|
||||
char theBuf[theBufSize+1];
|
||||
PRUint32 theCount=0;
|
||||
PRUint32 theRemains=0;
|
||||
|
||||
while(theOffset<aString.mLength){
|
||||
theRemains=aString.mLength-theOffset;
|
||||
theCount=(theRemains<theBufSize) ? theRemains : theBufSize;
|
||||
aString.ToCString(theBuf,theCount+1,theOffset);
|
||||
theBuf[theCount]=0;
|
||||
aStream<<theBuf;
|
||||
theOffset+=theCount;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1765,8 +1790,8 @@ nsAutoString2::nsAutoString2(eCharSize aCharSize) : nsString2(aCharSize){
|
|||
* @param anExtBuffer describes an external buffer
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCharSize)aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,(eCharSize)aStr.mCharSize,PR_FALSE);
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2(aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,aStr.mCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
Assign(aCString);
|
||||
|
@ -1776,7 +1801,7 @@ nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCha
|
|||
* Copy construct from ascii c-string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2((eCharSize)aCharSize) {
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2(aCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aCharSize)-1,0,aCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
|
@ -1881,7 +1906,7 @@ nsAutoString2::nsAutoString2(PRUnichar aChar,eCharSize aCharSize) : nsString2(aC
|
|||
* @update gess 1/4/99
|
||||
* @param reference to a subsumeString
|
||||
*/
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2((eCharSize)aSubsumeStr.mCharSize) {
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2(aSubsumeStr.mCharSize) {
|
||||
mAgent=0;
|
||||
Subsume(*this,aSubsumeStr);
|
||||
}
|
||||
|
@ -1900,11 +1925,11 @@ void nsAutoString2::SizeOf(nsISizeOfHandler* aHandler) const {
|
|||
aHandler->Add(mCapacity << mCharSize);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
|
@ -1913,13 +1938,26 @@ nsSubsumeStr::nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLe
|
|||
mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength) : nsString2(eOneByte) {
|
||||
mStr=aString;
|
||||
mCapacity=mLength=(-1==aLength) ? strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
IMPLEMENTATION of nsCAutoString, which is a vanilla string class that
|
||||
only ever stores 1 byte character strings. Typically you'll use this
|
||||
class to hold a pointer to a char*, which comes from an nsString.
|
||||
***********************************************************************/
|
||||
nsCAutoString::nsCAutoString(const nsString2& aString) : nsAutoString(aString,eOneByte){
|
||||
}
|
||||
|
||||
nsCAutoString::operator const char*() const {
|
||||
return (const char*)mStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
/***********************************************************************
|
||||
|
@ -1939,6 +1977,21 @@ CStringTester::CStringTester() {
|
|||
nsString2 theString0("foo",theSize); //watch it construct and destruct
|
||||
}
|
||||
|
||||
//Let's test our autoCStrings...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
nsCAutoString theCStr(theString);
|
||||
}
|
||||
|
||||
//now let's test out various features of out SubsumeStrs...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
|
||||
nsString2 theString2=theString+" there!"; //a subsumestr should be constructed and returned by operator+()
|
||||
nsSubsumeStr theSubStr=theString2.left(5);
|
||||
int x=5;
|
||||
}
|
||||
|
||||
{
|
||||
//this test makes sure that autostrings who assume ownership of a buffer,
|
||||
//don't also try to copy that buffer onto itself... (was a bug)
|
||||
|
|
|
@ -356,7 +356,7 @@ PRUnichar* ToNewUnicode() const;
|
|||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength) const;
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
|
@ -725,7 +725,7 @@ virtual void DebugDump(ostream& aStream) const;
|
|||
};
|
||||
|
||||
extern NS_COM int fputs(const nsString2& aString, FILE* out);
|
||||
ostream& operator<<(ostream& os,nsString2& aString);
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString);
|
||||
|
||||
|
||||
/**************************************************************
|
||||
|
@ -792,6 +792,17 @@ public:
|
|||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
|
||||
***************************************************************/
|
||||
class NS_COM nsCAutoString: public nsAutoString{
|
||||
public:
|
||||
nsCAutoString(const nsString2& aString);
|
||||
operator const char*() const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#include "nsICaseConversion.h"
|
||||
#endif
|
||||
|
||||
#define KSHIFTLEFT (0)
|
||||
#define KSHIFTRIGHT (1)
|
||||
|
||||
|
||||
inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) {
|
||||
return ((PRUnichar*)aString)[anIndex];
|
||||
|
@ -226,7 +229,7 @@ void CopyChars2To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32
|
|||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
if(*first<255)
|
||||
if(*first<256)
|
||||
*to=(char)*first;
|
||||
else *to='.';
|
||||
to++;
|
||||
|
@ -283,8 +286,9 @@ CopyChars gCopyChars[2][2]={
|
|||
*/
|
||||
inline PRInt32 FindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=anOffset;theIndex<aLength;theIndex++){
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 theLength=(PRInt32)aLength;
|
||||
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
|
@ -307,8 +311,9 @@ inline PRInt32 FindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,co
|
|||
*/
|
||||
inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=anOffset;theIndex<aLength;theIndex++){
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 theLength=(PRInt32)aLength;
|
||||
for(theIndex=(PRInt32)anOffset;theIndex<theLength;theIndex++){
|
||||
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
|
@ -319,7 +324,6 @@ inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,co
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer (in reverse) for the given char
|
||||
*
|
||||
|
@ -333,8 +337,9 @@ inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,co
|
|||
*/
|
||||
inline PRInt32 RFindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=aLength-1;theIndex>=0;theIndex--){
|
||||
PRInt32 theIndex=0;
|
||||
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
|
||||
for(theIndex=thePos;theIndex>=0;theIndex--){
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
|
@ -345,7 +350,6 @@ inline PRInt32 RFindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,c
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
|
@ -360,7 +364,8 @@ inline PRInt32 RFindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,c
|
|||
inline PRInt32 RFindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRUnichar theCmpChar=(aIgnoreCase ? nsCRT::ToUpper(aChar) : aChar);
|
||||
PRInt32 theIndex=0;
|
||||
for(theIndex=aLength-1;theIndex>=0;theIndex--){
|
||||
PRInt32 thePos=(PRInt32)aLength-anOffset-1;
|
||||
for(theIndex=thePos;theIndex>=0;theIndex--){
|
||||
PRUnichar theChar=GetUnicharAt(aDest,theIndex);
|
||||
if(aIgnoreCase)
|
||||
theChar=nsCRT::ToUpper(theChar);
|
||||
|
@ -449,7 +454,7 @@ PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool a
|
|||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
else result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -821,7 +826,7 @@ PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet,PRUint32
|
|||
while (from <= end) {
|
||||
chartype ch = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = ' ';
|
||||
*to++ = (char)aChar;
|
||||
while (from <= end) {
|
||||
ch = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
|
@ -867,7 +872,7 @@ PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet,PRUint32
|
|||
while (from <= end) {
|
||||
chartype ch = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
*to++ = ' ';
|
||||
*to++ = (PRUnichar)aChar;
|
||||
while (from <= end) {
|
||||
ch = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,ch,PR_FALSE)){
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
aDest.mStr=new char[theSize];
|
||||
}
|
||||
aDest.mOwnsBuffer=1;
|
||||
return PR_TRUE;
|
||||
return PRBool(aDest.mStr!=0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ void nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* an
|
|||
void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,(eCharSize)aDest.mCharSize);
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
|
||||
EnsureCapacity(theTempStr,aNewLength,theAgent);
|
||||
|
@ -265,8 +265,10 @@ void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgen
|
|||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
if(&aDest!=&aSource){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,7 +325,7 @@ void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUin
|
|||
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
|
||||
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][PR_TRUE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
|
@ -360,7 +362,7 @@ void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAg
|
|||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][PR_FALSE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
}
|
||||
else Truncate(aDest,aDestOffset,anAgent);
|
||||
|
@ -440,31 +442,48 @@ void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEli
|
|||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0) && (anOffset<aTarget.mLength)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
//This little block of code builds up the boyer-moore skip table.
|
||||
//It might be nicer if this could be generated externally as passed in to improve performance.
|
||||
const int theSize=256;
|
||||
int theSkipTable[theSize];
|
||||
PRUint32 theIndex=0;
|
||||
for (theIndex=0;theIndex<theSize;++theIndex) {
|
||||
theSkipTable[theIndex]=aTarget.mLength;
|
||||
theSkipTable[theIndex]=theCopy.mLength;
|
||||
}
|
||||
for (theIndex=0;theIndex<aTarget.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(aTarget,theIndex)]=(aTarget.mLength-theIndex-1);
|
||||
for (theIndex=0;theIndex<theCopy.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(theCopy,theIndex)]=(theCopy.mLength-theIndex-1);
|
||||
}
|
||||
|
||||
//and now we do the actual searching.
|
||||
PRUint32 theMaxIndex=aDest.mLength-anOffset;
|
||||
for (theIndex=aTarget.mLength-1; theIndex< theMaxIndex; theIndex+= theSkipTable[(unsigned char)GetCharAt(aDest,theIndex)]) {
|
||||
int theBufIndex=theIndex;
|
||||
int thePatIndex=aTarget.mLength-1;
|
||||
while((thePatIndex>=0) && (GetCharAt(aDest,theBufIndex)==GetCharAt(aTarget,thePatIndex))){
|
||||
--theBufIndex;
|
||||
--thePatIndex;
|
||||
int iBuf =theIndex;
|
||||
int iPat=aTarget.mLength-1;
|
||||
|
||||
PRBool matches=PR_TRUE;
|
||||
while((iPat>=0) && (matches)){
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,iPat);
|
||||
PRUnichar theDestChar=GetCharAt(aDest,iBuf);
|
||||
if(aIgnoreCase)
|
||||
theDestChar=nsCRT::ToLower(theDestChar);
|
||||
matches=PRBool(theTargetChar==theDestChar);
|
||||
if(matches){
|
||||
--iBuf;
|
||||
--iPat;
|
||||
}
|
||||
}
|
||||
if(-1==thePatIndex){
|
||||
return anOffset+theBufIndex+1;
|
||||
if(-1==iPat){
|
||||
return anOffset+iBuf+1;
|
||||
}
|
||||
}
|
||||
} //for
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
}
|
||||
|
@ -509,41 +528,38 @@ 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 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1);
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
PRInt32 theNewStartPos=-1;
|
||||
PRUnichar theFirstTargetChar=GetCharAt(aTarget,0);
|
||||
PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1);
|
||||
PRInt32 theTargetMax=aTarget.mLength;
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
while(index--) {
|
||||
PRInt32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
if(anOffset+aTarget.mLength<=aDest.mLength) {
|
||||
int32 theTargetMax=theCopy.mLength;
|
||||
while(index--) {
|
||||
int32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if(anOffset+theCopy.mLength<=aDest.mLength) {
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theChar=GetCharAt(aDest,index+theSubIndex);
|
||||
if(theSubIndex>0) {
|
||||
if(theFirstTargetChar==theChar){
|
||||
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=GetCharAt(aTarget,theSubIndex);
|
||||
matches=PRBool(theChar==theTargetChar);
|
||||
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
|
||||
matches=PRBool(theDestChar==theTargetChar);
|
||||
} //while
|
||||
} //if
|
||||
if(matches)
|
||||
return index;
|
||||
if(-1<theNewStartPos){
|
||||
index=theNewStartPos-1;
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //while
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -177,7 +177,7 @@ nsString2::nsString2(const nsStr &aString,eCharSize aCharSize,nsIMemoryAgent* an
|
|||
* @param reference to another nsString2
|
||||
*/
|
||||
nsString2::nsString2(const nsString2& aString) :mAgent(aString.mAgent) {
|
||||
nsStr::Initialize(*this,(eCharSize)aString.mCharSize);
|
||||
nsStr::Initialize(*this,aString.mCharSize);
|
||||
nsStr::Assign(*this,aString,0,aString.mLength,mAgent);
|
||||
}
|
||||
|
||||
|
@ -267,9 +267,8 @@ void nsString2::SetCapacity(PRUint32 aLength) {
|
|||
* @return ptr to internal buffer (if 1-byte), otherwise NULL
|
||||
*/
|
||||
const char* nsString2::GetBuffer(void) const {
|
||||
if(!mCharSize)
|
||||
return mStr;
|
||||
return 0;
|
||||
const char* result=(eOneByte==mCharSize) ? mStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +277,8 @@ const char* nsString2::GetBuffer(void) const {
|
|||
* @return ptr to internal buffer (if 2-byte), otherwise NULL
|
||||
*/
|
||||
const PRUnichar* nsString2::GetUnicode(void) const {
|
||||
if(mCharSize)
|
||||
return (PRUnichar*)mUStr;
|
||||
return 0;
|
||||
const PRUnichar* result=(eTwoByte==mCharSize) ? mUStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,7 +303,7 @@ PRUnichar nsString2::Last(void) const{
|
|||
PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){
|
||||
PRBool result=PR_FALSE;
|
||||
if(anIndex<mLength){
|
||||
if(!mCharSize)
|
||||
if(eOneByte==mCharSize)
|
||||
mStr[anIndex]=char(aChar);
|
||||
else mUStr[anIndex]=aChar;
|
||||
result=PR_TRUE;
|
||||
|
@ -403,7 +401,7 @@ nsSubsumeStr nsString2::operator+(PRUnichar aChar) {
|
|||
void nsString2::ToUCS2(PRUint32 aStartOffset){
|
||||
static CTableConstructor gTableConstructor;
|
||||
if(aStartOffset<mLength){
|
||||
if(mCharSize) {
|
||||
if(eTwoByte==mCharSize) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=aStartOffset;theIndex<mLength;theIndex++){
|
||||
unsigned char ch = (unsigned char)mUStr[theIndex];
|
||||
|
@ -488,14 +486,18 @@ nsString2& nsString2::StripWhitespace() {
|
|||
*/
|
||||
nsString2& nsString2::ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(eTwoByte==mCharSize) {
|
||||
if(mUStr[theIndex]==aSourceChar)
|
||||
if(eTwoByte==mCharSize){
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mUStr[theIndex]==aSourceChar) {
|
||||
mUStr[theIndex]=aDestChar;
|
||||
}//if
|
||||
}
|
||||
else {
|
||||
if(mStr[theIndex]==aSourceChar)
|
||||
}
|
||||
else{
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mStr[theIndex]==(char)aSourceChar) {
|
||||
mStr[theIndex]=(char)aDestChar;
|
||||
}//if
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
@ -570,9 +572,11 @@ nsString2* nsString2::ToNewString() const {
|
|||
char* nsString2::ToNewCString() const {
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
char* result=new char[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -585,9 +589,11 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
PRUnichar* result=new PRUnichar[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -597,15 +603,19 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength) const{
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength,PRUint32 anOffset) const{
|
||||
PRUint32 theLength=0;
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,0,theLength,mAgent);
|
||||
if(0<aBufLength){
|
||||
if(0<aBufLength){
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,anOffset,theLength,mAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
aBuf[theLength]=0;
|
||||
return aBuf;
|
||||
|
@ -711,8 +721,10 @@ PRInt32 nsString2::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -723,8 +735,10 @@ nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsString2& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1704,16 +1718,27 @@ void nsString2::DebugDump(ostream& aStream) const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
ostream& operator<<(ostream& os,nsString2& aString){
|
||||
if(PR_FALSE==aString.mCharSize) {
|
||||
os<<aString.mStr;
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString){
|
||||
if(eOneByte==aString.mCharSize) {
|
||||
aStream<<aString.mStr;
|
||||
}
|
||||
else{
|
||||
char* theStr=aString.ToNewCString();
|
||||
os<<theStr;
|
||||
delete [] theStr;
|
||||
PRUint32 theOffset=0;
|
||||
const PRUint32 theBufSize=300;
|
||||
char theBuf[theBufSize+1];
|
||||
PRUint32 theCount=0;
|
||||
PRUint32 theRemains=0;
|
||||
|
||||
while(theOffset<aString.mLength){
|
||||
theRemains=aString.mLength-theOffset;
|
||||
theCount=(theRemains<theBufSize) ? theRemains : theBufSize;
|
||||
aString.ToCString(theBuf,theCount+1,theOffset);
|
||||
theBuf[theCount]=0;
|
||||
aStream<<theBuf;
|
||||
theOffset+=theCount;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1765,8 +1790,8 @@ nsAutoString2::nsAutoString2(eCharSize aCharSize) : nsString2(aCharSize){
|
|||
* @param anExtBuffer describes an external buffer
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCharSize)aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,(eCharSize)aStr.mCharSize,PR_FALSE);
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2(aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,aStr.mCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
Assign(aCString);
|
||||
|
@ -1776,7 +1801,7 @@ nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCha
|
|||
* Copy construct from ascii c-string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2((eCharSize)aCharSize) {
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2(aCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aCharSize)-1,0,aCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
|
@ -1881,7 +1906,7 @@ nsAutoString2::nsAutoString2(PRUnichar aChar,eCharSize aCharSize) : nsString2(aC
|
|||
* @update gess 1/4/99
|
||||
* @param reference to a subsumeString
|
||||
*/
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2((eCharSize)aSubsumeStr.mCharSize) {
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2(aSubsumeStr.mCharSize) {
|
||||
mAgent=0;
|
||||
Subsume(*this,aSubsumeStr);
|
||||
}
|
||||
|
@ -1900,11 +1925,11 @@ void nsAutoString2::SizeOf(nsISizeOfHandler* aHandler) const {
|
|||
aHandler->Add(mCapacity << mCharSize);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
|
@ -1913,13 +1938,26 @@ nsSubsumeStr::nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLe
|
|||
mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength) : nsString2(eOneByte) {
|
||||
mStr=aString;
|
||||
mCapacity=mLength=(-1==aLength) ? strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
IMPLEMENTATION of nsCAutoString, which is a vanilla string class that
|
||||
only ever stores 1 byte character strings. Typically you'll use this
|
||||
class to hold a pointer to a char*, which comes from an nsString.
|
||||
***********************************************************************/
|
||||
nsCAutoString::nsCAutoString(const nsString2& aString) : nsAutoString(aString,eOneByte){
|
||||
}
|
||||
|
||||
nsCAutoString::operator const char*() const {
|
||||
return (const char*)mStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
/***********************************************************************
|
||||
|
@ -1939,6 +1977,21 @@ CStringTester::CStringTester() {
|
|||
nsString2 theString0("foo",theSize); //watch it construct and destruct
|
||||
}
|
||||
|
||||
//Let's test our autoCStrings...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
nsCAutoString theCStr(theString);
|
||||
}
|
||||
|
||||
//now let's test out various features of out SubsumeStrs...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
|
||||
nsString2 theString2=theString+" there!"; //a subsumestr should be constructed and returned by operator+()
|
||||
nsSubsumeStr theSubStr=theString2.left(5);
|
||||
int x=5;
|
||||
}
|
||||
|
||||
{
|
||||
//this test makes sure that autostrings who assume ownership of a buffer,
|
||||
//don't also try to copy that buffer onto itself... (was a bug)
|
||||
|
|
|
@ -356,7 +356,7 @@ PRUnichar* ToNewUnicode() const;
|
|||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength) const;
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
|
@ -725,7 +725,7 @@ virtual void DebugDump(ostream& aStream) const;
|
|||
};
|
||||
|
||||
extern NS_COM int fputs(const nsString2& aString, FILE* out);
|
||||
ostream& operator<<(ostream& os,nsString2& aString);
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString);
|
||||
|
||||
|
||||
/**************************************************************
|
||||
|
@ -792,6 +792,17 @@ public:
|
|||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
|
||||
***************************************************************/
|
||||
class NS_COM nsCAutoString: public nsAutoString{
|
||||
public:
|
||||
nsCAutoString(const nsString2& aString);
|
||||
operator const char*() const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -8,14 +8,14 @@
|
|||
* 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.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
|||
aDest.mStr=new char[theSize];
|
||||
}
|
||||
aDest.mOwnsBuffer=1;
|
||||
return PR_TRUE;
|
||||
return PRBool(aDest.mStr!=0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ void nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength,nsIMemoryAgent* an
|
|||
void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgent) {
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,(eCharSize)aDest.mCharSize);
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
nsIMemoryAgent* theAgent=(anAgent) ? anAgent : GetDefaultAgent();
|
||||
EnsureCapacity(theTempStr,aNewLength,theAgent);
|
||||
|
@ -265,8 +265,10 @@ void nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength,nsIMemoryAgent* anAgen
|
|||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount,nsIMemoryAgent* anAgent){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
if(&aDest!=&aSource){
|
||||
Truncate(aDest,0,anAgent);
|
||||
Append(aDest,aSource,anOffset,aCount,anAgent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,7 +325,7 @@ void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUin
|
|||
GrowCapacity(aDest,aDest.mLength+theLength,anAgent);
|
||||
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][PR_TRUE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
|
@ -360,7 +362,7 @@ void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount,nsIMemoryAg
|
|||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][PR_FALSE])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
}
|
||||
else Truncate(aDest,aDestOffset,anAgent);
|
||||
|
@ -440,31 +442,48 @@ void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRUint32 aChar,PRBool aEli
|
|||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRUint32 anOffset) {
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0) && (anOffset<aTarget.mLength)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
//This little block of code builds up the boyer-moore skip table.
|
||||
//It might be nicer if this could be generated externally as passed in to improve performance.
|
||||
const int theSize=256;
|
||||
int theSkipTable[theSize];
|
||||
PRUint32 theIndex=0;
|
||||
for (theIndex=0;theIndex<theSize;++theIndex) {
|
||||
theSkipTable[theIndex]=aTarget.mLength;
|
||||
theSkipTable[theIndex]=theCopy.mLength;
|
||||
}
|
||||
for (theIndex=0;theIndex<aTarget.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(aTarget,theIndex)]=(aTarget.mLength-theIndex-1);
|
||||
for (theIndex=0;theIndex<theCopy.mLength-1;++theIndex) {
|
||||
theSkipTable[(PRUint32)GetCharAt(theCopy,theIndex)]=(theCopy.mLength-theIndex-1);
|
||||
}
|
||||
|
||||
//and now we do the actual searching.
|
||||
PRUint32 theMaxIndex=aDest.mLength-anOffset;
|
||||
for (theIndex=aTarget.mLength-1; theIndex< theMaxIndex; theIndex+= theSkipTable[(unsigned char)GetCharAt(aDest,theIndex)]) {
|
||||
int theBufIndex=theIndex;
|
||||
int thePatIndex=aTarget.mLength-1;
|
||||
while((thePatIndex>=0) && (GetCharAt(aDest,theBufIndex)==GetCharAt(aTarget,thePatIndex))){
|
||||
--theBufIndex;
|
||||
--thePatIndex;
|
||||
int iBuf =theIndex;
|
||||
int iPat=aTarget.mLength-1;
|
||||
|
||||
PRBool matches=PR_TRUE;
|
||||
while((iPat>=0) && (matches)){
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,iPat);
|
||||
PRUnichar theDestChar=GetCharAt(aDest,iBuf);
|
||||
if(aIgnoreCase)
|
||||
theDestChar=nsCRT::ToLower(theDestChar);
|
||||
matches=PRBool(theTargetChar==theDestChar);
|
||||
if(matches){
|
||||
--iBuf;
|
||||
--iPat;
|
||||
}
|
||||
}
|
||||
if(-1==thePatIndex){
|
||||
return anOffset+theBufIndex+1;
|
||||
if(-1==iPat){
|
||||
return anOffset+iBuf+1;
|
||||
}
|
||||
}
|
||||
} //for
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
}
|
||||
|
@ -509,41 +528,38 @@ 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 index=(anOffset ? anOffset : aDest.mLength-aTarget.mLength+1);
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
PRInt32 theNewStartPos=-1;
|
||||
PRUnichar theFirstTargetChar=GetCharAt(aTarget,0);
|
||||
PRUnichar theLastTargetChar=GetCharAt(aTarget,aTarget.mLength-1);
|
||||
PRInt32 theTargetMax=aTarget.mLength;
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
while(index--) {
|
||||
PRInt32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if((aDest.mLength>0) && (aTarget.mLength>0)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength,0);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,false); //force to lowercase
|
||||
}
|
||||
|
||||
if(anOffset+aTarget.mLength<=aDest.mLength) {
|
||||
int32 theTargetMax=theCopy.mLength;
|
||||
while(index--) {
|
||||
int32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
if(anOffset+theCopy.mLength<=aDest.mLength) {
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theChar=GetCharAt(aDest,index+theSubIndex);
|
||||
if(theSubIndex>0) {
|
||||
if(theFirstTargetChar==theChar){
|
||||
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=GetCharAt(aTarget,theSubIndex);
|
||||
matches=PRBool(theChar==theTargetChar);
|
||||
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
|
||||
matches=PRBool(theDestChar==theTargetChar);
|
||||
} //while
|
||||
} //if
|
||||
if(matches)
|
||||
return index;
|
||||
if(-1<theNewStartPos){
|
||||
index=theNewStartPos-1;
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //while
|
||||
nsStr::Destroy(theCopy,0);
|
||||
}//if
|
||||
return kNotFound;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -177,7 +177,7 @@ nsString2::nsString2(const nsStr &aString,eCharSize aCharSize,nsIMemoryAgent* an
|
|||
* @param reference to another nsString2
|
||||
*/
|
||||
nsString2::nsString2(const nsString2& aString) :mAgent(aString.mAgent) {
|
||||
nsStr::Initialize(*this,(eCharSize)aString.mCharSize);
|
||||
nsStr::Initialize(*this,aString.mCharSize);
|
||||
nsStr::Assign(*this,aString,0,aString.mLength,mAgent);
|
||||
}
|
||||
|
||||
|
@ -267,9 +267,8 @@ void nsString2::SetCapacity(PRUint32 aLength) {
|
|||
* @return ptr to internal buffer (if 1-byte), otherwise NULL
|
||||
*/
|
||||
const char* nsString2::GetBuffer(void) const {
|
||||
if(!mCharSize)
|
||||
return mStr;
|
||||
return 0;
|
||||
const char* result=(eOneByte==mCharSize) ? mStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -278,9 +277,8 @@ const char* nsString2::GetBuffer(void) const {
|
|||
* @return ptr to internal buffer (if 2-byte), otherwise NULL
|
||||
*/
|
||||
const PRUnichar* nsString2::GetUnicode(void) const {
|
||||
if(mCharSize)
|
||||
return (PRUnichar*)mUStr;
|
||||
return 0;
|
||||
const PRUnichar* result=(eTwoByte==mCharSize) ? mUStr : 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -305,7 +303,7 @@ PRUnichar nsString2::Last(void) const{
|
|||
PRBool nsString2::SetCharAt(PRUnichar aChar,PRUint32 anIndex){
|
||||
PRBool result=PR_FALSE;
|
||||
if(anIndex<mLength){
|
||||
if(!mCharSize)
|
||||
if(eOneByte==mCharSize)
|
||||
mStr[anIndex]=char(aChar);
|
||||
else mUStr[anIndex]=aChar;
|
||||
result=PR_TRUE;
|
||||
|
@ -403,7 +401,7 @@ nsSubsumeStr nsString2::operator+(PRUnichar aChar) {
|
|||
void nsString2::ToUCS2(PRUint32 aStartOffset){
|
||||
static CTableConstructor gTableConstructor;
|
||||
if(aStartOffset<mLength){
|
||||
if(mCharSize) {
|
||||
if(eTwoByte==mCharSize) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=aStartOffset;theIndex<mLength;theIndex++){
|
||||
unsigned char ch = (unsigned char)mUStr[theIndex];
|
||||
|
@ -488,14 +486,18 @@ nsString2& nsString2::StripWhitespace() {
|
|||
*/
|
||||
nsString2& nsString2::ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar) {
|
||||
PRUint32 theIndex=0;
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(eTwoByte==mCharSize) {
|
||||
if(mUStr[theIndex]==aSourceChar)
|
||||
if(eTwoByte==mCharSize){
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mUStr[theIndex]==aSourceChar) {
|
||||
mUStr[theIndex]=aDestChar;
|
||||
}//if
|
||||
}
|
||||
else {
|
||||
if(mStr[theIndex]==aSourceChar)
|
||||
}
|
||||
else{
|
||||
for(theIndex=0;theIndex<mLength;theIndex++){
|
||||
if(mStr[theIndex]==(char)aSourceChar) {
|
||||
mStr[theIndex]=(char)aDestChar;
|
||||
}//if
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
|
@ -570,9 +572,11 @@ nsString2* nsString2::ToNewString() const {
|
|||
char* nsString2::ToNewCString() const {
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
char* result=new char[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eOneByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -585,9 +589,11 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
|
||||
PRUint32 theLength=mLength+2; //one for good measure and one for the Nullchar
|
||||
PRUnichar* result=new PRUnichar[theLength];
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
if(result){
|
||||
nsAutoString2 temp(result,theLength-1,eTwoByte,PR_TRUE);
|
||||
nsStr::Assign(temp,*this,0,mLength,0);
|
||||
temp.mStr=0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -597,15 +603,19 @@ PRUnichar* nsString2::ToNewUnicode() const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength) const{
|
||||
char* nsString2::ToCString(char* aBuf, PRUint32 aBufLength,PRUint32 anOffset) const{
|
||||
PRUint32 theLength=0;
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,0,theLength,mAgent);
|
||||
if(0<aBufLength){
|
||||
if(0<aBufLength){
|
||||
if(aBuf && (0<mLength)) {
|
||||
nsStr temp;
|
||||
nsStr::Initialize(temp,eOneByte);
|
||||
temp.mStr=aBuf;
|
||||
temp.mCapacity=aBufLength-1;
|
||||
theLength = (mLength<aBufLength-1) ? mLength : aBufLength-1;
|
||||
nsStr::Assign(temp,*this,anOffset,theLength,mAgent);
|
||||
}
|
||||
}
|
||||
}
|
||||
aBuf[theLength]=0;
|
||||
return aBuf;
|
||||
|
@ -711,8 +721,10 @@ PRInt32 nsString2::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -723,8 +735,10 @@ nsString2& nsString2::Assign(const nsStr& aString,PRInt32 aCount) {
|
|||
* @return this
|
||||
*/
|
||||
nsString2& nsString2::Assign(const nsString2& aString,PRInt32 aCount) {
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
if(this!=&aString){
|
||||
if(-1==aCount) aCount=aString.mLength;
|
||||
nsStr::Assign(*this,aString,0,aCount,mAgent);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -1704,16 +1718,27 @@ void nsString2::DebugDump(ostream& aStream) const {
|
|||
* @param
|
||||
* @return
|
||||
*/
|
||||
ostream& operator<<(ostream& os,nsString2& aString){
|
||||
if(PR_FALSE==aString.mCharSize) {
|
||||
os<<aString.mStr;
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString){
|
||||
if(eOneByte==aString.mCharSize) {
|
||||
aStream<<aString.mStr;
|
||||
}
|
||||
else{
|
||||
char* theStr=aString.ToNewCString();
|
||||
os<<theStr;
|
||||
delete [] theStr;
|
||||
PRUint32 theOffset=0;
|
||||
const PRUint32 theBufSize=300;
|
||||
char theBuf[theBufSize+1];
|
||||
PRUint32 theCount=0;
|
||||
PRUint32 theRemains=0;
|
||||
|
||||
while(theOffset<aString.mLength){
|
||||
theRemains=aString.mLength-theOffset;
|
||||
theCount=(theRemains<theBufSize) ? theRemains : theBufSize;
|
||||
aString.ToCString(theBuf,theCount+1,theOffset);
|
||||
theBuf[theCount]=0;
|
||||
aStream<<theBuf;
|
||||
theOffset+=theCount;
|
||||
}
|
||||
}
|
||||
return os;
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1765,8 +1790,8 @@ nsAutoString2::nsAutoString2(eCharSize aCharSize) : nsString2(aCharSize){
|
|||
* @param anExtBuffer describes an external buffer
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCharSize)aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,(eCharSize)aStr.mCharSize,PR_FALSE);
|
||||
nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2(aStr.mCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aStr.mCharSize)-1,0,aStr.mCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
Assign(aCString);
|
||||
|
@ -1776,7 +1801,7 @@ nsAutoString2::nsAutoString2(nsStr& aStr,const char* aCString) : nsString2((eCha
|
|||
* Copy construct from ascii c-string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2((eCharSize)aCharSize) {
|
||||
nsAutoString2::nsAutoString2(const char* aCString,eCharSize aCharSize) : nsString2(aCharSize) {
|
||||
nsStr::Initialize(*this,mBuffer,(sizeof(mBuffer)>>aCharSize)-1,0,aCharSize,PR_FALSE);
|
||||
mAgent=0;
|
||||
AddNullTerminator(*this);
|
||||
|
@ -1881,7 +1906,7 @@ nsAutoString2::nsAutoString2(PRUnichar aChar,eCharSize aCharSize) : nsString2(aC
|
|||
* @update gess 1/4/99
|
||||
* @param reference to a subsumeString
|
||||
*/
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2((eCharSize)aSubsumeStr.mCharSize) {
|
||||
nsAutoString2::nsAutoString2( nsSubsumeStr& aSubsumeStr) :nsString2(aSubsumeStr.mCharSize) {
|
||||
mAgent=0;
|
||||
Subsume(*this,aSubsumeStr);
|
||||
}
|
||||
|
@ -1900,11 +1925,11 @@ void nsAutoString2::SizeOf(nsISizeOfHandler* aHandler) const {
|
|||
aHandler->Add(mCapacity << mCharSize);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsString2& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2((eCharSize)aString.mCharSize) {
|
||||
nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString2(aString.mCharSize) {
|
||||
Subsume(*this,aString);
|
||||
}
|
||||
|
||||
|
@ -1913,13 +1938,26 @@ nsSubsumeStr::nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLe
|
|||
mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
|
||||
nsSubsumeStr::nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength) : nsString2(eOneByte) {
|
||||
mStr=aString;
|
||||
mCapacity=mLength=(-1==aLength) ? strlen(aString) : aLength-1;
|
||||
mOwnsBuffer=assumeOwnership;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
IMPLEMENTATION of nsCAutoString, which is a vanilla string class that
|
||||
only ever stores 1 byte character strings. Typically you'll use this
|
||||
class to hold a pointer to a char*, which comes from an nsString.
|
||||
***********************************************************************/
|
||||
nsCAutoString::nsCAutoString(const nsString2& aString) : nsAutoString(aString,eOneByte){
|
||||
}
|
||||
|
||||
nsCAutoString::operator const char*() const {
|
||||
return (const char*)mStr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef RICKG_DEBUG
|
||||
/***********************************************************************
|
||||
|
@ -1939,6 +1977,21 @@ CStringTester::CStringTester() {
|
|||
nsString2 theString0("foo",theSize); //watch it construct and destruct
|
||||
}
|
||||
|
||||
//Let's test our autoCStrings...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
nsCAutoString theCStr(theString);
|
||||
}
|
||||
|
||||
//now let's test out various features of out SubsumeStrs...
|
||||
{
|
||||
nsString2 theString("hello");
|
||||
|
||||
nsString2 theString2=theString+" there!"; //a subsumestr should be constructed and returned by operator+()
|
||||
nsSubsumeStr theSubStr=theString2.left(5);
|
||||
int x=5;
|
||||
}
|
||||
|
||||
{
|
||||
//this test makes sure that autostrings who assume ownership of a buffer,
|
||||
//don't also try to copy that buffer onto itself... (was a bug)
|
||||
|
|
|
@ -356,7 +356,7 @@ PRUnichar* ToNewUnicode() const;
|
|||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength) const;
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
|
@ -725,7 +725,7 @@ virtual void DebugDump(ostream& aStream) const;
|
|||
};
|
||||
|
||||
extern NS_COM int fputs(const nsString2& aString, FILE* out);
|
||||
ostream& operator<<(ostream& os,nsString2& aString);
|
||||
ostream& operator<<(ostream& aStream,const nsString2& aString);
|
||||
|
||||
|
||||
/**************************************************************
|
||||
|
@ -792,6 +792,17 @@ public:
|
|||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
|
||||
***************************************************************/
|
||||
class NS_COM nsCAutoString: public nsAutoString{
|
||||
public:
|
||||
nsCAutoString(const nsString2& aString);
|
||||
operator const char*() const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче