diff --git a/mozilla/string/obsolete/nsStr.cpp b/mozilla/string/obsolete/nsStr.cpp index 2a8e14970a6..44b176bc6d1 100644 --- a/mozilla/string/obsolete/nsStr.cpp +++ b/mozilla/string/obsolete/nsStr.cpp @@ -468,7 +468,7 @@ void nsStrPrivate::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,P if(aEliminateLeading) { while(++theIndex<=theMax) { - PRUnichar theChar=aDest.GetCharAt(theIndex); + PRUnichar theChar=GetCharAt(aDest, theIndex); PRInt32 thePos=::FindChar1(aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); if(kNotFound==thePos) break; @@ -489,7 +489,7 @@ void nsStrPrivate::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,P theIndex=aDest.mLength; PRInt32 theNewLen=theIndex; while(--theIndex>=0) { - PRUnichar theChar=aDest.GetCharAt(theIndex); //read at end now... + PRUnichar theChar=GetCharAt(aDest, theIndex); //read at end now... PRInt32 thePos=::FindChar1(aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); if(kNotFound=0) { - PRUnichar theChar=aDest.GetCharAt(index); - thePos=::FindChar1(aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase,aSet.mLength); - if(kNotFound!=thePos) - return index; - } //while - } - return kNotFound; -} - -PRInt32 nsStrPrivate::RFindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset) { - - NS_ASSERTION(aSet.GetCharSize() == eTwoByte, "Must be 2 byte"); - - PRInt32 index=(0<=anOffset) ? anOffset : aDest.mLength; - PRInt32 thePos; - - //note that the search is inverted here. We're scanning aDest, one char at a time - //but doing the search against the given set. That's why we use 0 as the offset below. - if(0=0) { - PRUnichar theChar=aDest.GetCharAt(index); - thePos=::FindChar2(aSet.mUStr,aSet.mLength,0,theChar,aSet.mLength); - if(kNotFound!=thePos) - return index; - } //while - } - return kNotFound; -} - // from the start of the old nsStrPrivate::StrCompare - now used as helper // routines for nsStrPrivate::Compare1To1 and so forth static inline PRInt32 diff --git a/mozilla/string/obsolete/nsStrPrivate.h b/mozilla/string/obsolete/nsStrPrivate.h index 488930bc566..124bf9c6743 100644 --- a/mozilla/string/obsolete/nsStrPrivate.h +++ b/mozilla/string/obsolete/nsStrPrivate.h @@ -229,21 +229,37 @@ class nsStrPrivate { static PRInt32 FindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); static PRInt32 FindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); - static PRInt32 FindCharInSet1(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - static PRInt32 FindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset); - static PRInt32 RFindSubstr1in1(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindSubstr1in2(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindSubstr2in2(const nsStr& aDest,const nsStr& aSource, PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); - - static PRInt32 RFindCharInSet1(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - static PRInt32 RFindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset); static void Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 anOffset); + static char GetFindInSetFilter(const char *set) + { + // Calculate filter + char filter = ~char(0); // All bits set + while (*set) { + filter &= ~(*set); + ++set; + } + + return filter; + } + static PRUnichar GetFindInSetFilter(const PRUnichar *set) + { + // Calculate filter + PRUnichar filter = ~PRUnichar(0); // All bits set + while (*set) { + filter &= ~(*set); + ++set; + } + return filter; + } + #ifdef NS_STR_STATS static PRBool DidAcquireMemory(void); #endif diff --git a/mozilla/string/obsolete/nsString.cpp b/mozilla/string/obsolete/nsString.cpp index e2aea28ba0e..3c6c66aa913 100644 --- a/mozilla/string/obsolete/nsString.cpp +++ b/mozilla/string/obsolete/nsString.cpp @@ -848,14 +848,35 @@ PRInt32 nsCString::Find(const nsCString& aString,PRBool aIgnoreCase,PRInt32 anOf * * @update gess 2/04/00 * @param char is the character you're trying to find. - * @param aIgnorecase indicates case sensitivity of search * @param anOffset tells us where to start the search; -1 means start at 0. * @param aCount tell us how many chars to search from offset; -1 means use full length. * @return index in aDest where member of aSet occurs, or -1 if not found */ PRInt32 nsCString::FindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) const{ - PRInt32 result=nsStrPrivate::FindChar1(*this,aChar,anOffset,aCount); - return result; + if (anOffset < 0) + anOffset=0; + + if (aCount < 0) + aCount = (PRInt32)mLength; + + if ((aChar < 256) && (0 < mLength) && + ((PRUint32)anOffset < mLength) && (0 < aCount)) { + // We'll only search if the given aChar is 8-bit, + // since this string is 8-bit. + + PRUint32 last = anOffset + aCount; + PRUint32 end = (last < mLength) ? last : mLength; + PRUint32 searchLen = end - anOffset; // Will be > 0 by the conditions above + const char* leftp = mStr + anOffset; + unsigned char theChar = (unsigned char) aChar; + + const char* result = (const char*)memchr(leftp, (int)theChar, searchLen); + + if (result) + return result - mStr; + } + + return kNotFound; } /** @@ -868,21 +889,46 @@ PRInt32 nsCString::FindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) con * @return */ PRInt32 nsCString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ - NS_ASSERTION(0!=aCStringSet,kNullPointerError); + if (anOffset < 0) + anOffset = 0; - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr=(char*)aCStringSet; - result=nsStrPrivate::FindCharInSet1(*this,temp,PR_FALSE,anOffset); + if(*aCStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + char filter = nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const char* endChar = mStr + mLength; + for(char *charp = mStr + anOffset; charp < endChar; ++charp) { + char currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *charInSet = aCStringSet; + char setChar = *charInSet; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mStr; // The index of the found char + } + setChar = *(++charInSet); + } + } // end for all chars in the string } - return result; + return kNotFound; } PRInt32 nsCString::FindCharInSet(const nsCString& aSet,PRInt32 anOffset) const{ - PRInt32 result=nsStrPrivate::FindCharInSet1(*this,aSet,PR_FALSE,anOffset); + // This assumes that the set doesn't contain the null char. + PRInt32 result = FindCharInSet(aSet.get(), anOffset); return result; } @@ -952,19 +998,46 @@ PRInt32 nsCString::RFindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) co PRInt32 nsCString::RFindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aCStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr=(char*)aCStringSet; - result=nsStrPrivate::RFindCharInSet1(*this,temp,PR_FALSE,anOffset); + if (anOffset < 0 || (PRUint32)anOffset > mLength-1) + anOffset = mLength-1; + + if(*aCStringSet) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + char filter = nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const char* end = mStr; + for(char *charp = mStr + anOffset; charp > end; --charp) { + char currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *setp = aCStringSet; + char setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mStr; + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } PRInt32 nsCString::RFindCharInSet(const nsCString& aSet,PRInt32 anOffset) const{ - PRInt32 result=nsStrPrivate::RFindCharInSet1(*this,aSet,PR_FALSE,anOffset); + // Assumes that the set doesn't contain any nulls. + PRInt32 result = RFindCharInSet(aSet.get(), anOffset); return result; } diff --git a/mozilla/string/obsolete/nsString2.cpp b/mozilla/string/obsolete/nsString2.cpp index 8006c2de42e..32e1360978f 100644 --- a/mozilla/string/obsolete/nsString2.cpp +++ b/mozilla/string/obsolete/nsString2.cpp @@ -857,6 +857,39 @@ nsString::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy Searching methods... *********************************************************************/ + /** + * Search for given character within this string + * + * @param aChar is the character to search for + * @param anOffset tells us where in this string to start searching + (optional parameter) + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. (optional parameter) + * @return offset in string, or -1 (kNotFound) + */ +PRInt32 nsString::FindChar(PRUnichar aChar, PRInt32 anOffset/*=0*/, PRInt32 aCount/*=-1*/) const{ + if (anOffset < 0) + anOffset=0; + + if (aCount < 0) + aCount = (PRInt32)mLength; + + if ((0 < mLength) && ((PRUint32)anOffset < mLength) && (0 < aCount)) { + PRUint32 last = anOffset + aCount; + PRUint32 end = (last < mLength) ? last : mLength; + const PRUnichar* charp = mUStr + anOffset; + const PRUnichar* endp = mUStr + end; + + while (charp < endp && *charp != aChar) { + ++charp; + } + + if (charp < endp) + return charp - mUStr; + } + return kNotFound; +} + /** * search for given string within this string * @@ -938,15 +971,42 @@ PRInt32 nsString::Find(const nsAFlatString& aString,PRInt32 anOffset,PRInt32 aCo PRInt32 nsString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aCStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr = NS_CONST_CAST(char*, aCStringSet); - result=nsStrPrivate::FindCharInSet1(*this,temp,PR_FALSE,anOffset); + if (anOffset < 0) + anOffset = 0; + + if(*aCStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = (~PRUnichar(0)^~char(0)) | + nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const PRUnichar* endChar = mUStr + mLength; + for(PRUnichar *charp = mUStr + anOffset; charp < endChar; ++charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *setp = aCStringSet; + PRUnichar setChar = PRUnichar(*setp); + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; // The index of the found char + } + setChar = PRUnichar(*(++setp)); + } + } // end for all chars in the string } - return result; + return kNotFound; } /** @@ -961,15 +1021,41 @@ PRInt32 nsString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ PRInt32 nsString::FindCharInSet(const PRUnichar* aStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eTwoByte); - temp.mLength=nsCharTraits::length(aStringSet); - temp.mUStr=NS_CONST_CAST(PRUnichar*, aStringSet); - result=nsStrPrivate::FindCharInSet2(*this,temp,anOffset); + if (anOffset < 0) + anOffset = 0; + + if (*aStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = nsStrPrivate::GetFindInSetFilter(aStringSet); + + const PRUnichar* endChar = mUStr + mLength; + for(PRUnichar *charp = mUStr + anOffset;charp < endChar; ++charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const PRUnichar *setp = aStringSet; + PRUnichar setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; // The index of the found char + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } /** @@ -1056,15 +1142,41 @@ PRInt32 nsString::RFindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) con PRInt32 nsString::RFindCharInSet(const PRUnichar* aStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eTwoByte); - temp.mLength = nsCharTraits::length(aStringSet); - temp.mUStr = NS_CONST_CAST(PRUnichar*, aStringSet); - result=nsStrPrivate::RFindCharInSet2(*this,temp,anOffset); + if (anOffset < 0 || (PRUint32)anOffset >= mLength) + anOffset = mLength - 1; + + if(*aStringSet) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = nsStrPrivate::GetFindInSetFilter(aStringSet); + + const PRUnichar* endp = mUStr - 1; + for(PRUnichar *charp = mUStr + anOffset; charp > endp; --charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const PRUnichar* setp = aStringSet; + PRUnichar setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } diff --git a/mozilla/string/obsolete/nsString2.h b/mozilla/string/obsolete/nsString2.h index 005e9b21dae..b491a9a6cf6 100644 --- a/mozilla/string/obsolete/nsString2.h +++ b/mozilla/string/obsolete/nsString2.h @@ -324,14 +324,26 @@ public: /********************************************************************** Searching methods... *********************************************************************/ + /** + * Search for given character within this string + * + * @param aChar is the character to search for + * @param anOffset tells us where in this string to start searching + (optional parameter) + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. (optional parameter) + * @return offset in string, or -1 (kNotFound) + */ + PRInt32 FindChar(PRUnichar aChar, PRInt32 anOffset=0, PRInt32 aCount=-1) const; /** * Search for given substring within this string * * @param aString is substring to be sought in this * @param aIgnoreCase selects case sensitivity - * @param anOffset tells us where in this strig to start searching - * @param aCount tells us how many iterations to make starting at the given offset + * @param anOffset tells us where in this string to start searching + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. * @return offset in string, or -1 (kNotFound) */ PRInt32 Find(const nsCString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; @@ -350,9 +362,6 @@ public: */ PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const; PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsString& aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsCString& aString,PRInt32 anOffset=0) const; - /** * This methods scans the string backwards, looking for the given string @@ -377,7 +386,6 @@ public: * @param aCount tells us how many iterations to make starting at the given offset * @return find pos in string, or -1 (kNotFound) */ - //PRInt32 RFind(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const; PRInt32 RFindChar(PRUnichar aChar,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; /** diff --git a/mozilla/xpcom/string/obsolete/nsStr.cpp b/mozilla/xpcom/string/obsolete/nsStr.cpp index 2a8e14970a6..44b176bc6d1 100644 --- a/mozilla/xpcom/string/obsolete/nsStr.cpp +++ b/mozilla/xpcom/string/obsolete/nsStr.cpp @@ -468,7 +468,7 @@ void nsStrPrivate::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,P if(aEliminateLeading) { while(++theIndex<=theMax) { - PRUnichar theChar=aDest.GetCharAt(theIndex); + PRUnichar theChar=GetCharAt(aDest, theIndex); PRInt32 thePos=::FindChar1(aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); if(kNotFound==thePos) break; @@ -489,7 +489,7 @@ void nsStrPrivate::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,P theIndex=aDest.mLength; PRInt32 theNewLen=theIndex; while(--theIndex>=0) { - PRUnichar theChar=aDest.GetCharAt(theIndex); //read at end now... + PRUnichar theChar=GetCharAt(aDest, theIndex); //read at end now... PRInt32 thePos=::FindChar1(aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); if(kNotFound=0) { - PRUnichar theChar=aDest.GetCharAt(index); - thePos=::FindChar1(aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase,aSet.mLength); - if(kNotFound!=thePos) - return index; - } //while - } - return kNotFound; -} - -PRInt32 nsStrPrivate::RFindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset) { - - NS_ASSERTION(aSet.GetCharSize() == eTwoByte, "Must be 2 byte"); - - PRInt32 index=(0<=anOffset) ? anOffset : aDest.mLength; - PRInt32 thePos; - - //note that the search is inverted here. We're scanning aDest, one char at a time - //but doing the search against the given set. That's why we use 0 as the offset below. - if(0=0) { - PRUnichar theChar=aDest.GetCharAt(index); - thePos=::FindChar2(aSet.mUStr,aSet.mLength,0,theChar,aSet.mLength); - if(kNotFound!=thePos) - return index; - } //while - } - return kNotFound; -} - // from the start of the old nsStrPrivate::StrCompare - now used as helper // routines for nsStrPrivate::Compare1To1 and so forth static inline PRInt32 diff --git a/mozilla/xpcom/string/obsolete/nsStrPrivate.h b/mozilla/xpcom/string/obsolete/nsStrPrivate.h index 488930bc566..124bf9c6743 100644 --- a/mozilla/xpcom/string/obsolete/nsStrPrivate.h +++ b/mozilla/xpcom/string/obsolete/nsStrPrivate.h @@ -229,21 +229,37 @@ class nsStrPrivate { static PRInt32 FindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); static PRInt32 FindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); - static PRInt32 FindCharInSet1(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - static PRInt32 FindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset); - static PRInt32 RFindSubstr1in1(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindSubstr1in2(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindSubstr2in2(const nsStr& aDest,const nsStr& aSource, PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindChar1(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); static PRInt32 RFindChar2(const nsStr& aDest,PRUnichar aChar, PRInt32 anOffset,PRInt32 aCount); - - static PRInt32 RFindCharInSet1(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - static PRInt32 RFindCharInSet2(const nsStr& aDest,const nsStr& aSet,PRInt32 anOffset); static void Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 anOffset); + static char GetFindInSetFilter(const char *set) + { + // Calculate filter + char filter = ~char(0); // All bits set + while (*set) { + filter &= ~(*set); + ++set; + } + + return filter; + } + static PRUnichar GetFindInSetFilter(const PRUnichar *set) + { + // Calculate filter + PRUnichar filter = ~PRUnichar(0); // All bits set + while (*set) { + filter &= ~(*set); + ++set; + } + return filter; + } + #ifdef NS_STR_STATS static PRBool DidAcquireMemory(void); #endif diff --git a/mozilla/xpcom/string/obsolete/nsString.cpp b/mozilla/xpcom/string/obsolete/nsString.cpp index e2aea28ba0e..3c6c66aa913 100644 --- a/mozilla/xpcom/string/obsolete/nsString.cpp +++ b/mozilla/xpcom/string/obsolete/nsString.cpp @@ -848,14 +848,35 @@ PRInt32 nsCString::Find(const nsCString& aString,PRBool aIgnoreCase,PRInt32 anOf * * @update gess 2/04/00 * @param char is the character you're trying to find. - * @param aIgnorecase indicates case sensitivity of search * @param anOffset tells us where to start the search; -1 means start at 0. * @param aCount tell us how many chars to search from offset; -1 means use full length. * @return index in aDest where member of aSet occurs, or -1 if not found */ PRInt32 nsCString::FindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) const{ - PRInt32 result=nsStrPrivate::FindChar1(*this,aChar,anOffset,aCount); - return result; + if (anOffset < 0) + anOffset=0; + + if (aCount < 0) + aCount = (PRInt32)mLength; + + if ((aChar < 256) && (0 < mLength) && + ((PRUint32)anOffset < mLength) && (0 < aCount)) { + // We'll only search if the given aChar is 8-bit, + // since this string is 8-bit. + + PRUint32 last = anOffset + aCount; + PRUint32 end = (last < mLength) ? last : mLength; + PRUint32 searchLen = end - anOffset; // Will be > 0 by the conditions above + const char* leftp = mStr + anOffset; + unsigned char theChar = (unsigned char) aChar; + + const char* result = (const char*)memchr(leftp, (int)theChar, searchLen); + + if (result) + return result - mStr; + } + + return kNotFound; } /** @@ -868,21 +889,46 @@ PRInt32 nsCString::FindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) con * @return */ PRInt32 nsCString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ - NS_ASSERTION(0!=aCStringSet,kNullPointerError); + if (anOffset < 0) + anOffset = 0; - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr=(char*)aCStringSet; - result=nsStrPrivate::FindCharInSet1(*this,temp,PR_FALSE,anOffset); + if(*aCStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + char filter = nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const char* endChar = mStr + mLength; + for(char *charp = mStr + anOffset; charp < endChar; ++charp) { + char currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *charInSet = aCStringSet; + char setChar = *charInSet; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mStr; // The index of the found char + } + setChar = *(++charInSet); + } + } // end for all chars in the string } - return result; + return kNotFound; } PRInt32 nsCString::FindCharInSet(const nsCString& aSet,PRInt32 anOffset) const{ - PRInt32 result=nsStrPrivate::FindCharInSet1(*this,aSet,PR_FALSE,anOffset); + // This assumes that the set doesn't contain the null char. + PRInt32 result = FindCharInSet(aSet.get(), anOffset); return result; } @@ -952,19 +998,46 @@ PRInt32 nsCString::RFindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) co PRInt32 nsCString::RFindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aCStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr=(char*)aCStringSet; - result=nsStrPrivate::RFindCharInSet1(*this,temp,PR_FALSE,anOffset); + if (anOffset < 0 || (PRUint32)anOffset > mLength-1) + anOffset = mLength-1; + + if(*aCStringSet) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + char filter = nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const char* end = mStr; + for(char *charp = mStr + anOffset; charp > end; --charp) { + char currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *setp = aCStringSet; + char setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mStr; + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } PRInt32 nsCString::RFindCharInSet(const nsCString& aSet,PRInt32 anOffset) const{ - PRInt32 result=nsStrPrivate::RFindCharInSet1(*this,aSet,PR_FALSE,anOffset); + // Assumes that the set doesn't contain any nulls. + PRInt32 result = RFindCharInSet(aSet.get(), anOffset); return result; } diff --git a/mozilla/xpcom/string/obsolete/nsString2.cpp b/mozilla/xpcom/string/obsolete/nsString2.cpp index 8006c2de42e..32e1360978f 100644 --- a/mozilla/xpcom/string/obsolete/nsString2.cpp +++ b/mozilla/xpcom/string/obsolete/nsString2.cpp @@ -857,6 +857,39 @@ nsString::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy Searching methods... *********************************************************************/ + /** + * Search for given character within this string + * + * @param aChar is the character to search for + * @param anOffset tells us where in this string to start searching + (optional parameter) + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. (optional parameter) + * @return offset in string, or -1 (kNotFound) + */ +PRInt32 nsString::FindChar(PRUnichar aChar, PRInt32 anOffset/*=0*/, PRInt32 aCount/*=-1*/) const{ + if (anOffset < 0) + anOffset=0; + + if (aCount < 0) + aCount = (PRInt32)mLength; + + if ((0 < mLength) && ((PRUint32)anOffset < mLength) && (0 < aCount)) { + PRUint32 last = anOffset + aCount; + PRUint32 end = (last < mLength) ? last : mLength; + const PRUnichar* charp = mUStr + anOffset; + const PRUnichar* endp = mUStr + end; + + while (charp < endp && *charp != aChar) { + ++charp; + } + + if (charp < endp) + return charp - mUStr; + } + return kNotFound; +} + /** * search for given string within this string * @@ -938,15 +971,42 @@ PRInt32 nsString::Find(const nsAFlatString& aString,PRInt32 anOffset,PRInt32 aCo PRInt32 nsString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aCStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aCStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eOneByte); - temp.mLength=nsCharTraits::length(aCStringSet); - temp.mStr = NS_CONST_CAST(char*, aCStringSet); - result=nsStrPrivate::FindCharInSet1(*this,temp,PR_FALSE,anOffset); + if (anOffset < 0) + anOffset = 0; + + if(*aCStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = (~PRUnichar(0)^~char(0)) | + nsStrPrivate::GetFindInSetFilter(aCStringSet); + + const PRUnichar* endChar = mUStr + mLength; + for(PRUnichar *charp = mUStr + anOffset; charp < endChar; ++charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const char *setp = aCStringSet; + PRUnichar setChar = PRUnichar(*setp); + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; // The index of the found char + } + setChar = PRUnichar(*(++setp)); + } + } // end for all chars in the string } - return result; + return kNotFound; } /** @@ -961,15 +1021,41 @@ PRInt32 nsString::FindCharInSet(const char* aCStringSet,PRInt32 anOffset) const{ PRInt32 nsString::FindCharInSet(const PRUnichar* aStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eTwoByte); - temp.mLength=nsCharTraits::length(aStringSet); - temp.mUStr=NS_CONST_CAST(PRUnichar*, aStringSet); - result=nsStrPrivate::FindCharInSet2(*this,temp,anOffset); + if (anOffset < 0) + anOffset = 0; + + if (*aStringSet && (PRUint32)anOffset < mLength) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = nsStrPrivate::GetFindInSetFilter(aStringSet); + + const PRUnichar* endChar = mUStr + mLength; + for(PRUnichar *charp = mUStr + anOffset;charp < endChar; ++charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const PRUnichar *setp = aStringSet; + PRUnichar setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; // The index of the found char + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } /** @@ -1056,15 +1142,41 @@ PRInt32 nsString::RFindChar(PRUnichar aChar,PRInt32 anOffset,PRInt32 aCount) con PRInt32 nsString::RFindCharInSet(const PRUnichar* aStringSet,PRInt32 anOffset) const{ NS_ASSERTION(0!=aStringSet,kNullPointerError); - PRInt32 result=kNotFound; - if(aStringSet) { - nsStr temp; - nsStrPrivate::Initialize(temp,eTwoByte); - temp.mLength = nsCharTraits::length(aStringSet); - temp.mUStr = NS_CONST_CAST(PRUnichar*, aStringSet); - result=nsStrPrivate::RFindCharInSet2(*this,temp,anOffset); + if (anOffset < 0 || (PRUint32)anOffset >= mLength) + anOffset = mLength - 1; + + if(*aStringSet) { + // Build filter that will be used to filter out characters with + // bits that none of the terminal chars have. This works very well + // because searches are often done for chars with only the last + // 4-6 bits set and normal ascii letters have bit 7 set. Other + // letters have even higher bits set. + + // Calculate filter + PRUnichar filter = nsStrPrivate::GetFindInSetFilter(aStringSet); + + const PRUnichar* endp = mUStr - 1; + for(PRUnichar *charp = mUStr + anOffset; charp > endp; --charp) { + PRUnichar currentChar = *charp; + // Check if all bits are in the required area + if (currentChar & filter) { + // They were not. Go on with the next char. + continue; + } + + // Test all chars + const PRUnichar* setp = aStringSet; + PRUnichar setChar = *setp; + while (setChar) { + if (setChar == currentChar) { + // Found it! + return charp - mUStr; + } + setChar = *(++setp); + } + } // end for all chars in the string } - return result; + return kNotFound; } diff --git a/mozilla/xpcom/string/obsolete/nsString2.h b/mozilla/xpcom/string/obsolete/nsString2.h index 005e9b21dae..b491a9a6cf6 100644 --- a/mozilla/xpcom/string/obsolete/nsString2.h +++ b/mozilla/xpcom/string/obsolete/nsString2.h @@ -324,14 +324,26 @@ public: /********************************************************************** Searching methods... *********************************************************************/ + /** + * Search for given character within this string + * + * @param aChar is the character to search for + * @param anOffset tells us where in this string to start searching + (optional parameter) + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. (optional parameter) + * @return offset in string, or -1 (kNotFound) + */ + PRInt32 FindChar(PRUnichar aChar, PRInt32 anOffset=0, PRInt32 aCount=-1) const; /** * Search for given substring within this string * * @param aString is substring to be sought in this * @param aIgnoreCase selects case sensitivity - * @param anOffset tells us where in this strig to start searching - * @param aCount tells us how many iterations to make starting at the given offset + * @param anOffset tells us where in this string to start searching + * @param aCount tells us how far from the offset we are to search. Use + -1 to search the whole string. * @return offset in string, or -1 (kNotFound) */ PRInt32 Find(const nsCString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; @@ -350,9 +362,6 @@ public: */ PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const; PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsString& aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsCString& aString,PRInt32 anOffset=0) const; - /** * This methods scans the string backwards, looking for the given string @@ -377,7 +386,6 @@ public: * @param aCount tells us how many iterations to make starting at the given offset * @return find pos in string, or -1 (kNotFound) */ - //PRInt32 RFind(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const; PRInt32 RFindChar(PRUnichar aChar,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; /**