diff --git a/xpcom/ds/bufferRoutines.h b/xpcom/ds/bufferRoutines.h deleted file mode 100644 index 31cc767171f1..000000000000 --- a/xpcom/ds/bufferRoutines.h +++ /dev/null @@ -1,967 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Pierre Phaneuf - */ - -/****************************************************************************************** - MODULE NOTES: - - This file contains the workhorse copy and shift functions used in nsStrStruct. - Ultimately, I plan to make the function pointers in this system available for - use by external modules. They'll be able to install their own "handlers". - Not so, today though. - -*******************************************************************************************/ - -#ifndef _BUFFERROUTINES_H -#define _BUFFERROUTINES_H - -#include "nsCRT.h" - -#ifndef XPCOM_STANDALONE -#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS) -#include "nsUnicharUtilCIID.h" -#include "nsIServiceManager.h" -#include "nsICaseConversion.h" -#endif -#endif /* XPCOM_STANDALONE */ - -#define KSHIFTLEFT (0) -#define KSHIFTRIGHT (1) - -// uncomment the following line to caught nsString char* casting problem -//#define DEBUG_ILLEGAL_CAST_UP -//#define DEBUG_ILLEGAL_CAST_DOWN - -#if defined(DEBUG_ILLEGAL_CAST_UP) || defined(DEBUG_ILLEGAL_CAST_DOWN) - -static PRBool track_illegal = PR_TRUE; -static PRBool track_latin1 = PR_TRUE; - -#ifdef XP_UNIX -#include "nsTraceRefcnt.h" -class CTraceFile { -public: - CTraceFile() { - mFile = fopen("nsStringTrace.txt" , "a+"); - } - ~CTraceFile() { - fflush(mFile); - fclose(mFile); - } - void ReportCastUp(const char* data, const char* msg) - { - if(mFile) { - fprintf(mFile, "ERRORTEXT= %s\n", msg); - fprintf(mFile, "BEGINDATA\n"); - const char* s=data; - while(*s) { - if(*s & 0x80) { - fprintf(mFile, "[%2X]", (char)*s); - } else { - fprintf(mFile, "%c", *s); - } - s++; - } - fprintf(mFile, "\n"); - fprintf(mFile, "ENDDATA\n"); - fprintf(mFile, "BEGINSTACK\n"); - nsTraceRefcnt::WalkTheStack(mFile); - fprintf(mFile, "\n"); - fprintf(mFile, "ENDSTACK\n"); - fflush(mFile); - } - } - void ReportCastDown(const PRUnichar* data, const char* msg) - { - if(mFile) { - fprintf(mFile, "ERRORTEXT=%s\n", msg); - fprintf(mFile, "BEGINDATA\n"); - const PRUnichar* s=data; - while(*s) { - if(*s & 0xFF80) { - fprintf(mFile, "\\u%X", *s); - } else { - fprintf(mFile, "%c", *s); - } - s++; - } - fprintf(mFile, "\n"); - fprintf(mFile, "ENDDATA\n"); - fprintf(mFile, "BEGINSTACK\n"); - nsTraceRefcnt::WalkTheStack(mFile); - fprintf(mFile, "\n"); - fprintf(mFile, "ENDSTACK\n"); - fflush(mFile); - } - } -private: - FILE* mFile; -}; -static CTraceFile gTrace; -#define TRACE_ILLEGAL_CAST_UP(c, s, m) if(!(c)) gTrace.ReportCastUp(s,m); -#define TRACE_ILLEGAL_CAST_DOWN(c, s, m) if(!(c)) gTrace.ReportCastDown(s,m); - -#else // XP_UNIX - -#define TRACE_ILLEGAL_CAST_UP(c, s, m) NS_ASSERTION((c), (m)) -#define TRACE_ILLEGAL_CAST_DOWN(c, s, m) NS_ASSERTION((c), (m)) - -#endif //XP_UNIX - -#endif - -inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) { - return ((PRUnichar*)aString)[anIndex]; -} - -inline PRUnichar GetCharAt(const char* aString,PRUint32 anIndex) { - return (PRUnichar)aString[anIndex]; -} - -//---------------------------------------------------------------------------------------- -// -// This set of methods is used to shift the contents of a char buffer. -// The functions are differentiated by shift direction and the underlying charsize. -// - -/** - * This method shifts single byte characters left by a given amount from an given offset. - * @update gess 01/04/99 - * @param aDest is a ptr to a cstring where left-shift is to be performed - * @param aLength is the known length of aDest - * @param anOffset is the index into aDest where shifting shall begin - * @param aCount is the number of chars to be "cut" - */ -void ShiftCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) { - char* dst = aDest+anOffset; - char* src = aDest+anOffset+aCount; - - memmove(dst,src,aLength-(aCount+anOffset)); -} - -/** - * This method shifts single byte characters right by a given amount from an given offset. - * @update gess 01/04/99 - * @param aDest is a ptr to a cstring where the shift is to be performed - * @param aLength is the known length of aDest - * @param anOffset is the index into aDest where shifting shall begin - * @param aCount is the number of chars to be "inserted" - */ -void ShiftCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) { - char* src = aDest+anOffset; - char* dst = aDest+anOffset+aCount; - - memmove(dst,src,aLength-anOffset); -} - -/** - * This method shifts unicode characters by a given amount from an given offset. - * @update gess 01/04/99 - * @param aDest is a ptr to a cstring where the shift is to be performed - * @param aLength is the known length of aDest - * @param anOffset is the index into aDest where shifting shall begin - * @param aCount is the number of chars to be "cut" - */ -void ShiftDoubleCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) { - PRUnichar* root=(PRUnichar*)aDest; - PRUnichar* dst = root+anOffset; - PRUnichar* src = root+anOffset+aCount; - - memmove(dst,src,(aLength-(aCount+anOffset))*sizeof(PRUnichar)); -} - - -/** - * This method shifts unicode characters by a given amount from an given offset. - * @update gess 01/04/99 - * @param aDest is a ptr to a cstring where the shift is to be performed - * @param aLength is the known length of aDest - * @param anOffset is the index into aDest where shifting shall begin - * @param aCount is the number of chars to be "inserted" - */ -void ShiftDoubleCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) { - PRUnichar* root=(PRUnichar*)aDest; - PRUnichar* src = root+anOffset; - PRUnichar* dst = root+anOffset+aCount; - - memmove(dst,src,sizeof(PRUnichar)*(aLength-anOffset)); -} - - -typedef void (*ShiftChars)(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount); -ShiftChars gShiftChars[2][2]= { - {&ShiftCharsLeft,&ShiftCharsRight}, - {&ShiftDoubleCharsLeft,&ShiftDoubleCharsRight} -}; - - -//---------------------------------------------------------------------------------------- -// -// This set of methods is used to copy one buffer onto another. -// The functions are differentiated by the size of source and dest character sizes. -// WARNING: Your destination buffer MUST be big enough to hold all the source bytes. -// We don't validate these ranges here (this should be done in higher level routines). -// - - -/** - * Going 1 to 1 is easy, since we assume ascii. No conversions are necessary. - * @update gess 01/04/99 - * @param aDest is the destination buffer - * @param aDestOffset is the pos to start copy to in the dest buffer - * @param aSource is the source buffer - * @param anOffset is the offset to start copying from in the source buffer - * @param aCount is the (max) number of chars to copy - */ -void CopyChars1To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) { - - char* dst = aDest+anDestOffset; - char* src = (char*)aSource+anOffset; - - memcpy(dst,src,aCount); -} - -/** - * Going 1 to 2 requires a conversion from ascii to unicode. This can be expensive. - * @param aDest is the destination buffer - * @param aDestOffset is the pos to start copy to in the dest buffer - * @param aSource is the source buffer - * @param anOffset is the offset to start copying from in the source buffer - * @param aCount is the (max) number of chars to copy - */ -void CopyChars1To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) { - - PRUnichar* theDest=(PRUnichar*)aDest; - PRUnichar* to = theDest+anDestOffset; - const unsigned char* first= (const unsigned char*)aSource+anOffset; - const unsigned char* last = first+aCount; - -#ifdef DEBUG_ILLEGAL_CAST_UP - PRBool illegal= PR_FALSE; -#endif - //now loop over characters, shifting them left... - while(first - */ -PRInt32 Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){ - PRInt32 result=0; - if(aIgnoreCase) - result=nsCRT::strncasecmp(aStr1,aStr2,aCount); - else result=memcmp(aStr1,aStr2,aCount); - return result; -} - -/** - * This method compares the data in one buffer with another - * @update gess 01/04/99 - * @param aStr1 is the first buffer to be compared - * @param aStr2 is the 2nd buffer to be compared - * @param aCount is the number of chars to compare - * @param aIgnorecase tells us whether to use a case-sensitive comparison - * @return -1,0,1 depending on <,==,> - */ -PRInt32 Compare2To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){ - PRInt32 result=0; - if(aIgnoreCase) - result=nsCRT::strncasecmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount); - else result=nsCRT::strncmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount); - return result; -} - - -/** - * This method compares the data in one buffer with another - * @update gess 01/04/99 - * @param aStr1 is the first buffer to be compared - * @param aStr2 is the 2nd buffer to be compared - * @param aCount is the number of chars to compare - * @param aIgnorecase tells us whether to use a case-sensitive comparison - * @return -1,0,1 depending on <,==,> - */ -PRInt32 Compare2To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){ - PRInt32 result; - if(aIgnoreCase) - result=nsCRT::strncasecmp((PRUnichar*)aStr1,aStr2,aCount); - else result=nsCRT::strncmp((PRUnichar*)aStr1,aStr2,aCount); - return result; -} - - -/** - * This method compares the data in one buffer with another - * @update gess 01/04/99 - * @param aStr1 is the first buffer to be compared - * @param aStr2 is the 2nd buffer to be compared - * @param aCount is the number of chars to compare - * @param aIgnorecase tells us whether to use a case-sensitive comparison - * @return -1,0,1 depending on <,==,> - */ -PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){ - PRInt32 result; - if(aIgnoreCase) - result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1; - else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1; - return result; -} - - -typedef PRInt32 (*CompareChars)(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase); -CompareChars gCompare[2][2]={ - {&Compare1To1,&Compare1To2}, - {&Compare2To1,&Compare2To2}, -}; - -//---------------------------------------------------------------------------------------- -// -// This set of methods is used to convert the case of strings... -// - - -/** - * This method performs a case conversion the data in the given buffer - * - * @update gess 01/04/99 - * @param aString is the buffer to be case shifted - * @param aCount is the number of chars to compare - * @param aToUpper tells us whether to convert to upper or lower - * @return 0 - */ -PRInt32 ConvertCase1(char* aString,PRUint32 aCount,PRBool aToUpper){ - PRInt32 result=0; - - typedef char chartype; - chartype* cp = (chartype*)aString; - chartype* end = cp + aCount-1; - while (cp <= end) { - chartype ch = *cp; - if(aToUpper) { - if ((ch >= 'a') && (ch <= 'z')) { - *cp = 'A' + (ch - 'a'); - } - } - else { - if ((ch >= 'A') && (ch <= 'Z')) { - *cp = 'a' + (ch - 'A'); - } - } - cp++; - } - return result; -} - -//---------------------------------------------------------------------------------------- - -#ifndef XPCOM_STANDALONE -#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS) -class HandleCaseConversionShutdown3 : public nsIShutdownListener { -public : - NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service); - HandleCaseConversionShutdown3(void) { NS_INIT_REFCNT(); } - virtual ~HandleCaseConversionShutdown3(void) {} - NS_DECL_ISUPPORTS -}; - -static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID); -static nsICaseConversion * gCaseConv = 0; - -NS_IMPL_ISUPPORTS1(HandleCaseConversionShutdown3, nsIShutdownListener); - -nsresult HandleCaseConversionShutdown3::OnShutdown(const nsCID& cid, nsISupports* service) { - if (cid.Equals(kUnicharUtilCID)) { - NS_ASSERTION(service == gCaseConv, "wrong service!"); - if(gCaseConv){ - gCaseConv->Release(); - gCaseConv = 0; - } - } - return NS_OK; -} - - -class CCaseConversionServiceInitializer { -public: - CCaseConversionServiceInitializer(){ - HandleCaseConversionShutdown3* listener = - new HandleCaseConversionShutdown3(); - if(listener){ - nsServiceManager::GetService(kUnicharUtilCID, NS_GET_IID(nsICaseConversion),(nsISupports**) &gCaseConv, listener); - } - } -}; - -#endif -#endif /* XPCOM_STANDALONE */ - -//---------------------------------------------------------------------------------------- - -/** - * This method performs a case conversion the data in the given buffer - * - * @update gess 01/04/99 - * @param aString is the buffer to be case shifted - * @param aCount is the number of chars to compare - * @param aToUpper tells us whether to convert to upper or lower - * @return 0 - */ -PRInt32 ConvertCase2(char* aString,PRUint32 aCount,PRBool aToUpper){ - PRUnichar* cp = (PRUnichar*)aString; - PRUnichar* end = cp + aCount-1; - PRInt32 result=0; - -#ifndef XPCOM_STANDALONE -#if !defined(RICKG_TESTBED) && !defined(STANDALONE_STRING_TESTS) - static CCaseConversionServiceInitializer gCaseConversionServiceInitializer; - - // I18N code begin - if(gCaseConv) { - nsresult err=(aToUpper) ? gCaseConv->ToUpper(cp, cp, aCount) : gCaseConv->ToLower(cp, cp, aCount); - if(NS_SUCCEEDED(err)) - return 0; - } - // I18N code end -#endif -#endif /* XPCOM_STANDALONE */ - - - while (cp <= end) { - PRUnichar ch = *cp; - if(aToUpper) { - if ((ch >= 'a') && (ch <= 'z')) { - *cp = 'A' + (ch - 'a'); - } - } - else { - if ((ch >= 'A') && (ch <= 'Z')) { - *cp = 'a' + (ch - 'A'); - } - } - cp++; - } - - return result; -} - -typedef PRInt32 (*CaseConverters)(char*,PRUint32,PRBool); -CaseConverters gCaseConverters[]={&ConvertCase1,&ConvertCase2}; - - - -//---------------------------------------------------------------------------------------- -// -// This set of methods is used compress char sequences in a buffer... -// - - -/** - * This method compresses duplicate runs of a given char from the given buffer - * - * @update rickg 03.23.2000 - * @param aString is the buffer to be manipulated - * @param aLength is the length of the buffer - * @param aSet tells us which chars to compress from given buffer - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - * @return the new length of the given buffer - */ -PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet){ - - char* from = aString; - char* end = aString + aLength; - char* to = from; - - //this code converts /n, /t, /r into normal space ' '; - //it also compresses runs of whitespace down to a single char... - if(aSet && aString && (0 < aLength)){ - PRUint32 aSetLen=strlen(aSet); - - while (from < end) { - char theChar = *from++; - - *to++=theChar; //always copy this char... - - if((kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen))){ - while (from < end) { - theChar = *from++; - if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){ - *to++ = theChar; - break; - } - } //while - } //if - } //if - *to = 0; - } - return to - aString; -} - - - -/** - * This method compresses duplicate runs of a given char from the given buffer - * - * @update rickg 03.23.2000 - * @param aString is the buffer to be manipulated - * @param aLength is the length of the buffer - * @param aSet tells us which chars to compress from given buffer - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - * @return the new length of the given buffer - */ -PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet){ - - PRUnichar* from = (PRUnichar*)aString; - PRUnichar* end = from + aLength; - PRUnichar* to = from; - - //this code converts /n, /t, /r into normal space ' '; - //it also compresses runs of whitespace down to a single char... - if(aSet && aString && (0 < aLength)){ - PRUint32 aSetLen=strlen(aSet); - - while (from < end) { - PRUnichar theChar = *from++; - - *to++=theChar; //always copy this char... - - if((theChar<256) && (kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen))){ - while (from < end) { - theChar = *from++; - if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){ - *to++ = theChar; - break; - } - } //while - } //if - } //if - *to = 0; - } - return to - (PRUnichar*)aString; -} - -typedef PRInt32 (*CompressChars)(char* aString,PRUint32 aCount,const char* aSet); -CompressChars gCompressChars[]={&CompressChars1,&CompressChars2}; - -/** - * This method strips chars in a given set from the given buffer - * - * @update gess 01/04/99 - * @param aString is the buffer to be manipulated - * @param aLength is the length of the buffer - * @param aSet tells us which chars to compress from given buffer - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - * @return the new length of the given buffer - */ -PRInt32 StripChars1(char* aString,PRUint32 aLength,const char* aSet){ - - char* to = aString; - char* from = aString-1; - char* end = aString + aLength; - - if(aSet && aString && (0 < aLength)){ - PRUint32 aSetLen=strlen(aSet); - while (++from < end) { - char theChar = *from; - if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE,aSetLen)){ - *to++ = theChar; - } - } - *to = 0; - } - return to - (char*)aString; -} - - -/** - * This method strips chars in a given set from the given buffer - * - * @update gess 01/04/99 - * @param aString is the buffer to be manipulated - * @param aLength is the length of the buffer - * @param aSet tells us which chars to compress from given buffer - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - * @return the new length of the given buffer - */ -PRInt32 StripChars2(char* aString,PRUint32 aLength,const char* aSet){ - - PRUnichar* to = (PRUnichar*)aString; - PRUnichar* from = (PRUnichar*)aString-1; - PRUnichar* end = to + aLength; - - if(aSet && aString && (0 < aLength)){ - PRUint32 aSetLen=strlen(aSet); - while (++from < end) { - PRUnichar theChar = *from; - //Note the test for ascii range below. If you have a real unicode char, - //and you're searching for chars in the (given) ascii string, there's no - //point in doing the real search since it's out of the ascii range. - if((255 (original author) - */ - -#ifndef nsAReadableString_h___ -#define nsAReadableString_h___ - -#ifndef nscore_h___ -#include "nscore.h" - // for |PRUnichar| -#endif - -#ifndef nsCharTraits_h___ -#include "nsCharTraits.h" -#endif - -#ifndef nsAlgorithm_h___ -#include "nsAlgorithm.h" - // for |NS_MIN|, |NS_MAX|, and |NS_COUNT|... -#endif - -#ifndef nsPrivateSharableString_h___ -#include "nsPrivateSharableString.h" -#endif - -#include "nsMemory.h" - -/* - This file defines the abstract interfaces |nsAReadableString| and - |nsAReadableCString| (the 'A' is for 'abstract', as opposed to the 'I' in - [XP]COM interface names). - - These types are intended to be as source compatible as possible with the original - definitions of |const nsString&| and |const nsCString&|, respectively. In otherwords, - these interfaces provide only non-mutating access to the underlying strings. We - split the these interfaces out from the mutating parts (see - "nsAWritableString.h") because tests showed that we could exploit specialized - implementations in some areas; we need an abstract interface to bring the whole - family of strings together. - - |nsAReadableString| is a string of |PRUnichar|s. |nsAReadableCString| (note the - 'C') is a string of |char|s. -*/ - -enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt }; - -template -struct nsReadableFragment - { - const CharT* mStart; - const CharT* mEnd; - const void* mFragmentIdentifier; - - nsReadableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; - -template class basic_nsAReadableString; - -template class basic_nsAWritableString; - // ...because we sometimes use them as `out' params - -#ifdef _MSC_VER - // Under VC++, at the highest warning level, we are overwhelmed with warnings - // about a possible error when |operator->()| is used against something that - // doesn't have members, e.g., a |PRUnichar|. This is to be expected with - // templates, so we disable the warning. - #pragma warning( disable: 4284 ) -#endif - -template -class nsReadingIterator -// : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef const CharT* pointer; - typedef const CharT& reference; -// typedef bidirectional_iterator_tag iterator_category; - - private: - friend class basic_nsAReadableString; - - nsReadableFragment mFragment; - const CharT* mPosition; - const basic_nsAReadableString* mOwningString; - - nsReadingIterator( const nsReadableFragment& aFragment, - const CharT* aStartingPosition, - const basic_nsAReadableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - nsReadingIterator() { } - // nsReadingIterator( const nsReadingIterator& ); // auto-generated copy-constructor OK - // nsReadingIterator& operator=( const nsReadingIterator& ); // auto-generated copy-assignment operator OK - - inline void normalize_forward(); - inline void normalize_backward(); - - pointer - get() const - { - return mPosition; - } - - CharT - operator*() const - { - return *get(); - } - -#if 0 - // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2) - // don't like this when |CharT| is a type without members. - pointer - operator->() const - { - return get(); - } -#endif - - nsReadingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - nsReadingIterator - operator++( int ) - { - nsReadingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - nsReadingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - nsReadingIterator - operator--( int ) - { - nsReadingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const nsReadableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - nsReadingIterator& - advance( difference_type n ) - { - while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - while ( n < 0 ) - { - normalize_backward(); - difference_type one_hop = NS_MAX(n, -size_backward()); - - NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - n -= one_hop; - } - - return *this; - } - - /** - * Really don't want to call these two operations |+=| and |-=|. - * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. - * - * We'll get rid of these as soon as we can. - */ - nsReadingIterator& - operator+=( difference_type n ) // deprecated - { - return advance(n); - } - - nsReadingIterator& - operator-=( difference_type n ) // deprecated - { - return advance(-n); - } - }; - -#if 0 -template -nsReadingIterator& -nsReadingIterator::advance( difference_type n ) - { - while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a reading iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - while ( n < 0 ) - { - normalize_backward(); - difference_type one_hop = NS_MAX(n, -size_backward()); - - NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a reading iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - n -= one_hop; - } - - return *this; - } -#endif - - // NOTE: need to break iterators out into their own file (as with many classes here), need - // these routines, but can't currently |#include "nsReadableUtils.h"|, this hack is bad - // but we need it to get OS2 building again. Fix by splitting things into different files. -NS_COM size_t Distance( const nsReadingIterator&, const nsReadingIterator& ); -NS_COM size_t Distance( const nsReadingIterator&, const nsReadingIterator& ); - -template -inline -PRBool -SameFragment( const Iterator& lhs, const Iterator& rhs ) - { - return lhs.fragment().mStart == rhs.fragment().mStart; - } - - - // - // nsAReadable[C]String - // - -template -class basic_nsAReadableString - : public nsPrivateSharableString - { - public: - typedef CharT char_type; - typedef PRUint32 size_type; - typedef PRUint32 index_type; - - typedef nsReadingIterator const_iterator; - - - // basic_nsAReadableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAReadableString( const basic_nsAReadableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - private: - // NOT TO BE IMPLEMENTED - void operator=( const basic_nsAReadableString& ); // but assignment is _not_ OK (we're immutable) so make it impossible - - public: - virtual ~basic_nsAReadableString() { } - // ...yes, I expect to be sub-classed. - - nsReadingIterator& BeginReading( nsReadingIterator& ) const; - nsReadingIterator& EndReading( nsReadingIterator& ) const; - - virtual PRUint32 Length() const = 0; - PRBool IsEmpty() const; - - /** - * |CharAt|, |operator[]|, |First()|, and |Last()| are not guaranteed to be constant-time operations. - * These signatures should be pushed down into interfaces that guarantee flat allocation. - * Clients at _this_ level should always use iterators. - */ - CharT CharAt( PRUint32 ) const; - CharT operator[]( PRUint32 ) const; - CharT First() const; - CharT Last() const; - - PRUint32 CountChar( CharT ) const; - - - /* - |Left|, |Mid|, and |Right| are annoying signatures that seem better almost - any _other_ way than they are now. Consider these alternatives - - aWritable = aReadable.Left(17); // ...a member function that returns a |Substring| - aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring| - Left(aReadable, 17, aWritable); // ...a global function that does the assignment - - as opposed to the current signature - - aReadable.Left(aWritable, 17); // ...a member function that does the assignment - - or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality - - aWritable = Substring(aReadable, 0, 17); - */ - - PRUint32 Left( basic_nsAWritableString&, PRUint32 ) const; - PRUint32 Mid( basic_nsAWritableString&, PRUint32, PRUint32 ) const; - PRUint32 Right( basic_nsAWritableString&, PRUint32 ) const; - - // Find( ... ) const; - PRInt32 FindChar( CharT, PRUint32 aOffset = 0 ) const; - // FindCharInSet( ... ) const; - // RFind( ... ) const; - // RFindChar( ... ) const; - // RFindCharInSet( ... ) const; - - - int Compare( const basic_nsAReadableString& rhs ) const; - int Compare( const CharT* ) const; -// int Compare( const CharT*, PRUint32 ) const; -// int Compare( CharT ) const; - - // |Equals()| is a synonym for |Compare()| - PRBool Equals( const basic_nsAReadableString& rhs ) const; - PRBool Equals( const CharT* ) const; -// PRBool Equals( const CharT*, PRUint32 ) const; -// PRBool Equals( CharT ) const; - - // Comparison operators are all synonyms for |Compare()| - PRBool operator!=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)!=0; } - PRBool operator< ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)< 0; } - PRBool operator<=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)<=0; } - PRBool operator==( const basic_nsAReadableString& rhs ) const { return Compare(rhs)==0; } - PRBool operator>=( const basic_nsAReadableString& rhs ) const { return Compare(rhs)>=0; } - PRBool operator> ( const basic_nsAReadableString& rhs ) const { return Compare(rhs)> 0; } - - - /* - Shouldn't be implemented because they're i18n sensitive. - Let's leave them in |nsString| for now. - */ - - // ToLowerCase - // ToUpperCase - // EqualsIgnoreCase - // IsASCII - // IsSpace - // IsAlpha - // IsDigit - // ToFloat - // ToInteger - - // char* ToNewCString() const; - // char* ToNewUTF8String() const; - // PRUnichar* ToNewUnicode() const; - // char* ToCString( char*, PRUint32, PRUint32 ) const; - - - /* - Shouldn't be implemented because it's wrong duplication. - Let's leave it in |nsString| for now. - */ - - // nsString* ToNewString() const; - // NO! The right way to say this is |new nsString( fromAReadableString )| - - - /* - Shouldn't be implemented because they're not generally applicable. - Let's leave them in |nsString| for now. - */ - - // IsOrdered - // BinarySearch - - // protected: - virtual const void* Implementation() const; - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const = 0; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return &aString == this; } -// virtual PRBool PromisesExactly( const basic_nsAReadableString& aString ) const { return false; } - - private: - // NOT TO BE IMPLEMENTED - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - PRUint32 CountChar( incompatible_char_type ) const; -// in Compare( incompatible_char_type ) const; -// PRBool Equals( incompatible_char_type ) const; - }; - - /* - The following macro defines a cast that helps us solve type-unification error problems on compilers - with poor template support. String clients probably _never_ need to use it. String implementors - sometimes will. - */ - -#ifdef NEED_CPP_TEMPLATE_CAST_TO_BASE -#define NS_READABLE_CAST(CharT, expr) (NS_STATIC_CAST(const basic_nsAReadableString&, (expr))) -#else -#define NS_READABLE_CAST(CharT, expr) (expr) -#endif - -template -inline -void -nsReadingIterator::normalize_forward() - { - while ( mPosition == mFragment.mEnd - && mOwningString->GetReadableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - -template -inline -void -nsReadingIterator::normalize_backward() - { - while ( mPosition == mFragment.mStart - && mOwningString->GetReadableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - - /** - * Note: measure -- should the |BeginReading| and |EndReading| be |inline|? - */ -template -inline -nsReadingIterator& -basic_nsAReadableString::BeginReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - -template -inline -nsReadingIterator& -basic_nsAReadableString::EndReading( nsReadingIterator& aResult ) const - { - aResult.mOwningString = this; - GetReadableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - -template -inline -PRBool -basic_nsAReadableString::IsEmpty() const - { - return Length() == 0; - } - -template -inline -PRBool -basic_nsAReadableString::Equals( const basic_nsAReadableString& rhs ) const - { - return Compare(rhs) == 0; - } - -template -inline -PRBool -operator==( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() == rhs.get(); - } - -template -inline -PRBool -operator!=( const nsReadingIterator& lhs, const nsReadingIterator& rhs ) - { - return lhs.get() != rhs.get(); - } - - -#define NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _CharT* rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), rhs) comp 0); \ - } - -#define NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _CharT* lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(lhs, NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - inline \ - PRBool \ - operator comp( const _StringT& lhs, const _StringT& rhs ) \ - { \ - return PRBool(Compare(NS_READABLE_CAST(_CharT, lhs), NS_READABLE_CAST(_CharT, rhs)) comp 0); \ - } - -#define NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - template NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - template NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_3_STRING_COMPARISON_OPERATORS(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_STRING_PTR_COMPARISON_OPERATOR(comp, _StringT, _CharT) \ - NS_DEF_1_PTR_STRING_COMPARISON_OPERATOR(comp, _StringT, _CharT) - -#define NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_2_TEMPLATE_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - -#define NS_DEF_STRING_COMPARISON_OPERATORS(_StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(!=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(< , _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(<=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(==, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(>=, _StringT, _CharT) \ - NS_DEF_3_STRING_COMPARISON_OPERATORS(> , _StringT, _CharT) - - -NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsAReadableString, CharT) - - - -template -const void* -basic_nsAReadableString::Implementation() const - { - return 0; - } - - - -template -CharT -basic_nsAReadableString::CharAt( PRUint32 aIndex ) const - { - NS_ASSERTION(aIndex iter; - return *(BeginReading(iter).advance(PRInt32(aIndex))); - } - -template -inline -CharT -basic_nsAReadableString::operator[]( PRUint32 aIndex ) const - { - return CharAt(aIndex); - } - -template -CharT -basic_nsAReadableString::First() const - { - NS_ASSERTION(Length()>0, "|First()| on an empty string"); - - nsReadingIterator iter; - return *BeginReading(iter); - } - -template -CharT -basic_nsAReadableString::Last() const - { - NS_ASSERTION(Length()>0, "|Last()| on an empty string"); - - nsReadingIterator iter; - EndReading(iter); - - if ( !IsEmpty() ) - iter.advance(-1); - - return *iter; // Note: this has undefined results if |IsEmpty()| - } - -template -PRUint32 -basic_nsAReadableString::CountChar( CharT c ) const - { -#if 0 - nsReadingIterator countBegin, countEnd; - return PRUint32(NS_COUNT(BeginReading(countBegin), EndReading(countEnd), c)); -#else - PRUint32 result = 0; - PRUint32 lengthToExamine = Length(); - - nsReadingIterator iter; - for ( BeginReading(iter); ; ) - { - PRInt32 lengthToExamineInThisFragment = iter.size_forward(); - const CharT* fromBegin = iter.get(); - result += PRUint32(NS_COUNT(fromBegin, fromBegin+lengthToExamineInThisFragment, c)); - if ( !(lengthToExamine -= lengthToExamineInThisFragment) ) - return result; - iter.advance(lengthToExamineInThisFragment); - } - // never reached; quiets warnings - return 0; -#endif - } - -#if 0 - // had to move these definitions into "nsAWritableString.h" -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } -#endif - -template -PRInt32 -basic_nsAReadableString::FindChar( CharT aChar, PRUint32 aOffset ) const - { - nsReadingIterator iter, done_searching; - BeginReading(iter).advance( PRInt32(aOffset) ); - EndReading(done_searching); - - PRUint32 lengthSearched = 0; - while ( iter != done_searching ) - { - PRInt32 fragmentLength = iter.size_forward(); - const CharT* charFoundAt = nsCharTraits::find(iter.get(), fragmentLength, aChar); - if ( charFoundAt ) - return lengthSearched + (charFoundAt-iter.get()) + aOffset; - - lengthSearched += fragmentLength; - iter.advance(fragmentLength); - } - - return -1; - } - -template -inline -int -basic_nsAReadableString::Compare( const basic_nsAReadableString& rhs ) const - { - return ::Compare(*this, rhs); - } - - - - - - - // - // nsLiteral[C]String - // - -template -class basic_nsLiteralString - : public basic_nsAReadableString - /* - ...this class wraps a constant literal string and lets it act like an |nsAReadable...|. - - Use it like this: - - SomeFunctionTakingACString( nsLiteralCString("Hello, World!") ); - - With some tweaking, I think I can make this work as well... - - SomeStringFunc( nsLiteralString( L"Hello, World!" ) ); - - This class just holds a pointer. If you don't supply the length, it must calculate it. - No copying or allocations are performed. - - |const basic_nsLiteralString&| appears frequently in interfaces because it - allows the automatic conversion of a |CharT*|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - public: - - explicit - basic_nsLiteralString( const CharT* aLiteral ) - : mStart(aLiteral), - mEnd(mStart ? (mStart + nsCharTraits::length(mStart)) : mStart) - { - // nothing else to do here - } - - basic_nsLiteralString( const CharT* aLiteral, PRUint32 aLength ) - : mStart(aLiteral), - mEnd(mStart + aLength) - { - // This is an annoying hack. Callers should be fixed to use the other - // constructor if they don't really know the length. - if ( aLength == PRUint32(-1) ) - { -// NS_WARNING("Tell scc: Caller constructing a string doesn't know the real length. Please use the other constructor."); - mEnd = mStart ? (mStart + nsCharTraits::length(mStart)) : mStart; - } - } - - // basic_nsLiteralString( const basic_nsLiteralString& ); // auto-generated copy-constructor OK - // ~basic_nsLiteralString(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const basic_nsLiteralString& ); // we're immutable - - public: - - virtual PRUint32 Length() const; - - - const CharT* get() const { return mStart; } - operator const CharT*() const { return get(); } // to be deprecated, prefer |get()| - - private: - const CharT* mStart; - const CharT* mEnd; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsLiteralString, CharT) - -template -const CharT* -basic_nsLiteralString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mStart = mStart; - aFragment.mEnd = mEnd; - return mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - -template -PRUint32 -basic_nsLiteralString::Length() const - { - return PRUint32(mEnd - mStart); - } - - -// XXX Note that these are located here because some compilers are -// sensitive to the ordering of declarations with regard to templates. -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs ) const - { - return Compare(basic_nsLiteralString(rhs)) == 0; - } - -#if 0 -template -inline -PRBool -basic_nsAReadableString::Equals( const CharT* rhs, PRUint32 rhs_length ) const - { - return Compare(basic_nsLiteralString(rhs, rhs_length)) == 0; - } -#endif - -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, basic_nsLiteralString(rhs))); - } - -#if 0 -template -inline -int -basic_nsAReadableString::Compare( const CharT* rhs, PRUint32 rhs_length ) const - { - return ::Compare(*this, NS_READABLE_CAST(CharT, basic_nsLiteralString(rhs, rhs_length))); - } -#endif - - - // - // nsLiteralChar, nsLiteralPRUnichar - // - -template -class basic_nsLiteralChar - : public basic_nsAReadableString - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - public: - - explicit - basic_nsLiteralChar( CharT aChar ) - : mChar(aChar) - { - // nothing else to do here - } - - // basic_nsLiteralChar( const basic_nsLiteralString& ); // auto-generated copy-constructor OK - // ~basic_nsLiteralChar(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const basic_nsLiteralChar& ); // we're immutable - - public: - - virtual - PRUint32 - Length() const - { - return 1; - } - - private: - CharT mChar; - }; - -template -const CharT* -basic_nsLiteralChar::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = &mChar) + 1; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - - - - - - - // - // nsPromiseConcatenation - // - -template class nsPromiseReadable : public basic_nsAReadableString { }; - -template -class nsPromiseConcatenation - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS - - Instances of this class only exist as anonymous temporary results from |operator+()|. - This is the machinery that makes string concatenation efficient. No allocations or - character copies are required unless and until a final assignment is made. It works - its magic by overriding and forwarding calls to |GetReadableFragment()|. - - Note: |nsPromiseConcatenation| imposes some limits on string concatenation with |operator+()|. - - no more than 33 strings, e.g., |s1 + s2 + s3 + ... s32 + s33| - - left to right evaluation is required ... do not use parentheses to override this - - In practice, neither of these is onerous. Parentheses do not change the semantics of the - concatenation, only the order in which the result is assembled ... so there's no reason - for a user to need to control it. Too many strings summed together can easily be worked - around with an intermediate assignment. I wouldn't have the parentheses limitation if I - assigned the identifier mask starting at the top, the first time anybody called - |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - enum { kLeftString, kRightString }; - - int - GetCurrentStringFromFragment( const nsReadableFragment& aFragment ) const - { - return (NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & mFragmentIdentifierMask) ? kRightString : kLeftString; - } - - int - SetLeftStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) & ~mFragmentIdentifierMask); - return kLeftString; - } - - int - SetRightStringInFragment( nsReadableFragment& aFragment ) const - { - aFragment.mFragmentIdentifier = NS_REINTERPRET_CAST(void*, NS_REINTERPRET_CAST(PRUint32, aFragment.mFragmentIdentifier) | mFragmentIdentifierMask); - return kRightString; - } - - public: - nsPromiseConcatenation( const basic_nsAReadableString& aLeftString, const basic_nsAReadableString& aRightString, PRUint32 aMask = 1 ) - : mFragmentIdentifierMask(aMask) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - nsPromiseConcatenation( const nsPromiseConcatenation& aLeftString, const basic_nsAReadableString& aRightString ) - : mFragmentIdentifierMask(aLeftString.mFragmentIdentifierMask<<1) - { - mStrings[kLeftString] = &aLeftString; - mStrings[kRightString] = &aRightString; - } - - // nsPromiseConcatenation( const nsPromiseConcatenation& ); // auto-generated copy-constructor should be OK - // ~nsPromiseConcatenation(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseConcatenation& ); // we're immutable, you can't assign into a concatenation - - public: - - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& ) const; -// virtual PRBool PromisesExactly( const basic_nsAReadableString& ) const; - -// nsPromiseConcatenation operator+( const basic_nsAReadableString& rhs ) const; - - PRUint32 GetFragmentIdentifierMask() const { return mFragmentIdentifierMask; } - - private: - void operator+( const nsPromiseConcatenation& ); // NOT TO BE IMPLEMENTED - // making this |private| stops you from over parenthesizing concatenation expressions, e.g., |(A+B) + (C+D)| - // which would break the algorithm for distributing bits in the fragment identifier - - private: - const basic_nsAReadableString* mStrings[2]; - PRUint32 mFragmentIdentifierMask; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseConcatenation, CharT) - -template -PRUint32 -nsPromiseConcatenation::Length() const - { - return mStrings[kLeftString]->Length() + mStrings[kRightString]->Length(); - } - -template -PRBool -nsPromiseConcatenation::Promises( const basic_nsAReadableString& aString ) const - { - return mStrings[0]->Promises(aString) || mStrings[1]->Promises(aString); - } - -#if 0 -PRBool -nsPromiseConcatenation::PromisesExactly( const basic_nsAReadableString& aString ) const - { - // Not really like this, test for the empty string, etc - return mStrings[0] == &aString && !mStrings[1] || !mStrings[0] && mStrings[1] == &aString; - } -#endif - -template -const CharT* -nsPromiseConcatenation::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - int whichString; - - // based on the request, pick which string we will forward the |GetReadableFragment()| call into - - switch ( aRequest ) - { - case kPrevFragment: - case kNextFragment: - whichString = GetCurrentStringFromFragment(aFragment); - break; - - case kFirstFragment: - whichString = SetLeftStringInFragment(aFragment); - break; - - case kLastFragment: - whichString = SetRightStringInFragment(aFragment); - break; - - case kFragmentAt: - PRUint32 leftLength = mStrings[kLeftString]->Length(); - if ( aPosition < leftLength ) - whichString = SetLeftStringInFragment(aFragment); - else - { - whichString = SetRightStringInFragment(aFragment); - aPosition -= leftLength; - } - break; - - } - - const CharT* result; - PRBool done; - do - { - done = PR_TRUE; - result = mStrings[whichString]->GetReadableFragment(aFragment, aRequest, aPosition); - - if ( !result ) - { - done = PR_FALSE; - if ( aRequest == kNextFragment && whichString == kLeftString ) - { - aRequest = kFirstFragment; - whichString = SetRightStringInFragment(aFragment); - } - else if ( aRequest == kPrevFragment && whichString == kRightString ) - { - aRequest = kLastFragment; - whichString = SetLeftStringInFragment(aFragment); - } - else - done = PR_TRUE; - } - } - while ( !done ); - return result; - } - -#if 0 -template -inline -nsPromiseConcatenation -nsPromiseConcatenation::operator+( const basic_nsAReadableString& rhs ) const - { - return nsPromiseConcatenation(*this, rhs, mFragmentIdentifierMask<<1); - } -#endif - - - - - - // - // nsPromiseSubstring - // - -template -class nsPromiseSubstring - : public nsPromiseReadable - /* - NOT FOR USE BY HUMANS (mostly) - - ...not unlike |nsPromiseConcatenation|. Instances of this class exist only as anonymous - temporary results from |Substring()|. Like |nsPromiseConcatenation|, this class only - holds a pointer, no string data of its own. It does its magic by overriding and forwarding - calls to |GetReadableFragment()|. - */ - { - protected: - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - public: - nsPromiseSubstring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsPromiseSubstring( const basic_nsAReadableString& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - : mString(aString) - { - nsReadingIterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } - - // nsPromiseSubstring( const nsPromiseSubstring& ); // auto-generated copy-constructor should be OK - // ~nsPromiseSubstring(); // auto-generated destructor OK - - private: - // NOT TO BE IMPLEMENTED - void operator=( const nsPromiseSubstring& ); // we're immutable, you can't assign into a substring - - public: - virtual PRUint32 Length() const; - virtual PRBool Promises( const basic_nsAReadableString& aString ) const { return mString.Promises(aString); } - - private: - const basic_nsAReadableString& mString; - PRUint32 mStartPos; - PRUint32 mLength; - }; - -// NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(nsPromiseSubstring, CharT) - -template -PRUint32 -nsPromiseSubstring::Length() const - { - return mLength; - } - -template -const CharT* -nsPromiseSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aPosition ) const - { - // Offset any request for a specific position (First, Last, At) by our - // substrings startpos within the owning string - - if ( aRequest == kFirstFragment ) - { - aPosition = mStartPos; - aRequest = kFragmentAt; - } - else if ( aRequest == kLastFragment ) - { - aPosition = mStartPos + mLength; - aRequest = kFragmentAt; - } - else if ( aRequest == kFragmentAt ) - aPosition += mStartPos; - - // requests for |kNextFragment| or |kPrevFragment| are just relayed down into the string we're slicing - - const CharT* position_ptr = mString.GetReadableFragment(aFragment, aRequest, aPosition); - - // If |GetReadableFragment| returns |0|, then we are off the string, the contents of the - // fragment are garbage. - - // Therefore, only need to fix up the fragment boundaries when |position_ptr| is not null - if ( position_ptr ) - { - // if there's more physical data in the returned fragment than I logically have left... - size_t logical_size_backward = aPosition - mStartPos; - if ( size_t(position_ptr - aFragment.mStart) > logical_size_backward ) - aFragment.mStart = position_ptr - logical_size_backward; - - size_t logical_size_forward = mLength - logical_size_backward; - if ( size_t(aFragment.mEnd - position_ptr) > logical_size_forward ) - aFragment.mEnd = position_ptr + logical_size_forward; - } - - return position_ptr; - } - - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - #define NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T) \ - template \ - inline \ - nsPromiseConcatenation \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation(lhs, rhs); \ - } - - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring, nsPromiseSubstring) - NS_DEF_TEMPLATE_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation, nsPromiseSubstring) - -#endif // NEED_CPP_DERIVED_TEMPLATE_OPERATORS - - - // - // Global functions - // - -template -inline -PRBool -SameImplementation( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - const void* imp_tag = lhs.Implementation(); - return imp_tag && (imp_tag==rhs.Implementation()); - } - -template -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, PRUint32 aStartPos, PRUint32 aSubstringLength ) - { - return nsPromiseSubstring(aString, aStartPos, aSubstringLength); - } - -template -nsPromiseSubstring -Substring( const basic_nsAReadableString& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return nsPromiseSubstring(aString, aStart, aEnd); - } - -template -int -Compare( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - if ( &lhs == &rhs ) - return 0; - - PRUint32 lLength = lhs.Length(); - PRUint32 rLength = rhs.Length(); - PRUint32 lengthToCompare = NS_MIN(lLength, rLength); - - nsReadingIterator leftIter, rightIter; - lhs.BeginReading(leftIter); - rhs.BeginReading(rightIter); - - int result; - - for (;;) - { - PRUint32 lengthAvailable = PRUint32( NS_MIN(leftIter.size_forward(), rightIter.size_forward()) ); - - if ( lengthAvailable > lengthToCompare ) - lengthAvailable = lengthToCompare; - - // Note: |result| should be declared in this |if| expression, but some compilers don't like that - if ( (result = nsCharTraits::compare(leftIter.get(), rightIter.get(), lengthAvailable)) != 0 ) - return result; - - if ( !(lengthToCompare -= lengthAvailable) ) - break; - - leftIter.advance( PRInt32(lengthAvailable) ); - rightIter.advance( PRInt32(lengthAvailable) ); - } - - if ( lLength < rLength ) - return -1; - else if ( rLength < lLength ) - return 1; - else - return 0; - } - -template -inline -int -Compare( const basic_nsAReadableString& lhs, const CharT* rhs ) - { - return Compare(lhs, NS_READABLE_CAST(CharT, basic_nsLiteralString(rhs))); - } - -template -inline -int -Compare( const CharT* lhs, const basic_nsAReadableString& rhs ) - { - return Compare(NS_READABLE_CAST(CharT, basic_nsLiteralString(lhs)), rhs); - } - - - - /* - How shall we provide |operator+()|? - - What would it return? It has to return a stack based object, because the client will - not be given an opportunity to handle memory management in an expression like - - myWritableString = stringA + stringB + stringC; - - ...so the `obvious' answer of returning a new |nsSharedString| is no good. We could - return an |nsString|, if that name were in scope here, though there's no telling what the client - will really want to do with the result. What might be better, though, - is to return a `promise' to concatenate some strings... - - By making |nsPromiseConcatenation| inherit from readable strings, we automatically handle - assignment and other interesting uses within writable strings, plus we drastically reduce - the number of cases we have to write |operator+()| for. The cost is extra temporary concat strings - in the evaluation of strings of '+'s, e.g., |A + B + C + D|, and that we have to do some work - to implement the virtual functions of readables. - */ - -template -inline -nsPromiseConcatenation -operator+( const nsPromiseConcatenation& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs, lhs.GetFragmentIdentifierMask()<<1); - } - -template -inline -nsPromiseConcatenation -operator+( const basic_nsAReadableString& lhs, const basic_nsAReadableString& rhs ) - { - return nsPromiseConcatenation(lhs, rhs); - } - - - -#ifdef NEED_CPP_DERIVED_TEMPLATE_OPERATORS - #define NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - inline \ - nsPromiseConcatenation<_CharT> \ - operator+( const _String1T& lhs, const _String2T& rhs ) \ - { \ - return nsPromiseConcatenation<_CharT>(lhs, rhs); \ - } - - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseSubstring<_CharT>, _StringT, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_StringT, nsPromiseSubstring<_CharT>, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(nsPromiseConcatenation<_CharT>, _StringT, _CharT) - - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) \ - NS_DEF_DERIVED_STRING_STRING_OPERATOR_PLUS(_String2T, _String1T, _CharT) - -#else - #define NS_DEF_DERIVED_STRING_OPERATOR_PLUS(_StringT, _CharT) - #define NS_DEF_2_STRING_STRING_OPERATOR_PLUS(_String1T, _String2T, _CharT) -#endif - - -#define kDefaultFlatStringSize 64 - -template -class basic_nsPromiseFlatString - : public basic_nsAReadableString - { - public: - explicit basic_nsPromiseFlatString( const basic_nsAReadableString& ); - - virtual - ~basic_nsPromiseFlatString( ) - { - if (mOwnsBuffer) - nsMemory::Free((void*)mBuffer); - } - - virtual PRUint32 Length() const { return mLength; } - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 = 0 ) const; - - const CharT* get() const { return mBuffer; } - operator const CharT*() const { return get(); } // to be deprecated, prefer |get()| - - protected: - PRUint32 mLength; - const CharT* mBuffer; - PRBool mOwnsBuffer; - CharT mInlineBuffer[kDefaultFlatStringSize]; - }; - -template -basic_nsPromiseFlatString::basic_nsPromiseFlatString( const basic_nsAReadableString& aString ) - : mLength(aString.Length()), - mOwnsBuffer(PR_FALSE) - { - typedef nsReadingIterator iterator; - - iterator start; - iterator end; - - aString.BeginReading(start); - aString.EndReading(end); - - // First count the number of buffers - PRInt32 buffer_count = 0; - while ( start != end ) - { - buffer_count++; - start += start.size_forward(); - } - - // Now figure out what we want to do with the string - aString.BeginReading(start); - // XXX Not guaranteed null-termination in the first case - // If it's a single buffer, we just use the implementation's buffer - if ( buffer_count == 1 ) - mBuffer = start.get(); - // If it's too big for our inline buffer, we allocate a new one - else if ( mLength > kDefaultFlatStringSize-1 ) - { - CharT* result = NS_STATIC_CAST(CharT*, nsMemory::Alloc((mLength+1) * sizeof(CharT))); - CharT* toBegin = result; - *copy_string(start, end, toBegin) = CharT(0); - - mBuffer = result; - mOwnsBuffer = PR_TRUE; - } - // Otherwise copy into our internal buffer - else - { - mBuffer = mInlineBuffer; - CharT* toBegin = &mInlineBuffer[0]; - copy_string( start, end, toBegin); - mInlineBuffer[mLength] = 0; - } - } - - -template -const CharT* -basic_nsPromiseFlatString::GetReadableFragment( nsReadableFragment& aFragment, - nsFragmentRequest aRequest, - PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mBuffer) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - - -typedef basic_nsAReadableString nsAReadableString; -typedef basic_nsAReadableString nsAReadableCString; - -typedef basic_nsLiteralString nsLiteralString; -typedef basic_nsLiteralString nsLiteralCString; - -typedef basic_nsPromiseFlatString nsPromiseFlatString; -typedef basic_nsPromiseFlatString nsPromiseFlatCString; - - -#ifdef HAVE_CPP_2BYTE_WCHAR_T - #define NS_L(s) L##s - #define NS_MULTILINE_LITERAL_STRING(s) nsLiteralString(s, (sizeof(s)/sizeof(wchar_t))-1) - #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) nsLiteralString n(s, (sizeof(s)/sizeof(wchar_t))-1) -#else - #define NS_L(s) s - #define NS_MULTILINE_LITERAL_STRING(s) NS_ConvertASCIItoUCS2(s, sizeof(s)-1) - #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) NS_ConvertASCIItoUCS2 n(s, sizeof(s)-1) -#endif - -#define NS_LITERAL_STRING(s) NS_MULTILINE_LITERAL_STRING(NS_L(s)) -#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n,NS_L(s)) - -#define NS_LITERAL_CSTRING(s) nsLiteralCString(s, sizeof(s)-1) -#define NS_NAMED_LITERAL_CSTRING(n,s) nsLiteralCString n(s, sizeof(s)-1) - -typedef basic_nsLiteralChar nsLiteralChar; -typedef basic_nsLiteralChar nsLiteralPRUnichar; - - -#endif // !defined(nsAReadableString_h___) diff --git a/xpcom/ds/nsAWritableString.h b/xpcom/ds/nsAWritableString.h deleted file mode 100644 index 25fe641dec26..000000000000 --- a/xpcom/ds/nsAWritableString.h +++ /dev/null @@ -1,866 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - */ - -#ifndef nsAWritableString_h___ -#define nsAWritableString_h___ - - // See also... -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" -#endif - - -template -struct nsWritableFragment - { - CharT* mStart; - CharT* mEnd; - void* mFragmentIdentifier; - - nsWritableFragment() - : mStart(0), mEnd(0), mFragmentIdentifier(0) - { - // nothing else to do here - } - }; - -template class basic_nsAWritableString; - -template -class nsWritingIterator -// : public bidirectional_iterator_tag - { - public: - typedef ptrdiff_t difference_type; - typedef CharT value_type; - typedef CharT* pointer; - typedef CharT& reference; -// typedef bidirectional_iterator_tag iterator_category; - - private: - friend class basic_nsAWritableString; - - nsWritableFragment mFragment; - CharT* mPosition; - basic_nsAWritableString* mOwningString; - - nsWritingIterator( nsWritableFragment& aFragment, - CharT* aStartingPosition, - basic_nsAWritableString& aOwningString ) - : mFragment(aFragment), - mPosition(aStartingPosition), - mOwningString(&aOwningString) - { - // nothing else to do here - } - - public: - nsWritingIterator() { } - // nsWritingIterator( const nsWritingIterator& ); // auto-generated copy-constructor OK - // nsWritingIterator& operator=( const nsWritingIterator& ); // auto-generated copy-assignment operator OK - - inline void normalize_forward(); - inline void normalize_backward(); - - pointer - get() const - { - return mPosition; - } - - reference - operator*() const - { - return *get(); - } - -#if 0 - // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2) - // don't like this when |CharT| is a type without members. - pointer - operator->() const - { - return get(); - } -#endif - - nsWritingIterator& - operator++() - { - ++mPosition; - normalize_forward(); - return *this; - } - - nsWritingIterator - operator++( int ) - { - nsWritingIterator result(*this); - ++mPosition; - normalize_forward(); - return result; - } - - nsWritingIterator& - operator--() - { - normalize_backward(); - --mPosition; - return *this; - } - - nsWritingIterator - operator--( int ) - { - nsWritingIterator result(*this); - normalize_backward(); - --mPosition; - return result; - } - - const nsWritableFragment& - fragment() const - { - return mFragment; - } - - difference_type - size_forward() const - { - return mFragment.mEnd - mPosition; - } - - difference_type - size_backward() const - { - return mPosition - mFragment.mStart; - } - - nsWritingIterator& - advance( difference_type n ) - { - while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - while ( n < 0 ) - { - normalize_backward(); - difference_type one_hop = NS_MAX(n, -size_backward()); - - NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - n -= one_hop; - } - - return *this; - } - - /** - * Really don't want to call these two operations |+=| and |-=|. - * Would prefer a single function, e.g., |advance|, which doesn't imply a constant time operation. - * - * We'll get rid of these as soon as we can. - */ - nsWritingIterator& - operator+=( difference_type n ) // deprecated - { - return advance(n); - } - - nsWritingIterator& - operator-=( difference_type n ) // deprecated - { - return advance(-n); - } - - PRUint32 - write( const value_type* s, PRUint32 n ) - { - NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!"); - - n = NS_MIN(n, PRUint32(size_forward())); - nsCharTraits::move(mPosition, s, n); - advance( difference_type(n) ); - return n; - } - }; - -#if 0 -template -nsWritingIterator& -nsWritingIterator::advance( difference_type n ) - { - while ( n > 0 ) - { - difference_type one_hop = NS_MIN(n, size_forward()); - - NS_ASSERTION(one_hop>0, "Infinite loop: can't advance a writing iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - normalize_forward(); - n -= one_hop; - } - - while ( n < 0 ) - { - normalize_backward(); - difference_type one_hop = NS_MAX(n, -size_backward()); - - NS_ASSERTION(one_hop<0, "Infinite loop: can't advance (backward) a writing iterator beyond the end of a string"); - // perhaps I should |break| if |!one_hop|? - - mPosition += one_hop; - n -= one_hop; - } - - return *this; - } -#endif - -/* - This file defines the abstract interfaces |nsAWritableString| and - |nsAWritableCString|. - - |nsAWritableString| is a string of |PRUnichar|s. |nsAWritableCString| (note the - 'C') is a string of |char|s. -*/ - -template -class basic_nsAWritableString - : public basic_nsAReadableString - /* - ... - */ - { - // friend class nsWritingIterator; - - public: - typedef CharT char_type; - typedef PRUint32 size_type; - typedef PRUint32 index_type; - - typedef nsWritingIterator iterator; - - // basic_nsAWritableString(); // auto-generated default constructor OK (we're abstract anyway) - // basic_nsAWritableString( const basic_nsAWritableString& ); // auto-generated copy-constructor OK (again, only because we're abstract) - // ~basic_nsAWritableString(); // auto-generated destructor OK - // see below for copy-assignment operator - - virtual CharT* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 = 0 ) = 0; - - /** - * Note: measure -- should the |BeginWriting| and |EndWriting| be |inline|? - */ - nsWritingIterator& - BeginWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kFirstFragment); - aResult.mPosition = aResult.mFragment.mStart; - aResult.normalize_forward(); - return aResult; - } - - - nsWritingIterator& - EndWriting( nsWritingIterator& aResult ) - { - aResult.mOwningString = this; - GetWritableFragment(aResult.mFragment, kLastFragment); - aResult.mPosition = aResult.mFragment.mEnd; - // must not |normalize_backward| as that would likely invalidate tests like |while ( first != last )| - return aResult; - } - - - /** - * |SetCapacity| is not required to do anything; however, it can be used - * as a hint to the implementation to reduce allocations. - * |SetCapacity(0)| is a suggestion to discard all associated storage. - */ - virtual void SetCapacity( PRUint32 ) { } - - /** - * |SetLength| is used in two ways: - * 1) to |Cut| a suffix of the string; - * 2) to prepare to |Append| or move characters around. - * - * External callers are not allowed to use |SetLength| is this latter capacity. - * Should this really be a public operation? - * Additionally, your implementation of |SetLength| need not satisfy (2) if and only if you - * override the |do_...| routines to not need this facility. - * - * This distinction makes me think the two different uses should be split into - * two distinct functions. - */ - virtual void SetLength( PRUint32 ) = 0; - - - void - Truncate( PRUint32 aNewLength=0 ) - { - NS_ASSERTION(aNewLength<=this->Length(), "Can't use |Truncate()| to make a string longer."); - - if ( aNewLength < this->Length() ) - SetLength(aNewLength); - } - - - // PRBool SetCharAt( char_type, index_type ) = 0; - - - - // void ToLowerCase(); - // void ToUpperCase(); - - // void StripChars( const CharT* aSet ); - // void StripChar( ... ); - // void StripWhitespace(); - // void ReplaceChar( ... ); - // void ReplaceSubstring( ... ); - // void Trim( ... ); - // void CompressSet( ... ); - // void CompressWhitespace( ... ); - - - - // - // |Assign()|, |operator=()| - // - - void Assign( const basic_nsAReadableString& aReadable ) { AssignFromReadable(aReadable); } - void Assign( const nsPromiseReadable& aReadable ) { AssignFromPromise(aReadable); } - void Assign( const CharT* aPtr ) { aPtr ? do_AssignFromElementPtr(aPtr) : SetLength(0); } - void Assign( const CharT* aPtr, PRUint32 aLength ) { do_AssignFromElementPtrLength(aPtr, aLength); } - void Assign( CharT aChar ) { do_AssignFromElement(aChar); } - - // copy-assignment operator. I must define my own if I don't want the compiler to make me one - basic_nsAWritableString& operator=( const basic_nsAWritableString& aWritable ) { Assign(aWritable); return *this; } - - basic_nsAWritableString& operator=( const basic_nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - basic_nsAWritableString& operator=( const CharT* aPtr ) { Assign(aPtr); return *this; } - basic_nsAWritableString& operator=( CharT aChar ) { Assign(aChar); return *this; } - - - - // - // |Append()|, |operator+=()| - // - - void Append( const basic_nsAReadableString& aReadable ) { AppendFromReadable(aReadable); } - void Append( const nsPromiseReadable& aReadable ) { AppendFromPromise(aReadable); } - void Append( const CharT* aPtr ) { if (aPtr) do_AppendFromElementPtr(aPtr); } - void Append( const CharT* aPtr, PRUint32 aLength ) { do_AppendFromElementPtrLength(aPtr, aLength); } - void Append( CharT aChar ) { do_AppendFromElement(aChar); } - - basic_nsAWritableString& operator+=( const basic_nsAReadableString& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const nsPromiseReadable& aReadable ) { Append(aReadable); return *this; } - basic_nsAWritableString& operator+=( const CharT* aPtr ) { Append(aPtr); return *this; } - basic_nsAWritableString& operator+=( CharT aChar ) { Append(aChar); return *this; } - - - - /** - * The following index based routines need to be recast with iterators. - */ - - // - // |Insert()| - // Note: I would really like to move the |atPosition| parameter to the front of the argument list - // - - void Insert( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) { InsertFromReadable(aReadable, atPosition); } - void Insert( const nsPromiseReadable& aReadable, PRUint32 atPosition ) { InsertFromPromise(aReadable, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition ) { if (aPtr) do_InsertFromElementPtr(aPtr, atPosition); } - void Insert( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) { do_InsertFromElementPtrLength(aPtr, atPosition, aLength); } - void Insert( CharT aChar, PRUint32 atPosition ) { do_InsertFromElement(aChar, atPosition); } - - - - virtual void Cut( PRUint32 cutStart, PRUint32 cutLength ); - - - - void Replace( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) { ReplaceFromReadable(cutStart, cutLength, aReadable); } - void Replace( PRUint32 cutStart, PRUint32 cutLength, const nsPromiseReadable& aReadable ) { ReplaceFromPromise(cutStart, cutLength, aReadable); } - - private: - typedef typename nsCharTraits::incompatible_char_type incompatible_char_type; - - // NOT TO BE IMPLEMENTED - void operator= ( incompatible_char_type ); - void Assign ( incompatible_char_type ); - void operator+= ( incompatible_char_type ); - void Append ( incompatible_char_type ); - void Insert ( incompatible_char_type, PRUint32 ); - - - protected: - void AssignFromReadable( const basic_nsAReadableString& ); - void AssignFromPromise( const basic_nsAReadableString& ); - virtual void do_AssignFromReadable( const basic_nsAReadableString& ); - virtual void do_AssignFromElementPtr( const CharT* ); - virtual void do_AssignFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AssignFromElement( CharT ); - - void AppendFromReadable( const basic_nsAReadableString& ); - void AppendFromPromise( const basic_nsAReadableString& ); - virtual void do_AppendFromReadable( const basic_nsAReadableString& ); - virtual void do_AppendFromElementPtr( const CharT* ); - virtual void do_AppendFromElementPtrLength( const CharT*, PRUint32 ); - virtual void do_AppendFromElement( CharT ); - - void InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - void InsertFromPromise( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - virtual void do_InsertFromElementPtr( const CharT*, PRUint32 ); - virtual void do_InsertFromElementPtrLength( const CharT*, PRUint32, PRUint32 ); - virtual void do_InsertFromElement( CharT, PRUint32 ); - - void ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - void ReplaceFromPromise( PRUint32, PRUint32, const basic_nsAReadableString& ); - virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - }; - - - - // - // |nsWritingIterator|s - // - -template -inline -void -nsWritingIterator::normalize_forward() - { - while ( mPosition == mFragment.mEnd - && mOwningString->GetWritableFragment(mFragment, kNextFragment) ) - mPosition = mFragment.mStart; - } - -template -inline -void -nsWritingIterator::normalize_backward() - { - while ( mPosition == mFragment.mStart - && mOwningString->GetWritableFragment(mFragment, kPrevFragment) ) - mPosition = mFragment.mEnd; - } - -template -inline -PRBool -operator==( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) - { - return lhs.get() == rhs.get(); - } - -template -inline -PRBool -operator!=( const nsWritingIterator& lhs, const nsWritingIterator& rhs ) - { - return lhs.get() != rhs.get(); - } - - - - // - // |Assign()| - // - -template -void -basic_nsAWritableString::AssignFromReadable( const basic_nsAReadableString& rhs ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &rhs ) - do_AssignFromReadable(rhs); - // else, self-assign is a no-op - } - -template -void -basic_nsAWritableString::AssignFromPromise( const basic_nsAReadableString& aReadable ) - /* - ...this function is only called when a promise that somehow references |this| is assigned _into_ |this|. - E.g., - - ... writable& w ... - ... readable& r ... - - w = r + w; - - In this example, you can see that unless the characters promised by |w| in |r+w| are resolved before - anything starts getting copied into |w|, there will be trouble. They will be overritten by the contents - of |r| before being retrieved to be appended. - - We could have a really tricky solution where we tell the promise to resolve _just_ the data promised - by |this|, but this should be a rare case, since clients with more local knowledge will know that, e.g., - in the case above, |Insert| could have special behavior with significantly better performance. Since - it's a rare case anyway, we should just do the simplest thing that could possibly work, resolve the - entire promise. If we measure and this turns out to show up on performance radar, we then have the - option to fix either the callers or this mechanism. - */ - { - if ( !aReadable.Promises(*this) ) - do_AssignFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - // Note: not exception safe. We need something to manage temporary buffers like this - - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AssignFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AssignFromReadable( const basic_nsAReadableString& aReadable ) - { - SetLength(0); - SetLength(aReadable.Length()); - // first setting the length to |0| avoids copying characters only to be overwritten later - // in the case where the implementation decides to re-allocate - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtr( const CharT* aPtr ) - { - do_AssignFromReadable(basic_nsLiteralString(aPtr)); - } - -template -void -basic_nsAWritableString::do_AssignFromElementPtrLength( const CharT* aPtr, PRUint32 aLength ) - { - do_AssignFromReadable(basic_nsLiteralString(aPtr, aLength)); - } - -template -void -basic_nsAWritableString::do_AssignFromElement( CharT aChar ) - { - do_AssignFromReadable(basic_nsLiteralChar(aChar)); - } - - - - // - // |Append()| - // - -template -void -basic_nsAWritableString::AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_AppendFromReadable(aReadable); - else - AppendFromPromise(aReadable); - } - -template -void -basic_nsAWritableString::AppendFromPromise( const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_AppendFromReadable(aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_AppendFromElementPtrLength(buffer, length); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_AppendFromReadable( const basic_nsAReadableString& aReadable ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance( PRInt32(oldLength) ) ); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtr( const CharT* aChar ) - { - do_AppendFromReadable(basic_nsLiteralString(aChar)); - } - -template -void -basic_nsAWritableString::do_AppendFromElementPtrLength( const CharT* aChar, PRUint32 aLength ) - { - do_AppendFromReadable(basic_nsLiteralString(aChar, aLength)); - } - -template -void -basic_nsAWritableString::do_AppendFromElement( CharT aChar ) - { - do_AppendFromReadable(basic_nsLiteralChar(aChar)); - } - - - - // - // |Insert()| - // - -template -void -basic_nsAWritableString::InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReadable ) - do_InsertFromReadable(aReadable, atPosition); - else - InsertFromPromise(aReadable, atPosition); - } - -template -void -basic_nsAWritableString::InsertFromPromise( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - if ( !aReadable.Promises(*this) ) - do_InsertFromReadable(aReadable, atPosition); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_InsertFromElementPtrLength(buffer, atPosition, length); - delete buffer; - } - // else assert - } - } - -template -void -basic_nsAWritableString::do_InsertFromReadable( const basic_nsAReadableString& aReadable, PRUint32 atPosition ) - { - PRUint32 oldLength = this->Length(); - SetLength(oldLength + aReadable.Length()); - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( atPosition < oldLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(atPosition)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), EndWriting(toBegin)); - else - atPosition = oldLength; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(atPosition))); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtr( const CharT* aPtr, PRUint32 atPosition ) - { - do_InsertFromReadable(basic_nsLiteralString(aPtr), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElementPtrLength( const CharT* aPtr, PRUint32 atPosition, PRUint32 aLength ) - { - do_InsertFromReadable(basic_nsLiteralString(aPtr, aLength), atPosition); - } - -template -void -basic_nsAWritableString::do_InsertFromElement( CharT aChar, PRUint32 atPosition ) - { - do_InsertFromReadable(basic_nsLiteralChar(aChar), atPosition); - } - - - - // - // |Cut()| - // - -template -void -basic_nsAWritableString::Cut( PRUint32 cutStart, PRUint32 cutLength ) - { - PRUint32 myLength = this->Length(); - cutLength = NS_MIN(cutLength, myLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutEnd < myLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - SetLength(myLength-cutLength); - } - - - - // - // |Replace()| - // - -template -void -basic_nsAWritableString::ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - if ( NS_STATIC_CAST(const basic_nsAReadableString*, this) != &aReplacement ) - do_ReplaceFromReadable(cutStart, cutLength, aReplacement); - else - ReplaceFromPromise(cutStart, cutLength, aReplacement); - } - -template -void -basic_nsAWritableString::ReplaceFromPromise( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReadable ) - { - if ( !aReadable.Promises(*this) ) - do_ReplaceFromReadable(cutStart, cutLength, aReadable); - else - { - PRUint32 length = aReadable.Length(); - CharT* buffer = new CharT[length]; - if ( buffer ) - { - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = buffer; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - do_ReplaceFromReadable(cutStart, cutLength, basic_nsLiteralString(buffer, length)); - delete buffer; - } - // else assert? - } - } - -template -void -basic_nsAWritableString::do_ReplaceFromReadable( PRUint32 cutStart, PRUint32 cutLength, const basic_nsAReadableString& aReplacement ) - { - PRUint32 oldLength = this->Length(); - - cutStart = NS_MIN(cutStart, oldLength); - cutLength = NS_MIN(cutLength, oldLength-cutStart); - PRUint32 cutEnd = cutStart + cutLength; - - PRUint32 replacementLength = aReplacement.Length(); - PRUint32 replacementEnd = cutStart + replacementLength; - - PRUint32 newLength = oldLength - cutLength + replacementLength; - - nsReadingIterator fromBegin, fromEnd; - nsWritingIterator toBegin; - if ( cutLength > replacementLength ) - copy_string(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - SetLength(newLength); - if ( cutLength < replacementLength ) - copy_string_backward(this->BeginReading(fromBegin).advance(PRInt32(cutEnd)), this->BeginReading(fromEnd).advance(PRInt32(oldLength)), BeginWriting(toBegin).advance(PRInt32(replacementEnd))); - - copy_string(aReplacement.BeginReading(fromBegin), aReplacement.EndReading(fromEnd), BeginWriting(toBegin).advance(PRInt32(cutStart))); - } - - -template -PRUint32 -basic_nsAReadableString::Mid( basic_nsAWritableString& aResult, PRUint32 aStartPos, PRUint32 aLengthToCopy ) const - { - // If we're just assigning our entire self, give |aResult| the opportunity to share - if ( aStartPos == 0 && aLengthToCopy >= Length() ) - aResult = *this; - else - aResult = Substring(*this, aStartPos, aLengthToCopy); - - return aResult.Length(); - } - -template -inline -PRUint32 -basic_nsAReadableString::Left( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - return Mid(aResult, 0, aLengthToCopy); - } - -template -PRUint32 -basic_nsAReadableString::Right( basic_nsAWritableString& aResult, PRUint32 aLengthToCopy ) const - { - PRUint32 myLength = Length(); - aLengthToCopy = NS_MIN(myLength, aLengthToCopy); - return Mid(aResult, myLength-aLengthToCopy, aLengthToCopy); - } - - - - - // - // Types - // - -typedef basic_nsAWritableString nsAWritableString; -typedef basic_nsAWritableString nsAWritableCString; - -#endif // !defined(nsAWritableString_h___) diff --git a/xpcom/ds/nsAlgorithm.h b/xpcom/ds/nsAlgorithm.h deleted file mode 100755 index 9c2e5855cc14..000000000000 --- a/xpcom/ds/nsAlgorithm.h +++ /dev/null @@ -1,112 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsAlgorithm_h___ -#define nsAlgorithm_h___ - -#ifndef nsCharTraits_h___ -#include "nsCharTraits.h" - // for |nsCharSourceTraits|, |nsCharSinkTraits| -#endif - -#ifndef prtypes_h___ -#include "prtypes.h" - // for |PRUint32|... -#endif - -template -inline -const T& -NS_MIN( const T& a, const T& b ) - { - return b < a ? b : a; - } - -template -inline -const T& -NS_MAX( const T& a, const T& b ) - { - return a > b ? a : b; - } - -template -inline -PRUint32 -NS_COUNT( InputIterator& first, const InputIterator& last, const T& value ) - { - PRUint32 result = 0; - for ( ; first != last; ++first ) - if ( *first == value ) - ++result; - return result; - } - -template -inline -OutputIterator& -copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result ) - { - typedef nsCharSourceTraits source_traits; - typedef nsCharSinkTraits sink_traits; - - while ( first != last ) - { - PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last))); - NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate"); - source_traits::advance(first, count_copied); - } - - return result; - } - -template -OutputIterator& -copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result ) - { - while ( first != last ) - { - last.normalize_backward(); - result.normalize_backward(); - PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) ); - if ( first.fragment().mStart == last.fragment().mStart ) - lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.get() - first.get())); - - NS_ASSERTION(lengthToCopy, "|copy_string_backward| will never terminate"); - -#ifdef _MSC_VER - // XXX Visual C++ can't stomach 'typename' where it rightfully should - nsCharTraits::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy); -#else - nsCharTraits::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy); -#endif - - last.advance( -PRInt32(lengthToCopy) ); - result.advance( -PRInt32(lengthToCopy) ); - } - - return result; - } - -#endif // !defined(nsAlgorithm_h___) diff --git a/xpcom/ds/nsBufferHandle.h b/xpcom/ds/nsBufferHandle.h deleted file mode 100755 index b8cf0688dba3..000000000000 --- a/xpcom/ds/nsBufferHandle.h +++ /dev/null @@ -1,181 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsBufferHandle_h___ -#define nsBufferHandle_h___ - -#include - // for |ptrdiff_t| - -#include "prtypes.h" - // for |PRBool| - -#include "nsDebug.h" - // for |NS_ASSERTION| - -#include "nsMemory.h" - // for |nsMemory::Free| - - /** - * - */ -template -class nsBufferHandle - { - public: - nsBufferHandle( CharT* aDataStart, CharT* aDataEnd ) : mDataStart(aDataStart), mDataEnd(aDataEnd) { } - - void DataStart( CharT* aNewDataStart ) { mDataStart = aNewDataStart; } - CharT* DataStart() { return mDataStart; } - const CharT* DataStart() const { return mDataStart; } - - void DataEnd( CharT* aNewDataEnd ) { mDataEnd = aNewDataEnd; } - CharT* DataEnd() { return mDataEnd; } - const CharT* DataEnd() const { return mDataEnd; } - -// void DataLength( ptrdiff_t aNewDataLength ) { mDataEnd = mDataStart+aNewDataLength; } - ptrdiff_t DataLength() const { return mDataEnd - mDataStart; } - - protected: - CharT* mDataStart; - CharT* mDataEnd; - }; - - - - /** - * - */ -template -class nsSharedBufferHandle - : public nsBufferHandle - { - protected: - enum - { - kIsShared = 1<<31, - kIsSingleAllocationWithBuffer = 1<<30, - kIsStorageDefinedSeparately = 1<<29, - - kFlagsMask = kIsShared | kIsSingleAllocationWithBuffer | kIsStorageDefinedSeparately, - kRefCountMask = ~kFlagsMask - }; - - public: - nsSharedBufferHandle( CharT* aDataStart, CharT* aDataEnd ) - : nsBufferHandle(aDataStart, aDataEnd) - { - mFlags = kIsShared; - } - - ~nsSharedBufferHandle(); - - void - AcquireReference() const - { - nsSharedBufferHandle* mutable_this = NS_CONST_CAST(nsSharedBufferHandle*, this); - mutable_this->set_refcount( get_refcount()+1 ); - } - - void - ReleaseReference() const - { - nsSharedBufferHandle* mutable_this = NS_CONST_CAST(nsSharedBufferHandle*, this); - if ( !mutable_this->set_refcount( get_refcount()-1 ) ) - delete mutable_this; - } - - PRBool - IsReferenced() const - { - return get_refcount() != 0; - } - - protected: - PRUint32 mFlags; - - PRUint32 - get_refcount() const - { - return mFlags & kRefCountMask; - } - - PRUint32 - set_refcount( PRUint32 aNewRefCount ) - { - NS_ASSERTION(aNewRefCount <= kRefCountMask, "aNewRefCount <= kRefCountMask"); - - mFlags = (mFlags & kFlagsMask) | aNewRefCount; - return aNewRefCount; - } - }; - - - // need a name for this -template -class nsFlexBufferHandle - : public nsSharedBufferHandle - { - public: - nsFlexBufferHandle( CharT* aDataStart, CharT* aDataEnd, CharT* aStorageStart, CharT* aStorageEnd ) - : nsSharedBufferHandle(aDataStart, aDataEnd), - mStorageStart(aStorageStart), - mStorageEnd(aStorageEnd) - { - this->mFlags |= this->kIsStorageDefinedSeparately; - } - - void StorageStart( CharT* aNewStorageStart ) { mStorageStart = aNewStorageStart; } - CharT* StorageStart() { return mStorageStart; } - const CharT* StorageStart() const { return mStorageStart; } - - void StorageEnd( CharT* aNewStorageEnd ) { mStorageEnd = aNewStorageEnd; } - CharT* StorageEnd() { return mStorageEnd; } - const CharT* StorageEnd() const { return mStorageEnd; } - -// void StorageLength( ptrdiff_t aNewStorageLength ) { mStorageEnd = mStorageStart+aNewStorageLength; } - ptrdiff_t StorageLength() const { return mStorageEnd - mStorageStart; } - - protected: - CharT* mStorageStart; - CharT* mStorageEnd; - }; - -template -nsSharedBufferHandle::~nsSharedBufferHandle() - // really don't want this to be |inline| - { - NS_ASSERTION(!IsReferenced(), "!IsReferenced()"); - - if ( !(mFlags & kIsSingleAllocationWithBuffer) ) - { - CharT* string_storage = this->mDataStart; - if ( mFlags & kIsStorageDefinedSeparately ) - string_storage = NS_REINTERPRET_CAST(nsFlexBufferHandle*, this)->StorageStart(); - nsMemory::Free(string_storage); - } - } - - -#endif // !defined(nsBufferHandle_h___) diff --git a/xpcom/ds/nsBufferHandleUtils.h b/xpcom/ds/nsBufferHandleUtils.h deleted file mode 100644 index 6f05fabe22ab..000000000000 --- a/xpcom/ds/nsBufferHandleUtils.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsBufferHandleUtils_h___ -#define nsBufferHandleUtils_h___ - -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |basic_nsAReadableString|... -#endif - -#include - // for placement |new| - - - -template -inline -size_t -NS_AlignedHandleSize( const HandleT*, const CharT* ) - { - // figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part - return ((sizeof(HandleT) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT); - } - -template -inline -const CharT* -NS_DataAfterHandle( const HandleT* aHandlePtr, const CharT* aDummyCharTPtr ) - { - typedef const CharT* CharT_ptr; - return CharT_ptr(NS_STATIC_CAST(const unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr)); - } - -template -inline -CharT* -NS_DataAfterHandle( HandleT* aHandlePtr, const CharT* aDummyCharTPtr ) - { - typedef CharT* CharT_ptr; - return CharT_ptr(NS_STATIC_CAST(unsigned char*, aHandlePtr) + NS_AlignedHandleSize(aHandlePtr, aDummyCharTPtr)); - } - -template -HandleT* -NS_AllocateContiguousHandleWithData( const HandleT* aDummyHandlePtr, const basic_nsAReadableString& aDataSource, PRUint32 aAdditionalCapacity ) - { - typedef CharT* CharT_ptr; - - // figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part - size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, CharT_ptr(0)); - - // figure out how many |CharT|s wee need to fit in the data part - size_t data_length = aDataSource.Length(); - size_t buffer_length = data_length + aAdditionalCapacity; - - // how many bytes is that (including a zero-terminator so we can claim to be flat)? - size_t buffer_size = buffer_length * sizeof(CharT); - - - HandleT* result = 0; - void* handle_ptr = ::operator new(handle_size + buffer_size); - - if ( handle_ptr ) - { - CharT* data_start_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); - CharT* data_end_ptr = data_start_ptr + data_length; - CharT* buffer_end_ptr = data_start_ptr + buffer_length; - - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = data_start_ptr; - copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin); - - // and if the caller bothered asking for a buffer bigger than their string, we'll zero-terminate - if ( aAdditionalCapacity > 0 ) - *toBegin = CharT(0); - - result = new (handle_ptr) HandleT(data_start_ptr, data_end_ptr, data_start_ptr, buffer_end_ptr, PR_TRUE); - } - - return result; - } - -#endif // !defined(nsBufferHandleUtils_h___) diff --git a/xpcom/ds/nsCharTraits.h b/xpcom/ds/nsCharTraits.h deleted file mode 100644 index dc4b681a1f5e..000000000000 --- a/xpcom/ds/nsCharTraits.h +++ /dev/null @@ -1,703 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - */ - -#ifndef nsCharTraits_h___ -#define nsCharTraits_h___ - -#include - // for |EOF|, |WEOF| - -#include - // for |memcpy|, et al - -#ifndef nscore_h___ -#include "nscore.h" - // for |PRUnichar| -#endif - - -#ifdef HAVE_CPP_BOOL - typedef bool nsCharTraits_bool; -#else - typedef PRBool nsCharTraits_bool; -#endif - -template -struct nsCharTraits - { - typedef CharT char_type; - typedef char incompatible_char_type; - - static - void - assign( char_type& lhs, const char_type& rhs ) - { - lhs = rhs; - } - - - // integer representation of characters: - - typedef int int_type; - - static - char_type - to_char_type( const int_type& c ) - { - return char_type(c); - } - - static - int_type - to_int_type( const char_type& c ) - { - return int_type(c); - } - - static - nsCharTraits_bool - eq_int_type( const int_type& lhs, const int_type& rhs ) - { - return lhs == rhs; - } - - - // |char_type| comparisons: - - static - nsCharTraits_bool - eq( const char_type& lhs, const char_type& rhs ) - { - return lhs == rhs; - } - - static - nsCharTraits_bool - lt( const char_type& lhs, const char_type& rhs ) - { - return lhs < rhs; - } - - - // operations on s[n] arrays: - - static - char_type* - copy( char_type* s1, const char_type* s2, size_t n ) - { - char_type* result = s1; - while ( n-- ) - assign(*s1++, *s2++); - return result; - } - - static - char_type* - move( char_type* s1, const char_type* s2, size_t n ) - { - char_type* result = s1; - - if ( n ) - { - if ( s2 > s1 ) - copy(s1, s2, n); - else - { - s1 += n; - s2 += n; - while ( n-- ) - assign(*--s1, *--s2); - } - } - - return result; - } - - static - char_type* - assign( char_type* s, size_t n, const char_type& c ) - { - char_type* result = s; - while ( n-- ) - assign(*s++, c); - return result; - } - - static - int - compare( const char_type* s1, const char_type* s2, size_t n ) - { - for ( ; n--; ++s1, ++s2 ) - { - if ( lt(*s1, *s2) ) - return -1; - if ( lt(*s2, *s1) ) - return 1; - } - - return 0; - } - - static - size_t - length( const char_type* s ) - { - size_t result = 0; - while ( !eq(*s++, CharT(0)) ) - ++result; - return result; - } - - static - const char_type* - find( const char_type* s, size_t n, const char_type& c ) - { - while ( n-- ) - { - if ( eq(*s, c) ) - return s; - ++s; - } - - return 0; - } - -#if 0 - // I/O related: - - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static - int_type - eof() - { - return EOF; - } - - static - int_type - not_eof( const int_type& c ) - { - return eq_int_type(c, eof()) ? ~eof() : c; - } - - // static state_type get_state( pos_type ); -#endif - }; - -NS_SPECIALIZE_TEMPLATE -struct nsCharTraits - { - typedef char char_type; - typedef PRUnichar incompatible_char_type; - - static - void - assign( char& lhs, char rhs ) - { - lhs = rhs; - } - - - // integer representation of characters: - - typedef int int_type; - - static - char - to_char_type( int c ) - { - return char(c); - } - - static - int - to_int_type( char c ) - { - return int( NS_STATIC_CAST(unsigned char, c) ); - } - - static - nsCharTraits_bool - eq_int_type( int lhs, int rhs ) - { - return lhs == rhs; - } - - - // |char_type| comparisons: - - static - nsCharTraits_bool - eq( char lhs, char rhs ) - { - return lhs == rhs; - } - - static - nsCharTraits_bool - lt( char lhs, char rhs ) - { - return lhs < rhs; - } - - - // operations on s[n] arrays: - - static - char* - move( char* s1, const char* s2, size_t n ) - { - return NS_STATIC_CAST(char*, memmove(s1, s2, n)); - } - - static - char* - copy( char* s1, const char* s2, size_t n ) - { - return NS_STATIC_CAST(char*, memcpy(s1, s2, n)); - } - - static - char* - assign( char* s, size_t n, char c ) - { - return NS_STATIC_CAST(char*, memset(s, to_int_type(c), n)); - } - - static - int - compare( const char* s1, const char* s2, size_t n ) - { - return memcmp(s1, s2, n); - } - - static - size_t - length( const char* s ) - { - return strlen(s); - } - - static - const char* - find( const char* s, size_t n, char c ) - { - return NS_REINTERPRET_CAST(const char*, memchr(s, to_int_type(c), n)); - } - -#if 0 - // I/O related: - - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static - int_type - eof() - { - return EOF; - } - - static - int - not_eof( int c ) - { - return c==eof() ? ~eof() : c; - } - - // static state_type get_state( pos_type ); -#endif - }; - -#if 0 -NS_SPECIALIZE_TEMPLATE -struct nsCharTraits - { - typedef wchar_t char_type; - - static - void - assign( wchar_t& lhs, wchar_t rhs ) - { - lhs = rhs; - } - - - // integer representation of characters: - - typedef wint_t int_type; - - static - wchar_t - to_char_type( int_type c ) - { - return wchar_t(c); - } - - static - int_type - to_int_type( wchar_t c ) - { - return int_type(c); - } - - static - nsCharTraits_bool - eq_int_type( int_type lhs, int_type rhs ) - { - return lhs == rhs; - } - - - // |char_type| comparisons: - - static - nsCharTraits_bool - eq( wchar_t lhs, wchar_t rhs ) - { - return lhs == rhs; - } - - static - nsCharTraits_bool - lt( wchar_t lhs, wchar_t rhs ) - { - return lhs < rhs; - } - - - // operations on s[n] arrays: - - static - wchar_t* - move( wchar_t* s1, const wchar_t* s2, size_t n ) - { - return NS_STATIC_CAST(wchar_t*, wmemmove(s1, s2, n)); - } - - static - wchar_t* - copy( wchar_t* s1, const wchar_t* s2, size_t n ) - { - return NS_STATIC_CAST(wchar_t*, wmemcpy(s1, s2, n)); - } - - static - wchar_t* - assign( wchar_t* s, size_t n, wchar_t c ) - { - return NS_STATIC_CAST(wchar_t*, wmemset(s, to_int_type(c), n)); - } - - static - int - compare( const wchar_t* s1, const wchar_t* s2, size_t n ) - { - return wmemcmp(s1, s2, n); - } - - static - size_t - length( const wchar_t* s ) - { - return wcslen(s); - } - - static - const wchar_t* - find( const wchar_t* s, size_t n, wchar_t c ) - { - return NS_REINTERPRET_CAST(const wchar_t*, wmemchr(s, to_int_type(c), n)); - } - -#if 0 - // I/O related: - - typedef streamoff off_type; - typedef streampos pos_type; - typedef mbstate_t state_type; - - static - int_type - eof() - { - return WEOF; - } - - static - int_type - not_eof( int_type c ) - { - return c==eof() ? ~eof() : c; - } - - // static state_type get_state( pos_type ); -#endif - }; -#endif - - -template -struct nsCharSourceTraits - { - typedef typename InputIterator::difference_type difference_type; - -#if 0 - static - PRUint32 - distance( const InputIterator& first, const InputIterator& last ) - { - // ... - } -#endif - - static - PRUint32 - readable_distance( const InputIterator& iter ) - { - return iter.size_forward(); - } - - static - PRUint32 - readable_distance( const InputIterator& first, const InputIterator& last ) - { - return PRUint32(SameFragment(first, last) ? last.get()-first.get() : first.size_forward()); - } - - static - const typename InputIterator::value_type* - read( const InputIterator& iter ) - { - return iter.get(); - } - - static - void - advance( InputIterator& s, difference_type n ) - { - s.advance(n); - } - }; - -#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION - -template -struct nsCharSourceTraits - { - typedef ptrdiff_t difference_type; - -#if 0 - static - PRUint32 - distance( CharT* first, CharT* last ) - { - return PRUint32(last-first); - } -#endif - - static - PRUint32 - readable_distance( CharT* s ) - { - return PRUint32(nsCharTraits::length(s)); -// return numeric_limits::max(); - } - - static - PRUint32 - readable_distance( CharT* first, CharT* last ) - { - return PRUint32(last-first); - } - - static - const CharT* - read( CharT* s ) - { - return s; - } - - static - void - advance( CharT*& s, difference_type n ) - { - s += n; - } - }; - -#else - -NS_SPECIALIZE_TEMPLATE -struct nsCharSourceTraits - { - typedef ptrdiff_t difference_type; - -#if 0 - static - PRUint32 - distance( const char* first, const char* last ) - { - return PRUint32(last-first); - } -#endif - - static - PRUint32 - readable_distance( const char* s ) - { - return PRUint32(nsCharTraits::length(s)); -// return numeric_limits::max(); - } - - static - PRUint32 - readable_distance( const char* first, const char* last ) - { - return PRUint32(last-first); - } - - static - const char* - read( const char* s ) - { - return s; - } - - static - void - advance( const char*& s, difference_type n ) - { - s += n; - } - }; - - -NS_SPECIALIZE_TEMPLATE -struct nsCharSourceTraits - { - typedef ptrdiff_t difference_type; - -#if 0 - static - PRUint32 - distance( const PRUnichar* first, const PRUnichar* last ) - { - return PRUint32(last-first); - } -#endif - - static - PRUint32 - readable_distance( const PRUnichar* s ) - { - return PRUint32(nsCharTraits::length(s)); -// return numeric_limits::max(); - } - - static - PRUint32 - readable_distance( const PRUnichar* first, const PRUnichar* last ) - { - return PRUint32(last-first); - } - - static - const PRUnichar* - read( const PRUnichar* s ) - { - return s; - } - - static - void - advance( const PRUnichar*& s, difference_type n ) - { - s += n; - } - }; - -#endif - - -template -struct nsCharSinkTraits - { - static - PRUint32 - write( OutputIterator& iter, const typename OutputIterator::value_type* s, PRUint32 n ) - { - return iter.write(s, n); - } - }; - -#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION - -template -struct nsCharSinkTraits - { - static - PRUint32 - write( CharT*& iter, const CharT* s, PRUint32 n ) - { - nsCharTraits::move(iter, s, n); - iter += n; - return n; - } - }; - -#else - -NS_SPECIALIZE_TEMPLATE -struct nsCharSinkTraits - { - static - PRUint32 - write( char*& iter, const char* s, PRUint32 n ) - { - nsCharTraits::move(iter, s, n); - iter += n; - return n; - } - }; - -NS_SPECIALIZE_TEMPLATE -struct nsCharSinkTraits - { - static - PRUint32 - write( PRUnichar*& iter, const PRUnichar* s, PRUint32 n ) - { - nsCharTraits::move(iter, s, n); - iter += n; - return n; - } - }; - -#endif - -#endif // !defined(nsCharTraits_h___) diff --git a/xpcom/ds/nsFragmentedString.cpp b/xpcom/ds/nsFragmentedString.cpp deleted file mode 100755 index 42dd6aed379a..000000000000 --- a/xpcom/ds/nsFragmentedString.cpp +++ /dev/null @@ -1,162 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla XPCOM. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Original Author: - * Scott Collins - * - * Contributor(s): - */ - -#include "nsFragmentedString.h" - - -const PRUnichar* -nsFragmentedString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - const nsSharedBufferList::Buffer* buffer = 0; - switch ( aRequest ) - { - case kPrevFragment: - buffer = NS_STATIC_CAST(const nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mPrev; - break; - - case kFirstFragment: - buffer = mBufferList.GetFirstBuffer(); - break; - - case kLastFragment: - buffer = mBufferList.GetLastBuffer(); - break; - - case kNextFragment: - buffer = NS_STATIC_CAST(const nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mNext; - break; - - case kFragmentAt: - // ...work... - break; - } - - if ( buffer ) - { - aFragment.mStart = buffer->DataStart(); - aFragment.mEnd = buffer->DataEnd(); - aFragment.mFragmentIdentifier = buffer; - return aFragment.mStart + aOffset; - } - - return 0; - } - - -PRUnichar* -nsFragmentedString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) - { - nsSharedBufferList::Buffer* buffer = 0; - switch ( aRequest ) - { - case kPrevFragment: - buffer = NS_STATIC_CAST(nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mPrev; - break; - - case kFirstFragment: - buffer = mBufferList.GetFirstBuffer(); - break; - - case kLastFragment: - buffer = mBufferList.GetLastBuffer(); - break; - - case kNextFragment: - buffer = NS_STATIC_CAST(nsSharedBufferList::Buffer*, aFragment.mFragmentIdentifier)->mNext; - break; - - case kFragmentAt: - // ...work... - break; - } - - if ( buffer ) - { - aFragment.mStart = buffer->DataStart(); - aFragment.mEnd = buffer->DataEnd(); - aFragment.mFragmentIdentifier = buffer; - return aFragment.mStart + aOffset; - } - - return 0; - } - - /** - * ... - */ -PRUint32 -nsFragmentedString::Length() const - { - return PRUint32(mBufferList.GetDataLength()); - } - - /** - * |SetLength| - */ -void -nsFragmentedString::SetLength( PRUint32 aNewLength ) - { - // according to the current interpretation of |SetLength|, - // cut off characters from the end, or else add unitialized space to fill - - if ( aNewLength < PRUint32(mBufferList.GetDataLength()) ) - { -// if ( aNewLength ) - mBufferList.DiscardSuffix(mBufferList.GetDataLength()-aNewLength); -// else -// mBufferList.DestroyBuffers(); - } - -// temporarily... eliminate as soon as our munging routines don't need this form of |SetLength| - else if ( aNewLength > PRUint32(mBufferList.GetDataLength()) ) - { - size_t empty_space_to_add = aNewLength - mBufferList.GetDataLength(); - nsSharedBufferList::Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(0, 0, empty_space_to_add); - new_buffer->DataEnd(new_buffer->DataStart()+empty_space_to_add); - mBufferList.LinkBuffer(mBufferList.GetLastBuffer(), new_buffer, 0); - } - } - - -#if 0 - /** - * |SetCapacity|. - * - * If a client tries to increase the capacity of multi-fragment string, perhaps a single - * empty fragment of the appropriate size should be appended. - */ -void -nsFragmentedString::SetCapacity( PRUint32 aNewCapacity ) - { - if ( !aNewCapacity ) - { - // |SetCapacity(0)| is special and means ``release all storage''. - } - else if ( aNewCapacity > ... ) - { - - } - } -#endif diff --git a/xpcom/ds/nsFragmentedString.h b/xpcom/ds/nsFragmentedString.h deleted file mode 100644 index e5348b42f48a..000000000000 --- a/xpcom/ds/nsFragmentedString.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla XPCOM. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsFragmentedString_h___ -#define nsFragmentedString_h___ - - // WORK IN PROGRESS - -#ifndef nsAWritableString_h___ -#include "nsAWritableString.h" -#endif - -#ifndef nsSharedBufferList_h___ -#include "nsSharedBufferList.h" -#endif - - -class nsFragmentedString - : public basic_nsAWritableString - /* - ... - */ - { - protected: - virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); - - public: - nsFragmentedString() { } - - virtual PRUint32 Length() const; - - virtual void SetLength( PRUint32 aNewLength ); - // virtual void SetCapacity( PRUint32 aNewCapacity ); - - // virtual void Cut( PRUint32 cutStart, PRUint32 cutLength ); - - protected: - // virtual void do_AssignFromReadable( const basic_nsAReadableString& ); - // virtual void do_AppendFromReadable( const basic_nsAReadableString& ); - // virtual void do_InsertFromReadable( const basic_nsAReadableString&, PRUint32 ); - // virtual void do_ReplaceFromReadable( PRUint32, PRUint32, const basic_nsAReadableString& ); - - private: - nsSharedBufferList mBufferList; - }; - -#endif // !defined(nsFragmentedString_h___) diff --git a/xpcom/ds/nsPrintfCString.cpp b/xpcom/ds/nsPrintfCString.cpp deleted file mode 100755 index 17cc3f44c76f..000000000000 --- a/xpcom/ds/nsPrintfCString.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Original Author: - * Scott Collins - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "nsPrintfCString.h" -#include -#include "prprf.h" - - -nsPrintfCString::nsPrintfCString( const char* format, ... ) - : mStart(mLocalBuffer), - mLength(0) - { - va_list ap; - - size_t logical_capacity = kLocalBufferSize; - size_t physical_capacity = logical_capacity + 1; - - va_start(ap, format); - mLength = PR_vsnprintf(mStart, physical_capacity, format, ap); - va_end(ap); - } - -nsPrintfCString::nsPrintfCString( size_t n, const char* format, ... ) - : mStart(mLocalBuffer), - mLength(0) - { - va_list ap; - - // make sure there's at least |n| space - size_t logical_capacity = kLocalBufferSize; - if ( n > logical_capacity ) - { - char* nonlocal_buffer = new char[n]; - - // if we got something, use it - if ( nonlocal_buffer ) - { - mStart = nonlocal_buffer; - logical_capacity = n; - } - // else, it's the error case ... we'll use what space we have - // (since we can't throw) - } - size_t physical_capacity = logical_capacity + 1; - - va_start(ap, format); - mLength = PR_vsnprintf(mStart, physical_capacity, format, ap); - va_end(ap); - } - -nsPrintfCString::~nsPrintfCString() - { - if ( mStart != mLocalBuffer ) - delete [] mStart; - } - -PRUint32 -nsPrintfCString::Length() const - { - return mLength; - } - -#if 0 -PRBool -nsPrintfCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - aFragment.mFragmentIdentifier = this; - // fall through - case kThisFragment: - aFragment.mStart = mStart; - aFragment.mEnd = mStart + mLength; - return PR_TRUE; - - default: - return PR_FALSE; - } - } -#else -const char* -nsPrintfCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mStart) + mLength; - return mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } -#endif - diff --git a/xpcom/ds/nsPrintfCString.h b/xpcom/ds/nsPrintfCString.h deleted file mode 100755 index e434c8c8230f..000000000000 --- a/xpcom/ds/nsPrintfCString.h +++ /dev/null @@ -1,93 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Original Author: - * Scott Collins - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#ifndef nsPrintfCString_h___ -#define nsPrintfCString_h___ - -#include "nsAWritableString.h" - - - /** - * |nsPrintfCString| lets you use a formated |printf| string as an |nsAReadableCString|. - * - * myCStr += nsPrintfCString("%f", 13.917); - * // ...a general purpose substitute for |AppendFloat| - * - * For longer patterns, you'll want to use the constructor that takes a length - * - * nsPrintfCString(128, "%f, %f, %f, %f, %f, %f, %f, %i, %f", x, y, z, 3.2, j, k, l, 3, 3.1); - * - * Exceding the default size (which you must specify in the constructor, it is not determined) - * causes an allocation, so avoid that. If your formatted string exceeds the allocated space, it is - * cut off at the size of the buffer, no error is reported (and no out-of-bounds writing occurs). - * This class is intended to be useful for numbers and short - * strings, not arbitrary formatting of other strings (e.g., with %s). There is currently no - * wide version of this class, since wide |printf| is not generally available. That means - * to get a wide version of your formatted data, you must, e.g., - * - * CopyASCIItoUCS2(nsPrintfCString("%f", 13.917"), myStr); - * - * That's another good reason to avoid this class for anything but numbers ... as strings can be - * much more efficiently handled with |NS_LITERAL_[C]STRING| and |nsLiteral[C]String|. - */ - -class nsPrintfCString - : public nsAReadableCString - { - enum { kLocalBufferSize=15 }; - // ought to be large enough for most things ... a |long long| needs at most 20 (so you'd better ask) - // pinkerton suggests 7. We should measure and decide what's appropriate - - - public: - explicit nsPrintfCString( const char* format, ... ); - nsPrintfCString( size_t n, const char* format, ...); - ~nsPrintfCString(); - - virtual PRUint32 Length() const; - - protected: - virtual const char* GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const; -// virtual PRBool GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest ) const; - - private: - char* mStart; - PRUint32 mLength; - char mLocalBuffer[ kLocalBufferSize + 1 ]; - }; - -#endif // !defined(nsPrintfCString_h___) diff --git a/xpcom/ds/nsPrivateSharableString.h b/xpcom/ds/nsPrivateSharableString.h deleted file mode 100755 index 14cd13865103..000000000000 --- a/xpcom/ds/nsPrivateSharableString.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsPrivateSharableString_h___ -#define nsPrivateSharableString_h___ - -#ifndef nsBufferHandle_h___ -#include "nsBufferHandle.h" -#endif - - /** - * This class is (will be) part of the machinery that makes - * most string implementations in this family share their underlying buffers - * when convenient. It is _not_ part of the abstract string interface, - * though other machinery interested in sharing buffers will know about it. - */ -template -class nsPrivateSharableString - { - public: - virtual const nsBufferHandle* GetBufferHandle() const; - virtual const nsSharedBufferHandle* GetSharedBufferHandle() const; - }; - -template -const nsSharedBufferHandle* -nsPrivateSharableString::GetSharedBufferHandle() const - { - return 0; - } - -template -const nsBufferHandle* -nsPrivateSharableString::GetBufferHandle() const - { - return GetSharedBufferHandle(); - } - -#endif // !defined(nsPrivateSharableString_h___) diff --git a/xpcom/ds/nsReadableUtils.cpp b/xpcom/ds/nsReadableUtils.cpp deleted file mode 100755 index e05326fcc4b7..000000000000 --- a/xpcom/ds/nsReadableUtils.cpp +++ /dev/null @@ -1,593 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - */ - -#include "nsReadableUtils.h" -#include "nsMemory.h" -#include "nsString.h" -#include "nsCRT.h" - - -template class CalculateLength - { - public: - typedef CharT value_type; - - CalculateLength() : mDistance(0) { } - size_t GetDistance() const { return mDistance; } - - PRUint32 write( const CharT*, PRUint32 N ) - { mDistance += N; return N; } - private: - size_t mDistance; - }; - -template -inline -size_t -Distance_Impl( const nsReadingIterator& aStart, - const nsReadingIterator& aEnd ) - { - CalculateLength sink; - nsReadingIterator fromBegin(aStart); - copy_string(fromBegin, aEnd, sink); - return sink.GetDistance(); - } - -NS_COM -size_t -Distance( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return Distance_Impl(aStart, aEnd); - } - -NS_COM -size_t -Distance( const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - return Distance_Impl(aStart, aEnd); - } - - - - /** - * A character sink that performs a |reinterpret_cast| style conversion between character types. - */ -template -class LossyConvertEncoding - { - public: - typedef FromCharT value_type; - - typedef FromCharT input_type; - typedef ToCharT output_type; - - public: - LossyConvertEncoding( output_type* aDestination ) : mDestination(aDestination) { } - - PRUint32 - write( const input_type* aSource, PRUint32 aSourceLength ) - { - const input_type* done_writing = aSource + aSourceLength; - while ( aSource < done_writing ) - *mDestination++ = (output_type)(*aSource++); // use old-style cast to mimic old |ns[C]String| behavior - return aSourceLength; - } - - void - write_terminator() - { - *mDestination = output_type(0); - } - - private: - output_type* mDestination; - }; - - -NS_COM -void -CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ) - { - // right now, this won't work on multi-fragment destinations - aDest.SetLength(aSource.Length()); - - nsReadingIterator fromBegin, fromEnd; - - nsWritingIterator toBegin; - LossyConvertEncoding converter(aDest.BeginWriting(toBegin).get()); - - copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter); - } - -NS_COM -void -CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ) - { - // right now, this won't work on multi-fragment destinations - aDest.SetLength(aSource.Length()); - - nsReadingIterator fromBegin, fromEnd; - - nsWritingIterator toBegin; - LossyConvertEncoding converter(aDest.BeginWriting(toBegin).get()); - - copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter); - } - - - /** - * A helper function that allocates a buffer of the desired character type big enough to hold a copy of the supplied string (plus a zero terminator). - * - * @param aSource an string you will eventually be making a copy of - * @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|. - * - */ -template -inline -ToCharT* -AllocateStringCopy( const basic_nsAReadableString& aSource, ToCharT* ) - { - return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT))); - } - - -NS_COM -char* -ToNewCString( const nsAReadableString& aSource ) - { - char* result = AllocateStringCopy(aSource, (char*)0); - - nsReadingIterator fromBegin, fromEnd; - LossyConvertEncoding converter(result); - copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); - return result; - } - -NS_COM -char* -ToNewUTF8String( const nsAReadableString& aSource ) - { - NS_ConvertUCS2toUTF8 temp(aSource); - - char* result; - if (temp.mOwnsBuffer) { - // We allocated. Trick the string into not freeing its buffer to - // avoid an extra allocation. - result = temp.mStr; - - temp.mStr=0; - temp.mOwnsBuffer = PR_FALSE; - } - else { - // We didn't allocate a buffer, so we need to copy it out of the - // nsCAutoString's storage. - result = nsCRT::strdup(temp.mStr); - } - - return result; - } - -NS_COM -char* -ToNewCString( const nsAReadableCString& aSource ) - { - // no conversion needed, just allocate a buffer of the correct length and copy into it - - char* result = AllocateStringCopy(aSource, (char*)0); - - nsReadingIterator fromBegin, fromEnd; - char* toBegin = result; - *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = char(0); - return result; - } - -NS_COM -PRUnichar* -ToNewUnicode( const nsAReadableString& aSource ) - { - // no conversion needed, just allocate a buffer of the correct length and copy into it - - PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - - nsReadingIterator fromBegin, fromEnd; - PRUnichar* toBegin = result; - *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = PRUnichar(0); - return result; - } - -NS_COM -PRUnichar* -ToNewUnicode( const nsAReadableCString& aSource ) - { - PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0); - - nsReadingIterator fromBegin, fromEnd; - LossyConvertEncoding converter(result); - copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator(); - return result; - } - -NS_COM -PRUnichar* -CopyUnicodeTo( const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength ) - { - nsReadingIterator fromBegin, fromEnd; - PRUnichar* toBegin = aDest; - copy_string(aSource.BeginReading(fromBegin).advance( PRInt32(aSrcOffset) ), aSource.BeginReading(fromEnd).advance( PRInt32(aSrcOffset+aLength) ), toBegin); - return aDest; - } - -NS_COM -void -CopyUnicodeTo( const nsReadingIterator& aSrcStart, - const nsReadingIterator& aSrcEnd, - nsAWritableString& aDest ) - { - nsWritingIterator writer; - aDest.SetLength(Distance(aSrcStart, aSrcEnd)); - aDest.BeginWriting(writer); - nsReadingIterator fromBegin(aSrcStart); - - copy_string(fromBegin, aSrcEnd, writer); - } - -NS_COM -void -AppendUnicodeTo( const nsReadingIterator& aSrcStart, - const nsReadingIterator& aSrcEnd, - nsAWritableString& aDest ) - { - nsWritingIterator writer; - PRUint32 oldLength = aDest.Length(); - aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd)); - aDest.BeginWriting(writer).advance(oldLength); - nsReadingIterator fromBegin(aSrcStart); - - copy_string(fromBegin, aSrcEnd, writer); - } - -NS_COM -PRBool -IsASCII( const nsAReadableString& aString ) - { - static const PRUnichar NOT_ASCII = PRUnichar(~0x007F); - - - // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character - - nsReadingIterator done_reading; - aString.EndReading(done_reading); - - // for each chunk of |aString|... - PRUint32 fragmentLength = 0; - nsReadingIterator iter; - for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) ) - { - fragmentLength = PRUint32(iter.size_forward()); - const PRUnichar* c = iter.get(); - const PRUnichar* fragmentEnd = c + fragmentLength; - - // for each character in this chunk... - while ( c < fragmentEnd ) - if ( *c++ & NOT_ASCII ) - return PR_FALSE; - } - - return PR_TRUE; - } - - - - /** - * A character sink for case conversion. - */ -template -class ConvertToUpperCase - { - public: - typedef CharT value_type; - - PRUint32 - write( const CharT* aSource, PRUint32 aSourceLength ) - { - for ( PRUint32 i=0; i converter; - copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter); - } - -NS_COM -void -ToUpperCase( nsAWritableCString& aCString ) - { - nsAWritableCString::iterator fromBegin, fromEnd; - ConvertToUpperCase converter; - copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter); - } - - - /** - * A character sink for case conversion. - */ -template -class ConvertToLowerCase - { - public: - typedef CharT value_type; - - PRUint32 - write( const CharT* aSource, PRUint32 aSourceLength ) - { - for ( PRUint32 i=0; i converter; - copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter); - } - -NS_COM -void -ToLowerCase( nsAWritableCString& aCString ) - { - nsAWritableCString::iterator fromBegin, fromEnd; - ConvertToLowerCase converter; - copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter); - } - - -template -inline // probably wishful thinking -PRBool -FindInReadable_Impl( const basic_nsAReadableString& aPattern, - nsReadingIterator& aSearchStart, - nsReadingIterator& aSearchEnd ) - { - PRBool found_it = PR_FALSE; - - // only bother searching at all if we're given a non-empty range to search - if ( aSearchStart != aSearchEnd ) - { - nsReadingIterator aPatternStart, aPatternEnd; - aPattern.BeginReading(aPatternStart); - aPattern.EndReading(aPatternEnd); - - // outer loop keeps searching till we find it or run out of string to search - while ( !found_it ) - { - // fast inner loop (that's what it's called, not what it is) looks for a potential match - while ( aSearchStart != aSearchEnd && *aPatternStart != *aSearchStart ) - ++aSearchStart; - - // if we broke out of the `fast' loop because we're out of string ... we're done: no match - if ( aSearchStart == aSearchEnd ) - break; - - // otherwise, we're at a potential match, let's see if we really hit one - nsReadingIterator testPattern(aPatternStart); - nsReadingIterator testSearch(aSearchStart); - - // slow inner loop verifies the potential match (found by the `fast' loop) at the current position - for(;;) - { - // we already compared the first character in the outer loop, - // so we'll advance before the next comparison - ++testPattern; - ++testSearch; - - // if we verified all the way to the end of the pattern, then we found it! - if ( testPattern == aPatternEnd ) - { - found_it = PR_TRUE; - aSearchEnd = testSearch; // return the exact found range through the parameters - break; - } - - // if we got to end of the string we're searching before we hit the end of the - // pattern, we'll never find what we're looking for - if ( testSearch == aSearchEnd ) - { - aSearchStart = aSearchEnd; - break; - } - - // else if we mismatched ... it's time to advance to the next search position - // and get back into the `fast' loop - if ( *testPattern != *testSearch ) - { - ++aSearchStart; - break; - } - } - } - } - - return found_it; - } - -NS_COM -PRBool -FindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); - } - -NS_COM -PRBool -FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); - } - - /** - * This implementation is simple, but does too much work. - * It searches the entire string from left to right, and returns the last match found, if any. - * This implementation will be replaced when I get |reverse_iterator|s working. - */ -template -inline // probably wishful thinking -PRBool -RFindInReadable_Impl( const basic_nsAReadableString& aPattern, - nsReadingIterator& aSearchStart, - nsReadingIterator& aSearchEnd ) - { - PRBool found_it = PR_FALSE; - - nsReadingIterator savedSearchEnd(aSearchEnd); - nsReadingIterator searchStart(aSearchStart), searchEnd(aSearchEnd); - - while ( searchStart != searchEnd ) - { - if ( FindInReadable(aPattern, searchStart, searchEnd) ) - { - found_it = PR_TRUE; - - // this is the best match so far, so remember it - aSearchStart = searchStart; - aSearchEnd = searchEnd; - - // ...and get ready to search some more - // (it's tempting to set |searchStart=searchEnd| ... but that misses overlapping patterns) - ++searchStart; - searchEnd = savedSearchEnd; - } - } - - // if we never found it, return an empty range - if ( !found_it ) - aSearchStart = aSearchEnd; - - return found_it; - } - - -NS_COM -PRBool -RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); - } - -NS_COM -PRBool -RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return RFindInReadable_Impl(aPattern, aSearchStart, aSearchEnd); - } - - - -template -inline // probably wishful thinking -PRBool -FindCharInReadable_Impl( CharT aChar, - nsReadingIterator& aSearchStart, - nsReadingIterator& aSearchEnd ) - { - while ( aSearchStart != aSearchEnd ) - { - PRInt32 fragmentLength; - if ( SameFragment(aSearchStart, aSearchEnd) ) - fragmentLength = aSearchEnd.get() - aSearchStart.get(); - else - fragmentLength = aSearchStart.size_forward(); - - const CharT* charFoundAt = nsCharTraits::find(aSearchStart.get(), fragmentLength, aChar); - if ( charFoundAt ) { - aSearchStart.advance( charFoundAt - aSearchStart.get() ); - return PR_TRUE; - } - - aSearchStart.advance(fragmentLength); - } - - return PR_FALSE; - } - - -NS_COM -PRBool -FindCharInReadable( PRUnichar aChar, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return FindCharInReadable_Impl(aChar, aSearchStart, aSearchEnd); - } - -NS_COM -PRBool -FindCharInReadable( char aChar, nsReadingIterator& aSearchStart, nsReadingIterator& aSearchEnd ) - { - return FindCharInReadable_Impl(aChar, aSearchStart, aSearchEnd); - } - -template -PRUint32 -CountCharInReadable_Impl( const basic_nsAReadableString& aStr, - CharT aChar ) -{ - PRUint32 count = 0; - nsReadingIterator begin, end; - - aStr.BeginReading(begin); - aStr.EndReading(end); - - while (begin != end) { - if (*begin == aChar) { - count++; - } - begin++; - } - - return count; -} - -NS_COM -PRUint32 -CountCharInReadable( const nsAReadableString& aStr, - PRUnichar aChar ) -{ - return CountCharInReadable_Impl(aStr, aChar); -} - -NS_COM -PRUint32 -CountCharInReadable( const nsAReadableCString& aStr, - char aChar ) -{ - return CountCharInReadable_Impl(aStr, aChar); -} diff --git a/xpcom/ds/nsReadableUtils.h b/xpcom/ds/nsReadableUtils.h deleted file mode 100755 index 33b6c6ec2544..000000000000 --- a/xpcom/ds/nsReadableUtils.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * Johnny Stenbeck - * - */ - -#ifndef nsReadableUtils_h___ -#define nsReadableUtils_h___ - - /** - * I guess all the routines in this file are all mis-named. - * According to our conventions, they should be |NS_xxx|. - */ - -#ifndef nsAWritableString_h___ -#include "nsAWritableString.h" -#endif - -NS_COM size_t Distance( const nsReadingIterator&, const nsReadingIterator& ); -NS_COM size_t Distance( const nsReadingIterator&, const nsReadingIterator& ); - - -NS_COM void CopyUCS2toASCII( const nsAReadableString& aSource, nsAWritableCString& aDest ); -NS_COM void CopyASCIItoUCS2( const nsAReadableCString& aSource, nsAWritableString& aDest ); - - /** - * Returns a new |char| buffer containing a zero-terminated copy of |aSource|. - * - * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|. - * Performs a lossy encoding conversion by chopping 16-bit wide characters down to 8-bits wide while copying |aSource| to your new buffer. - * This conversion is not well defined; but it reproduces legacy string behavior. - * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls. - * - * @param aSource a 16-bit wide string - * @return a new |char| buffer you must free with |nsMemory::Free|. - */ -NS_COM char* ToNewCString( const nsAReadableString& aSource ); - - - /** - * Returns a new |char| buffer containing a zero-terminated copy of |aSource|. - * - * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|. - * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls. - * - * @param aSource an 8-bit wide string - * @return a new |char| buffer you must free with |nsMemory::Free|. - */ -NS_COM char* ToNewCString( const nsAReadableCString& aSource ); - - /** - * Returns a new |char| buffer containing a zero-terminated copy of |aSource|. - * - * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|. - * Performs a encoding conversion by converting 16-bit wide characters down to UTF8 encoded 8-bits wide string copying |aSource| to your new buffer. - * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls. - * - * @param aSource a 16-bit wide string - * @return a new |char| buffer you must free with |nsMemory::Free|. - */ - -NS_COM char* ToNewUTF8String( const nsAReadableString& aSource ); - - - /** - * Returns a new |PRUnichar| buffer containing a zero-terminated copy of |aSource|. - * - * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|. - * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls. - * - * @param aSource a 16-bit wide string - * @return a new |PRUnichar| buffer you must free with |nsMemory::Free|. - */ -NS_COM PRUnichar* ToNewUnicode( const nsAReadableString& aSource ); - - - /** - * Returns a new |PRUnichar| buffer containing a zero-terminated copy of |aSource|. - * - * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|. - * Performs an encoding conversion by 0-padding 8-bit wide characters up to 16-bits wide while copying |aSource| to your new buffer. - * This conversion is not well defined; but it reproduces legacy string behavior. - * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls. - * - * @param aSource an 8-bit wide string - * @return a new |PRUnichar| buffer you must free with |nsMemory::Free|. - */ -NS_COM PRUnichar* ToNewUnicode( const nsAReadableCString& aSource ); - - /** - * Copies |aLength| 16-bit characters from the start of |aSource| to the - * |PRUnichar| buffer |aDest|. - * - * After this operation |aDest| is not null terminated. - * - * @param aSource a 16-bit wide string - * @param aSrcOffset start offset in the source string - * @param aDest a |PRUnichar| buffer - * @param aLength the number of 16-bit characters to copy - * @return pointer to destination buffer - identical to |aDest| - */ -NS_COM PRUnichar* CopyUnicodeTo( const nsAReadableString& aSource, - PRUint32 aSrcOffset, - PRUnichar* aDest, - PRUint32 aLength ); - - - /** - * Copies 16-bit characters between iterators |aSrcStart| and - * |aSrcEnd| to the writable string |aDest|. Similar to the - * |nsString::Mid| method. - * - * After this operation |aDest| is not null terminated. - * - * @param aSrcStart start source iterator - * @param aSrcEnd end source iterator - * @param aDest destination for the copy - */ -NS_COM void CopyUnicodeTo( const nsReadingIterator& aSrcStart, - const nsReadingIterator& aSrcEnd, - nsAWritableString& aDest ); - - /** - * Appends 16-bit characters between iterators |aSrcStart| and - * |aSrcEnd| to the writable string |aDest|. - * - * After this operation |aDest| is not null terminated. - * - * @param aSrcStart start source iterator - * @param aSrcEnd end source iterator - * @param aDest destination for the copy - */ -NS_COM void AppendUnicodeTo( const nsReadingIterator& aSrcStart, - const nsReadingIterator& aSrcEnd, - nsAWritableString& aDest ); - - /** - * Returns |PR_TRUE| if |aString| contains only ASCII characters, that is, characters in the range (0x00, 0x7F). - * - * @param aString a 16-bit wide string to scan - */ -NS_COM PRBool IsASCII( const nsAReadableString& aString ); - - - - /** - * Converts case in place in the argument string. - */ -NS_COM void ToUpperCase( nsAWritableString& ); -NS_COM void ToUpperCase( nsAWritableCString& ); - -NS_COM void ToLowerCase( nsAWritableString& ); -NS_COM void ToLowerCase( nsAWritableCString& ); - - /** - * Finds the leftmost occurance of |aPattern|, if any in the range |aSearchStart|..|aSearchEnd|. - * - * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to - * point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|. - * - * Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|. - * If we need something faster; we can implement that later. - */ -NS_COM PRBool FindInReadable( const nsAReadableString& aPattern, nsReadingIterator&, nsReadingIterator& ); -NS_COM PRBool FindInReadable( const nsAReadableCString& aPattern, nsReadingIterator&, nsReadingIterator& ); - - - /** - * Finds the rightmost occurance of |aPattern| - * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to - * point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|. - * - * Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|. - * If we need something faster; we can implement that later. - */ -NS_COM PRBool RFindInReadable( const nsAReadableString& aPattern, nsReadingIterator&, nsReadingIterator& ); -NS_COM PRBool RFindInReadable( const nsAReadableCString& aPattern, nsReadingIterator&, nsReadingIterator& ); - - /** - * Finds the leftmost occurance of |aChar|, if any in the range - * |aSearchStart|..|aSearchEnd|. - * - * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| to - * point to the match. If no match was found, returns |PR_FALSE| and - * makes |aSearchStart == aSearchEnd|. - */ -NS_COM PRBool FindCharInReadable( PRUnichar aChar, nsReadingIterator&, nsReadingIterator& ); -NS_COM PRBool FindCharInReadable( char aChar, nsReadingIterator&, nsReadingIterator& ); - - /** - * Finds the number of occurences of |aChar| in the string |aStr| - */ -NS_COM PRUint32 CountCharInReadable( const nsAReadableString& aStr, - PRUnichar aChar ); -NS_COM PRUint32 CountCharInReadable( const nsAReadableCString& aStr, - char aChar ); - -#endif // !defined(nsReadableUtils_h___) diff --git a/xpcom/ds/nsSharedBufferList.cpp b/xpcom/ds/nsSharedBufferList.cpp deleted file mode 100755 index f6f570fd88e4..000000000000 --- a/xpcom/ds/nsSharedBufferList.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#include "nsSharedBufferList.h" - -#ifndef nsAlgorithm_h___ -#include "nsAlgorithm.h" - // for |copy_string| -#endif - - -ptrdiff_t -nsSharedBufferList::Position::Distance( const Position& aStart, const Position& aEnd ) - { - ptrdiff_t result = 0; - if ( aStart.mBuffer == aEnd.mBuffer ) - result = aEnd.mPosInBuffer - aStart.mPosInBuffer; - else - { - result = aStart.mBuffer->DataEnd() - aStart.mPosInBuffer; - for ( Buffer* b = aStart.mBuffer->mNext; b != aEnd.mBuffer; b = b->mNext ) - result += b->DataLength(); - result += aEnd.mPosInBuffer - aEnd.mBuffer->DataStart(); - } - - return result; - } - - -void -nsSharedBufferList::DestroyBuffers() - { - // destroy the entire list of buffers, without bothering to manage their links - Buffer* next_buffer; - for ( Buffer* cur_buffer=mFirstBuffer; cur_buffer; cur_buffer=next_buffer ) - { - next_buffer = cur_buffer->mNext; - operator delete(cur_buffer); - } - mFirstBuffer = mLastBuffer = 0; - mTotalDataLength = 0; - } - -nsSharedBufferList::~nsSharedBufferList() - { - DestroyBuffers(); - } - - - -void -nsSharedBufferList::LinkBuffer( Buffer* aPrevBuffer, Buffer* aNewBuffer, Buffer* aNextBuffer ) - { - NS_ASSERTION(aNewBuffer, "aNewBuffer"); - NS_ASSERTION(aPrevBuffer || mFirstBuffer == aNextBuffer, "aPrevBuffer || mFirstBuffer == aNextBuffer"); - NS_ASSERTION(!aPrevBuffer || aPrevBuffer->mNext == aNextBuffer, "!aPrevBuffer || aPrevBuffer->mNext == aNextBuffer"); - NS_ASSERTION(aNextBuffer || mLastBuffer == aPrevBuffer, "aNextBuffer || mLastBuffer == aPrevBuffer"); - NS_ASSERTION(!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer, "!aNextBuffer || aNextBuffer->mPrev == aPrevBuffer"); - - if ( (aNewBuffer->mPrev = aPrevBuffer) ) - aPrevBuffer->mNext = aNewBuffer; - else - mFirstBuffer = aNewBuffer; - - if ( (aNewBuffer->mNext = aNextBuffer) ) - aNextBuffer->mPrev = aNewBuffer; - else - mLastBuffer = aNewBuffer; - - mTotalDataLength += aNewBuffer->DataLength(); - } - -void -nsSharedBufferList::SplitBuffer( const Position& aSplitPosition, SplitDisposition aSplitDirection ) - { - Buffer* bufferToSplit = aSplitPosition.mBuffer; - - NS_ASSERTION(bufferToSplit, "bufferToSplit"); - - ptrdiff_t splitOffset = aSplitPosition.mPosInBuffer - bufferToSplit->DataStart(); - - NS_ASSERTION(0 <= splitOffset && splitOffset <= bufferToSplit->DataLength(), "|splitOffset| within buffer"); - - // if the caller specifically asked to split off the right side of the buffer-to-be-split - // or else if they asked for the minimum amount of work, and that turned out to be the right side... - ptrdiff_t savedLength = mTotalDataLength; - if ( aSplitDirection==kSplitCopyRightData || - ( aSplitDirection==kSplitCopyLeastData && ((bufferToSplit->DataLength() >> 1) <= splitOffset) ) ) - { - // ...then allocate a new buffer initializing it by copying all the data _after_ the split in the source buffer (i.e., `split right') - Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart()+splitOffset, PRUint32(bufferToSplit->DataLength()-splitOffset)); - LinkBuffer(bufferToSplit, new_buffer, bufferToSplit->mNext); - bufferToSplit->DataEnd(aSplitPosition.mPosInBuffer); - } - else - { - // ...else move the data _before_ the split point (i.e., `split left') - Buffer* new_buffer = NewSingleAllocationBuffer(bufferToSplit->DataStart(), PRUint32(splitOffset)); - LinkBuffer(bufferToSplit->mPrev, new_buffer, bufferToSplit); - bufferToSplit->DataStart(aSplitPosition.mPosInBuffer); - } - mTotalDataLength = savedLength; - // duh! splitting a buffer doesn't change the length. - } - - -nsSharedBufferList::Buffer* -nsSharedBufferList::UnlinkBuffer( Buffer* aBufferToUnlink ) - { - NS_ASSERTION(aBufferToUnlink, "aBufferToUnlink"); - - Buffer* prev_buffer = aBufferToUnlink->mPrev; - Buffer* next_buffer = aBufferToUnlink->mNext; - - if ( prev_buffer ) - prev_buffer->mNext = next_buffer; - else - mFirstBuffer = next_buffer; - - if ( next_buffer ) - next_buffer->mPrev = prev_buffer; - else - mLastBuffer = prev_buffer; - - mTotalDataLength -= aBufferToUnlink->DataLength(); - - return aBufferToUnlink; - } - - -void -nsSharedBufferList::DiscardSuffix( PRUint32 /* aLengthToDiscard */ ) - { - // XXX - } - - - -#if 0 -template -void -nsChunkList::CutTrailingData( PRUint32 aLengthToCut ) - { - Chunk* chunk = mLastChunk; - while ( chunk && aLengthToCut ) - { - Chunk* prev_chunk = chunk->mPrev; - if ( aLengthToCut < chunk->mDataLength ) - { - chunk->mDataLength -= aLengthToCut; - aLengthToCut = 0; - } - else - { - RemoveChunk(chunk); - aLengthToCut -= chunk->mDataLength; - operator delete(chunk); - } - - chunk = prev_chunk; - } - } -#endif diff --git a/xpcom/ds/nsSharedBufferList.h b/xpcom/ds/nsSharedBufferList.h deleted file mode 100755 index a97c2af1ec60..000000000000 --- a/xpcom/ds/nsSharedBufferList.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsSharedBufferList_h___ -#define nsSharedBufferList_h___ - -#ifndef nsBufferHandle_h___ -#include "nsBufferHandle.h" - // for |nsSharedBufferHandle| -#endif - -#ifndef nscore_h___ -#include "nscore.h" - // for |PRUnichar| -#endif - -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" - // for |nsReadingIterator| -#endif - -#ifndef nsBufferHandleUtils_h___ -#include "nsBufferHandleUtils.h" - // for |NS_AllocateContiguousHandleWithData| -#endif - - - /** - * This class forms the basis for several multi-fragment string classes, in - * particular: |nsFragmentedString| (though not yet), and |nsSlidingString|/|nsSlidingSubstring|. - * - * This class is not templated. It is provided only for |PRUnichar|-based strings. - * If we turn out to have a need for multi-fragment ASCII strings, then perhaps we'll templatize - * or else duplicate this class. - */ -class NS_COM nsSharedBufferList - { - public: - - class Buffer - : public nsFlexBufferHandle - { - public: - Buffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageStart, PRUnichar* aStorageEnd, PRBool aIsSingleAllocation=PR_FALSE ) - : nsFlexBufferHandle(aDataStart, aDataEnd, aStorageStart, aStorageEnd) - { - if ( aIsSingleAllocation ) - this->mFlags |= this->kIsSingleAllocationWithBuffer; - } - - /** - * These buffers will be `owned' by the list, and only the - * the list itself will be allowed to delete member |Buffer|s, - * therefore, we cannot use the inherited |AcquireReference| - * and |ReleaseReference|, as they use the model that the - * buffer manages its own lifetime. - */ - void - AcquireNonOwningReference() const - { - Buffer* mutable_this = NS_CONST_CAST(Buffer*, this); - mutable_this->set_refcount( get_refcount()+1 ); - } - - void - ReleaseNonOwningReference() const - { - Buffer* mutable_this = NS_CONST_CAST(Buffer*, this); - mutable_this->set_refcount( get_refcount()-1 ); - } - - Buffer* mPrev; - Buffer* mNext; - - private: - // pass-by-value is explicitly denied - Buffer( const Buffer& ); // NOT TO BE IMPLEMENTED - void operator=( const Buffer& ); // NOT TO BE IMPLEMENTED - }; - - struct Position - { - Buffer* mBuffer; - PRUnichar* mPosInBuffer; - - Position() { } - Position( Buffer* aBuffer, PRUnichar* aPosInBuffer ) : mBuffer(aBuffer), mPosInBuffer(aPosInBuffer) { } - - // Position( const Position& ); -- auto-generated copy-constructor OK - // Position& operator=( const Position& ); -- auto-generated copy-assignment OK - // ~Position(); -- auto-generated destructor OK - - // iff |aIter| is a valid iterator into a |nsSharedBufferList| - explicit - Position( const nsReadingIterator& aIter ) - : mBuffer( NS_CONST_CAST(Buffer*, NS_REINTERPRET_CAST(const Buffer*, aIter.fragment().mFragmentIdentifier)) ), - mPosInBuffer( NS_CONST_CAST(PRUnichar*, aIter.get()) ) - { - // nothing else to do here - } - - // iff |aIter| is a valid iterator into a |nsSharedBufferList| - Position& - operator=( const nsReadingIterator& aIter ) - { - mBuffer = NS_CONST_CAST(Buffer*, NS_REINTERPRET_CAST(const Buffer*, aIter.fragment().mFragmentIdentifier)); - mPosInBuffer = NS_CONST_CAST(PRUnichar*, aIter.get()); - return *this; - } - - void PointTo( Buffer* aBuffer, PRUnichar* aPosInBuffer ) { mBuffer=aBuffer; mPosInBuffer=aPosInBuffer; } - void PointBefore( Buffer* aBuffer ) { PointTo(aBuffer, aBuffer->DataStart()); } - void PointAfter( Buffer* aBuffer ) { PointTo(aBuffer, aBuffer->DataEnd()); } - - // Position( const Position& ); -- automatically generated copy-constructor is OK - // Position& operator=( const Position& ); -- automatically generated copy-assignment operator is OK - - // don't want to provide this as |operator-|, since that might imply O(1) - static ptrdiff_t Distance( const Position&, const Position& ); - }; - - - - public: - nsSharedBufferList( Buffer* aBuffer = 0 ) - : mFirstBuffer(aBuffer), - mLastBuffer(aBuffer), - mTotalDataLength(0) - { - if ( aBuffer ) - { - aBuffer->mPrev = aBuffer->mNext = 0; - mTotalDataLength = aBuffer->DataLength(); - } - } - - virtual ~nsSharedBufferList(); - - private: - // pass-by-value is explicitly denied - nsSharedBufferList( const nsSharedBufferList& ); // NOT TO BE IMPLEMENTED - void operator=( const nsSharedBufferList& ); // NOT TO BE IMPLEMENTED - - public: - void LinkBuffer( Buffer*, Buffer*, Buffer* ); - Buffer* UnlinkBuffer( Buffer* ); - - enum SplitDisposition // when splitting a buffer in two... - { - kSplitCopyRightData, // copy the data right of the split point to a new buffer - kSplitCopyLeastData, // copy the smaller amount of data to the new buffer - kSplitCopyLeftData // copy the data left of the split point to a new buffer - }; - - void SplitBuffer( const Position&, SplitDisposition = kSplitCopyLeastData ); - - static - Buffer* - NewSingleAllocationBuffer( const PRUnichar* aData, PRUint32 aDataLength, PRUint32 aAdditionalCapacity = 1 ) - { - typedef Buffer* Buffer_ptr; - return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), NS_READABLE_CAST(PRUnichar, nsLiteralString(aData, aDataLength)), aAdditionalCapacity); - } - - static - Buffer* - NewSingleAllocationBuffer( const nsAReadableString& aReadable, PRUint32 aAdditionalCapacity = 1 ) - { - typedef Buffer* Buffer_ptr; - return NS_AllocateContiguousHandleWithData(Buffer_ptr(0), aReadable, aAdditionalCapacity); - } - - static - Buffer* - NewWrappingBuffer( PRUnichar* aDataStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ) - { - return new Buffer(aDataStart, aDataEnd, aDataStart, aStorageEnd); - } - - void DiscardSuffix( PRUint32 ); - // need other discards: prefix, and by iterator or pointer or something - - Buffer* GetFirstBuffer() { return mFirstBuffer; } - const Buffer* GetFirstBuffer() const { return mFirstBuffer; } - - Buffer* GetLastBuffer() { return mLastBuffer; } - const Buffer* GetLastBuffer() const { return mLastBuffer; } - - ptrdiff_t GetDataLength() const { return mTotalDataLength; } - - protected: - void DestroyBuffers(); - - protected: - Buffer* mFirstBuffer; - Buffer* mLastBuffer; - ptrdiff_t mTotalDataLength; - }; - -#endif // !defined(nsSharedBufferList_h___) diff --git a/xpcom/ds/nsSharedString.h b/xpcom/ds/nsSharedString.h deleted file mode 100644 index b94fd4a02b07..000000000000 --- a/xpcom/ds/nsSharedString.h +++ /dev/null @@ -1,203 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Original Author: - * Scott Collins - * - * Contributor(s): - */ - -#ifndef nsSharedString_h___ -#define nsSharedString_h___ - -#ifndef nsAReadableString_h___ -#include "nsAReadableString.h" -#endif - -template -class basic_nsSharedString - : public basic_nsAReadableString - /* - ... - */ - { - public: - basic_nsSharedString( const CharT* data, size_t length ) - : mRefCount(0), mData(data), mLength(length) - { - // nothing else to do here - } - - private: - ~basic_nsSharedString() { } // You can't sub-class me, or make an instance of me on the stack - - // NOT TO BE IMPLEMENTED - // we're reference counted, remember. copying and passing by value are wrong - // basic_nsSharedString(); // we define at least one constructor, so the default constructor will not be auto-generated. It's wrong to create me with no data anyway - basic_nsSharedString( const basic_nsSharedString& ); // copy-constructor, the auto generated one would reference somebody elses data - void operator=( const basic_nsSharedString& ); // copy-assignment operator - - // operator delete? - - public: - - virtual const CharT* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - virtual - PRUint32 - Length() const - { - return mLength; - } - - nsrefcnt - AddRef() const - { - return ++mRefCount; - } - - nsrefcnt - Release() const - { - nsrefcnt result = --mRefCount; - if ( !mRefCount ) - { - // would have to call my destructor by hand here, if there was anything to destruct - operator delete(this); // form of |delete| should always match the |new| - } - return result; - } - - private: - mutable nsrefcnt mRefCount; - const CharT* mData; - size_t mLength; - }; - -NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsSharedString, CharT) - -template -const CharT* -basic_nsSharedString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 anOffset ) const - { - switch ( aRequest ) - { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mData) + mLength; - return aFragment.mStart + anOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } - } - - - -template -class basic_nsSharedStringPtr - { - public: - // default constructor - basic_nsSharedStringPtr() : mRawPtr(0) { } - - // copy-constructor - basic_nsSharedStringPtr( const basic_nsSharedStringPtr& rhs ) - : mRawPtr(rhs.mRawPtr) - { - mRawPtr->AddRef(); - } - - ~basic_nsSharedStringPtr() - { - if ( mRawPtr ) - mRawPtr->Release(); - } - - // copy-assignment operator - basic_nsSharedStringPtr& - operator=( const basic_nsSharedStringPtr& ); - - basic_nsSharedString* - operator->() const - { - NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL string pointer with operator->()."); - return mRawPtr; - } - - basic_nsSharedString& - operator*() const - { - NS_PRECONDITION(mRawPtr != 0, "You can't dereference a NULL string pointer with operator->()."); - return *mRawPtr; - } - - private: - const basic_nsSharedString* mRawPtr; - }; - -template -basic_nsSharedStringPtr& -basic_nsSharedStringPtr::operator=( const basic_nsSharedStringPtr& rhs ) - // Not |inline| - { - if ( rhs.mRawPtr ) - rhs.mRawPtr->AddRef(); - basic_nsSharedString* oldPtr = mRawPtr; - mRawPtr = rhs.mRawPtr; - if ( oldPtr ) - oldPtr->Release(); - } - - -template -basic_nsSharedString* -new_nsSharedString( const basic_nsAReadableString& aReadable ) - { - size_t object_size = ((sizeof(basic_nsSharedString) + sizeof(CharT) - 1) / sizeof(CharT)) * sizeof(CharT); - size_t string_length = aReadable.Length(); - size_t string_size = string_length * sizeof(CharT); - - void* object_ptr = operator new(object_size + string_size); - if ( object_ptr ) - { - typedef CharT* CharT_ptr; - CharT* string_ptr = CharT_ptr(NS_STATIC_CAST(unsigned char*, object_ptr) + object_size); - - nsReadingIterator fromBegin, fromEnd; - CharT* toBegin = string_ptr; - copy_string(aReadable.BeginReading(fromBegin), aReadable.EndReading(fromEnd), toBegin); - return new (object_ptr) basic_nsSharedString(string_ptr, string_length); - } - - return 0; - } - - -typedef basic_nsSharedString nsSharedString; -typedef basic_nsSharedString nsSharedCString; - -typedef basic_nsSharedStringPtr nsSharedStringPtr; -typedef basic_nsSharedStringPtr nsSharedCStringPtr; - - -#endif // !defined(nsSharedString_h___) diff --git a/xpcom/ds/nsSlidingString.cpp b/xpcom/ds/nsSlidingString.cpp deleted file mode 100755 index f574779c281b..000000000000 --- a/xpcom/ds/nsSlidingString.cpp +++ /dev/null @@ -1,338 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#include "nsSlidingString.h" - -#ifndef nsBufferHandleUtils_h___ -#include "nsBufferHandleUtils.h" -#endif - -#include - - - - /** - * |nsSlidingSharedBufferList| - */ - -void -nsSlidingSharedBufferList::DiscardUnreferencedPrefix( Buffer* aRecentlyReleasedBuffer ) - { - if ( aRecentlyReleasedBuffer == mFirstBuffer ) - { - while ( mFirstBuffer && !mFirstBuffer->IsReferenced() ) - delete UnlinkBuffer(mFirstBuffer); - } - } - - - - /** - * |nsSlidingSubstring| - */ - - // copy constructor -nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString ) - : mStart(aString.mStart), - mEnd(aString.mEnd), - mBufferList(aString.mBufferList), - mLength(aString.mLength) - { - acquire_ownership_of_buffer_list(); - } - -nsSlidingSubstring::nsSlidingSubstring( const nsSlidingSubstring& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - : mStart(aStart), - mEnd(aEnd), - mBufferList(aString.mBufferList), - mLength(PRUint32(Position::Distance(mStart, mEnd))) - { - acquire_ownership_of_buffer_list(); - } - -nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString ) - : mStart(aString.mStart), - mEnd(aString.mEnd), - mBufferList(aString.mBufferList), - mLength(aString.mLength) - { - acquire_ownership_of_buffer_list(); - } - -nsSlidingSubstring::nsSlidingSubstring( const nsSlidingString& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - : mStart(aStart), - mEnd(aEnd), - mBufferList(aString.mBufferList), - mLength(PRUint32(Position::Distance(mStart, mEnd))) - { - acquire_ownership_of_buffer_list(); - } - -nsSlidingSubstring::nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList ) - : mBufferList(aBufferList) - { - init_range_from_buffer_list(); - acquire_ownership_of_buffer_list(); - } - -typedef const nsSharedBufferList::Buffer* Buffer_ptr; - -static nsSharedBufferList::Buffer* -AllocateContiguousHandleWithData( Buffer_ptr aDummyHandlePtr, const nsAReadableString& aDataSource ) - { - typedef const PRUnichar* PRUnichar_ptr; - - // figure out the number of bytes needed the |HandleT| part, including padding to correctly align the data part - size_t handle_size = NS_AlignedHandleSize(aDummyHandlePtr, PRUnichar_ptr(0)); - - // figure out how many |CharT|s wee need to fit in the data part - size_t string_length = aDataSource.Length(); - - // how many bytes is that (including a zero-terminator so we can claim to be flat)? - size_t string_size = (string_length+1) * sizeof(PRUnichar); - - - nsSharedBufferList::Buffer* result = 0; - void* handle_ptr = ::operator new(handle_size + string_size); - - if ( handle_ptr ) - { - typedef PRUnichar* PRUnichar_ptr; - PRUnichar* string_start_ptr = PRUnichar_ptr(NS_STATIC_CAST(unsigned char*, handle_ptr) + handle_size); - PRUnichar* string_end_ptr = string_start_ptr + string_length; - - nsReadingIterator fromBegin, fromEnd; - PRUnichar* toBegin = string_start_ptr; - copy_string(aDataSource.BeginReading(fromBegin), aDataSource.EndReading(fromEnd), toBegin); - result = new (handle_ptr) nsSharedBufferList::Buffer(string_start_ptr, string_end_ptr, string_start_ptr, string_end_ptr+1, PR_TRUE); - } - - return result; - } - -nsSlidingSubstring::nsSlidingSubstring( const nsAReadableString& aSourceString ) - : mBufferList(new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString))) - { - init_range_from_buffer_list(); - acquire_ownership_of_buffer_list(); - } - -void -nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString ) - { - aString.acquire_ownership_of_buffer_list(); - release_ownership_of_buffer_list(); - - mStart = aString.mStart; - mEnd = aString.mEnd; - mBufferList = aString.mBufferList; - mLength = aString.mLength; - } - -void -nsSlidingSubstring::Rebind( const nsSlidingSubstring& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - release_ownership_of_buffer_list(); - - mStart = aStart; - mEnd = aEnd; - mBufferList = aString.mBufferList; - mLength = PRUint32(Position::Distance(mStart, mEnd)); - - acquire_ownership_of_buffer_list(); - } - -void -nsSlidingSubstring::Rebind( const nsSlidingString& aString ) - { - aString.acquire_ownership_of_buffer_list(); - release_ownership_of_buffer_list(); - - mStart = aString.mStart; - mEnd = aString.mEnd; - mBufferList = aString.mBufferList; - mLength = aString.mLength; - } - -void -nsSlidingSubstring::Rebind( const nsSlidingString& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ) - { - release_ownership_of_buffer_list(); - - mStart = aStart; - mEnd = aEnd; - mBufferList = aString.mBufferList; - mLength = PRUint32(Position::Distance(mStart, mEnd)); - - acquire_ownership_of_buffer_list(); - } - -void -nsSlidingSubstring::Rebind( const nsAReadableString& aSourceString ) - { - release_ownership_of_buffer_list(); - mBufferList = new nsSlidingSharedBufferList(AllocateContiguousHandleWithData(Buffer_ptr(0), aSourceString)); - init_range_from_buffer_list(); - acquire_ownership_of_buffer_list(); - } - -nsSlidingSubstring::~nsSlidingSubstring() - { - release_ownership_of_buffer_list(); - } - -const PRUnichar* -nsSlidingSubstring::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - const Buffer* result_buffer = 0; - switch ( aRequest ) - { - case kPrevFragment: - { - const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier); - if ( current_buffer != mStart.mBuffer ) - result_buffer = current_buffer->mPrev; - } - break; - - case kFirstFragment: - result_buffer = mStart.mBuffer; - break; - - case kLastFragment: - result_buffer = mEnd.mBuffer; - break; - - case kNextFragment: - { - const Buffer* current_buffer = NS_STATIC_CAST(const Buffer*, aFragment.mFragmentIdentifier); - if ( current_buffer != mEnd.mBuffer ) - result_buffer = current_buffer->mNext; - } - break; - - case kFragmentAt: - { - // kFragmentAt is going away; we hate this linear search - - PRUint32 N; - result_buffer = mStart.mBuffer; - - while ( result_buffer && (N = PRUint32(result_buffer->DataLength())) < aOffset ) - { - aOffset -= N; - result_buffer = result_buffer->mNext; - } - } - break; - } - - if ( result_buffer ) - { - if ( result_buffer == mStart.mBuffer ) - aFragment.mStart = mStart.mPosInBuffer; - else - aFragment.mStart = result_buffer->DataStart(); - - if ( result_buffer == mEnd.mBuffer ) - aFragment.mEnd = mEnd.mPosInBuffer; - else - aFragment.mEnd = result_buffer->DataEnd(); - - aFragment.mFragmentIdentifier = result_buffer; - return aFragment.mStart + aOffset; - } - - return 0; - } - - - - /** - * |nsSlidingString| - */ - -nsSlidingString::nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ) - : nsSlidingSubstring(new nsSlidingSharedBufferList(nsSlidingSharedBufferList::NewWrappingBuffer(aStorageStart, aDataEnd, aStorageEnd))) - { - // nothing else to do here - } - -void -nsSlidingString::AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ) - { - Buffer* new_buffer = new Buffer(aStorageStart, aDataEnd, aStorageStart, aStorageEnd); - Buffer* old_last_buffer = mBufferList->GetLastBuffer(); - mBufferList->LinkBuffer(old_last_buffer, new_buffer, 0); - mLength += new_buffer->DataLength(); - - mEnd.PointAfter(new_buffer); - } - -void -nsSlidingString::InsertReadable( const nsAReadableString& aReadable, const nsReadingIterator& aInsertPoint ) - /* - * Warning: this routine manipulates the shared buffer list in an unexpected way. - * The original design did not really allow for insertions, but this call promises - * that if called for a point after the end of all extant token strings, that no token string - * or the work string will be invalidated. - * - * This routine is protected because it is the responsibility of the derived class to keep those promises. - */ - { - Position insertPos(aInsertPoint); - - mBufferList->SplitBuffer(insertPos, nsSharedBufferList::kSplitCopyRightData); - // splitting to the right keeps the work string and any extant token pointing to and - // holding a reference count on the same buffer - - Buffer* new_buffer = nsSharedBufferList::NewSingleAllocationBuffer(aReadable, 0); - // make a new buffer with all the data to insert... - // BULLSHIT ALERT: we may have empty space to re-use in the split buffer, measure the cost - // of this and decide if we should do the work to fill it - - Buffer* buffer_to_split = insertPos.mBuffer; - mBufferList->LinkBuffer(buffer_to_split, new_buffer, buffer_to_split->mNext); - mLength += aReadable.Length(); - mEnd.PointAfter(mBufferList->GetLastBuffer()); - } - -void -nsSlidingString::DiscardPrefix( const nsReadingIterator& aIter ) - { - Position old_start(mStart); - mStart = aIter; - mLength -= Position::Distance(old_start, mStart); - - mStart.mBuffer->AcquireNonOwningReference(); - old_start.mBuffer->ReleaseNonOwningReference(); - - mBufferList->DiscardUnreferencedPrefix(old_start.mBuffer); - } - -const PRUnichar* -nsSlidingString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const - { - return nsSlidingSubstring::GetReadableFragment(aFragment, aRequest, aOffset); - } diff --git a/xpcom/ds/nsSlidingString.h b/xpcom/ds/nsSlidingString.h deleted file mode 100755 index 079e7e2f1eb3..000000000000 --- a/xpcom/ds/nsSlidingString.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is Mozilla strings. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Scott Collins (original author) - * - */ - -#ifndef nsSlidingString_h___ -#define nsSlidingString_h___ - -#include "nsAReadableString.h" -#include "nsSharedBufferList.h" - - - /** - * Maintains the sequence from the prev-most referenced buffer to the last buffer. - * As prev-most buffers become un-referenced, they are unlinked from the list - * and destroyed. - * - * One or more |nsSlidingSubstring|s may reference into the list. Each |nsSlidingSubstring| - * holds a reference into the prev-most buffer intersecting the - * substring it describes. The destructor of a |nsSlidingSubstring| releases this - * reference, allowing the buffer list to destroy the contiguous prefix of - * unreferenced buffers. - * - * A single instance of |nsSlidingString| may reference this list. - * Through that interface, new data can be appended onto the next-most end - * of the list. |nsSlidingString| also the client to advance its starting point. - * - */ -class NS_COM nsSlidingSharedBufferList - : public nsSharedBufferList - { - public: - nsSlidingSharedBufferList( Buffer* aBuffer ) : nsSharedBufferList(aBuffer), mRefCount(0) { } - - void AcquireReference() { ++mRefCount; } - void ReleaseReference() { if ( !--mRefCount ) delete this; } - - void DiscardUnreferencedPrefix( Buffer* ); - - private: - PRUint32 mRefCount; - }; - - - - -class nsSlidingString; - - /** - * a substring over a buffer list, this - */ -class NS_COM nsSlidingSubstring - : virtual public nsPromiseReadable - { - friend class nsSlidingString; - - public: - typedef nsSlidingSharedBufferList::Buffer Buffer; - typedef nsSlidingSharedBufferList::Position Position; - - nsSlidingSubstring() - : mStart(0,0), - mEnd(0,0), - mBufferList(0), - mLength(0) - { - // nothing else to do here - } - - nsSlidingSubstring( const nsSlidingSubstring& ); // copy-constructor - nsSlidingSubstring( const nsSlidingSubstring& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ); - nsSlidingSubstring( const nsSlidingString& ); - nsSlidingSubstring( const nsSlidingString& aString, const nsReadingIterator& aStart, const nsReadingIterator& aEnd ); - explicit nsSlidingSubstring( const nsAReadableString& ); - // copy the supplied string into a new buffer ... there will be no modifying instance over this buffer list - - void Rebind( const nsSlidingSubstring& ); - void Rebind( const nsSlidingSubstring&, const nsReadingIterator&, const nsReadingIterator& ); - void Rebind( const nsSlidingString& ); - void Rebind( const nsSlidingString&, const nsReadingIterator&, const nsReadingIterator& ); - void Rebind( const nsAReadableString& ); - - ~nsSlidingSubstring(); - - virtual PRUint32 Length() const { return mLength; } - - protected: - nsSlidingSubstring( nsSlidingSharedBufferList* aBufferList ); - virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - private: - // can't assign into me, I'm a read-only reference - void operator=( const nsSlidingSubstring& ); // NOT TO BE IMPLEMENTED - - void - init_range_from_buffer_list() - // used only from constructors - { - mStart.PointBefore(mBufferList->GetFirstBuffer()); - mEnd.PointAfter(mBufferList->GetLastBuffer()); - mLength = PRUint32(Position::Distance(mStart, mEnd)); - } - - void - acquire_ownership_of_buffer_list() const - // used only from constructors and |Rebind|, requires |mStart| already be initialized - { - mBufferList->AcquireReference(); - mStart.mBuffer->AcquireNonOwningReference(); - } - - void - release_ownership_of_buffer_list() - { - if ( mBufferList ) - { - mStart.mBuffer->ReleaseNonOwningReference(); - mBufferList->DiscardUnreferencedPrefix(mStart.mBuffer); - mBufferList->ReleaseReference(); - } - } - - protected: - Position mStart; - Position mEnd; - nsSlidingSharedBufferList* mBufferList; - PRUint32 mLength; - }; - - - - - /** - * An |nsSlidingSharedBufferList| may be modified by zero or one instances of this class. - * - */ -class NS_COM nsSlidingString - : virtual public nsPromiseReadable, - private nsSlidingSubstring - { - friend class nsSlidingSubstring; - - public: - nsSlidingString( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ); - // ...created by consuming ownership of a buffer ... |aStorageStart| must point to something - // that it will be OK for the slidking string to call |nsMemory::Free| on - - virtual PRUint32 Length() const { return mLength; } - - // you are giving ownership to the string, it takes and keeps your buffer, deleting it (with |nsMemory::Free|) when done - void AppendBuffer( PRUnichar* aStorageStart, PRUnichar* aDataEnd, PRUnichar* aStorageEnd ); - -// void Append( ... ); do you want some |Append|s that copy the supplied data? - - void DiscardPrefix( const nsReadingIterator& ); - // any other way you want to do this? - - protected: - virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - - void InsertReadable( const nsAReadableString&, const nsReadingIterator& ); // ...to implement |nsScannerString::UngetReadable| - - private: - - void - acquire_ownership_of_buffer_list() const - // used only from constructors and |Rebind|, requires |mStart| already be initialized - { - mBufferList->AcquireReference(); - mStart.mBuffer->AcquireNonOwningReference(); - } - - nsSlidingString( const nsSlidingString& ); // NOT TO BE IMPLEMENTED - void operator=( const nsSlidingString& ); // NOT TO BE IMPLEMENTED - }; - -#endif // !defined(nsSlidingString_h___) diff --git a/xpcom/ds/nsStr.cpp b/xpcom/ds/nsStr.cpp deleted file mode 100644 index 888c63ca37b1..000000000000 --- a/xpcom/ds/nsStr.cpp +++ /dev/null @@ -1,923 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Original Author: - * Rick Gessner - * - * Contributor(s): - * Scott Collins - */ - -/****************************************************************************************** - MODULE NOTES: - - This file contains the nsStr data structure. - This general purpose buffer management class is used as the basis for our strings. - It's benefits include: - 1. An efficient set of library style functions for manipulating nsStrs - 2. Support for 1 and 2 byte character strings (which can easily be increased to n) - 3. Unicode awareness and interoperability. - -*******************************************************************************************/ - -#include "nsStr.h" -#include "bufferRoutines.h" -#include //only used for printf -#include "nsCRT.h" -#include "nsDeque.h" - -//static const char* kCallFindChar = "For better performance, call FindChar() for targets whose length==1."; -//static const char* kCallRFindChar = "For better performance, call RFindChar() for targets whose length==1."; - -static const PRUnichar gCommonEmptyBuffer[1] = {0}; -static PRBool gStringAcquiredMemory = PR_TRUE; - -/** - * This method initializes all the members of the nsStr structure - * - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) { - aDest.mStr=(char*)gCommonEmptyBuffer; - aDest.mLength=0; - aDest.mCapacity=0; - aDest.mCharSize=aCharSize; - aDest.mOwnsBuffer=0; -} - -/** - * This method initializes all the members of the nsStr structure - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){ - aDest.mStr=(aCString) ? aCString : (char*)gCommonEmptyBuffer; - aDest.mLength=aLength; - aDest.mCapacity=aCapacity; - aDest.mCharSize=aCharSize; - aDest.mOwnsBuffer=aOwnsBuffer; -} - - -/** - * This member destroys the memory buffer owned by an nsStr object (if it actually owns it) - * @update gess10/30/98 - * @param - * @return - */ -void nsStr::Destroy(nsStr& aDest) { - if((aDest.mStr) && (aDest.mStr!=(char*)gCommonEmptyBuffer)) { - Free(aDest); - } -} - - -/** - * This method gets called when the internal buffer needs - * to grow to a given size. The original contents are not preserved. - * @update gess 3/30/98 - * @param aNewLength -- new capacity of string in charSize units - * @return void - */ -PRBool nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength) { - PRBool result=PR_TRUE; - if(aNewLength>aString.mCapacity) { - result=Realloc(aString,aNewLength); - if(aString.mStr) - AddNullTerminator(aString); - } - return result; -} - -/** - * This method gets called when the internal buffer needs - * to grow to a given size. The original contents ARE preserved. - * @update gess 3/30/98 - * @param aNewLength -- new capacity of string in charSize units - * @return void - */ -PRBool nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength) { - PRBool result=PR_TRUE; - if(aNewLength>aDest.mCapacity) { - nsStr theTempStr; - nsStr::Initialize(theTempStr,aDest.mCharSize); - -#ifndef NS_USE_OLD_STRING_ALLOCATION_STRATEGY - // the new strategy is, allocate exact size, double on grows - if ( aDest.mCapacity ) { - PRUint32 newCapacity = aDest.mCapacity; - while ( newCapacity < aNewLength ) - newCapacity <<= 1; - aNewLength = newCapacity; - } -#endif - - result=EnsureCapacity(theTempStr,aNewLength); - if(result) { - if(aDest.mLength) { - StrAppend(theTempStr,aDest,0,aDest.mLength); - } - Free(aDest); - aDest.mStr = theTempStr.mStr; - theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole... - aDest.mLength=theTempStr.mLength; - aDest.mCapacity=theTempStr.mCapacity; - aDest.mOwnsBuffer=theTempStr.mOwnsBuffer; - } - } - return result; -} - -/** - * Replaces the contents of aDest with aSource, up to aCount of chars. - * @update gess10/30/98 - * @param aDest is the nsStr that gets changed. - * @param aSource is where chars are copied from - * @param aCount is the number of chars copied from aSource - */ -void nsStr::StrAssign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){ - if(&aDest!=&aSource){ - StrTruncate(aDest,0); - StrAppend(aDest,aSource,anOffset,aCount); - } -} - -/** - * This method appends the given nsStr to this one. Note that we have to - * pay attention to the underlying char-size of both structs. - * @update gess10/30/98 - * @param aDest is the nsStr to be manipulated - * @param aSource is where char are copied from - * @aCount is the number of bytes to be copied - */ -void nsStr::StrAppend(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){ - if(anOffset aDest.mCapacity) { - isBigEnough=GrowCapacity(aDest,aDest.mLength+theLength); - } - - if(isBigEnough) { - //now append new chars, starting at offset - (*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDest.mLength,aSource.mStr,anOffset,theLength); - - aDest.mLength+=theLength; - AddNullTerminator(aDest); - NSSTR_SEEN(aDest); - } - } - } -} - - -/** - * This method inserts up to "aCount" chars from a source nsStr into a dest nsStr. - * @update gess10/30/98 - * @param aDest is the nsStr that gets changed - * @param aDestOffset is where in aDest the insertion is to occur - * @param aSource is where chars are copied from - * @param aSrcOffset is where in aSource chars are copied from - * @param aCount is the number of chars from aSource to be inserted into aDest - */ -void nsStr::StrInsert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount){ - //there are a few cases for insert: - // 1. You're inserting chars into an empty string (assign) - // 2. You're inserting onto the end of a string (append) - // 3. You're inserting onto the 1..n-1 pos of a string (the hard case). - if(0 aDest.mCapacity) { - nsStr theTempStr; - nsStr::Initialize(theTempStr,aDest.mCharSize); - - PRBool isBigEnough=EnsureCapacity(theTempStr,aDest.mLength+theLength); //grow the temp buffer to the right size - - if(isBigEnough) { - if(aDestOffset) { - StrAppend(theTempStr,aDest,0,aDestOffset); //first copy leftmost data... - } - - StrAppend(theTempStr,aSource,0,aSource.mLength); //next copy inserted (new) data - - PRUint32 theRemains=aDest.mLength-aDestOffset; - if(theRemains) { - StrAppend(theTempStr,aDest,aDestOffset,theRemains); //next copy rightmost data - } - - Free(aDest); - aDest.mStr = theTempStr.mStr; - theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole... - aDest.mCapacity=theTempStr.mCapacity; - aDest.mOwnsBuffer=theTempStr.mOwnsBuffer; - } - - } - - else { - //shift the chars right by theDelta... - (*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); - } - - //finally, make sure to update the string length... - aDest.mLength+=theLength; - AddNullTerminator(aDest); - NSSTR_SEEN(aDest); - }//if - //else nothing to do! - } - else StrAppend(aDest,aSource,0,aCount); - } - else StrAppend(aDest,aSource,0,aCount); - } -} - - -/** - * This method deletes up to aCount chars from aDest - * @update gess10/30/98 - * @param aDest is the nsStr to be manipulated - * @param aDestOffset is where in aDest deletion is to occur - * @param aCount is the number of chars to be deleted in aDest - */ -void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount){ - if(aDestOffset0) && aSet){ - PRInt32 theIndex=-1; - PRInt32 theMax=aDest.mLength; - PRInt32 theSetLen=nsCRT::strlen(aSet); - - if(aEliminateLeading) { - while(++theIndex<=theMax) { - PRUnichar theChar=GetCharAt(aDest,theIndex); - PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); - if(kNotFound==thePos) - break; - } - if(0=0) { - PRUnichar theChar=GetCharAt(aDest,theIndex); //read at end now... - PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE,theSetLen); - if(kNotFound=0) { - PRUnichar theChar=GetCharAt(aDest,index); - thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase,aSet.mLength); - if(kNotFound!=thePos) - return index; - } //while - } - return kNotFound; -} - -/** - * Compare source and dest strings, up to an (optional max) number of chars - * @param aDest is the first str to compare - * @param aSource is the second str to compare - * @param aCount -- if (-1), then we use length of longer string; if (0aSource=1 - */ -PRInt32 nsStr::StrCompare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) { - PRInt32 result=0; - - if(aCount) { - PRInt32 minlen=(aSource.mLength=aSource.mLength) { - //if you're here, then both dest and source have valid lengths - //and there's enough room in dest (at offset) to contain source. - (*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,0,aSource.mLength); - } - } -} - -//---------------------------------------------------------------------------------------- - -PRBool nsStr::Alloc(nsStr& aDest,PRUint32 aCount) { - - static int mAllocCount=0; - mAllocCount++; - -#ifdef NS_USE_OLD_STRING_ALLOCATION_STRATEGY - //we're given the acount value in charunits; now scale up to next multiple. - PRUint32 theNewCapacity=kDefaultStringSize; - while(theNewCapacity1) { - mCapacity=aCapacity-1; - mLength=(-1==aLength) ? strlen(aString) : aLength; - if(mLength>PRInt32(mCapacity)) - mLength=mCapacity; - } -} - -CBufDescriptor::CBufDescriptor(const char* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) { - mBuffer=(char*)aString; - mCharSize=eOneByte; - mStackBased=aStackBased; - mIsConst=PR_TRUE; - mLength=mCapacity=0; - if(aString && aCapacity>1) { - mCapacity=aCapacity-1; - mLength=(-1==aLength) ? strlen(aString) : aLength; - if(mLength>PRInt32(mCapacity)) - mLength=mCapacity; - } -} - - -CBufDescriptor::CBufDescriptor(PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) { - mBuffer=(char*)aString; - mCharSize=eTwoByte; - mStackBased=aStackBased; - mLength=mCapacity=0; - mIsConst=PR_FALSE; - if(aString && aCapacity>1) { - mCapacity=aCapacity-1; - mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength; - if(mLength>PRInt32(mCapacity)) - mLength=mCapacity; - } -} - -CBufDescriptor::CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) { - mBuffer=(char*)aString; - mCharSize=eTwoByte; - mStackBased=aStackBased; - mLength=mCapacity=0; - mIsConst=PR_TRUE; - if(aString && aCapacity>1) { - mCapacity=aCapacity-1; - mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength; - if(mLength>PRInt32(mCapacity)) - mLength=mCapacity; - } -} - -//---------------------------------------------------------------------------------------- - -PRUint32 -nsStr::HashCode(const nsStr& aDest) -{ - if (aDest.mCharSize == eTwoByte) - return nsCRT::HashCode(aDest.mUStr); - else - return nsCRT::HashCode(aDest.mStr); -} - -#ifdef NS_STR_STATS - -#include - -#ifdef XP_MAC -#define isascii(c) ((unsigned)(c) < 0x80) -#endif - -void -nsStr::Print(const nsStr& aDest, FILE* out, PRBool truncate) -{ - PRInt32 printLen = (PRInt32)aDest.mLength; - - if (aDest.mCharSize == eOneByte) { - const char* chars = aDest.mStr; - while (printLen-- && (!truncate || *chars != '\n')) { - fputc(*chars++, out); - } - } - else { - const PRUnichar* chars = aDest.mUStr; - while (printLen-- && (!truncate || *chars != '\n')) { - if (isascii(*chars)) - fputc((char)(*chars++), out); - else - fputc('-', out); - } - } -} - -//////////////////////////////////////////////////////////////////////////////// -// String Usage Statistics Routines - -static PLHashTable* gStringInfo = nsnull; -PRLock* gStringInfoLock = nsnull; -PRBool gNoStringInfo = PR_FALSE; - -nsStringInfo::nsStringInfo(nsStr& str) - : mCount(0) -{ - nsStr::Initialize(mStr, str.mCharSize); - nsStr::StrAssign(mStr, str, 0, -1); -// nsStr::Print(mStr, stdout); -// fputc('\n', stdout); -} - -PR_EXTERN(PRHashNumber) -nsStr_Hash(const void* key) -{ - nsStr* str = (nsStr*)key; - return nsStr::HashCode(*str); -} - -PR_EXTERN(PRIntn) -nsStr_Compare(const void *v1, const void *v2) -{ - nsStr* str1 = (nsStr*)v1; - nsStr* str2 = (nsStr*)v2; - return nsStr::StrCompare(*str1, *str2, -1, PR_FALSE) == 0; -} - -nsStringInfo* -nsStringInfo::GetInfo(nsStr& str) -{ - if (gStringInfo == nsnull) { - gStringInfo = PL_NewHashTable(1024, - nsStr_Hash, - nsStr_Compare, - PL_CompareValues, - NULL, NULL); - gStringInfoLock = PR_NewLock(); - } - PR_Lock(gStringInfoLock); - nsStringInfo* info = - (nsStringInfo*)PL_HashTableLookup(gStringInfo, &str); - if (info == NULL) { - gNoStringInfo = PR_TRUE; - info = new nsStringInfo(str); - if (info) { - PLHashEntry* e = PL_HashTableAdd(gStringInfo, &info->mStr, info); - if (e == NULL) { - delete info; - info = NULL; - } - } - gNoStringInfo = PR_FALSE; - } - PR_Unlock(gStringInfoLock); - return info; -} - -void -nsStringInfo::Seen(nsStr& str) -{ - if (!gNoStringInfo) { - nsStringInfo* info = GetInfo(str); - info->mCount++; - } -} - -void -nsStringInfo::Report(FILE* out) -{ - if (gStringInfo) { - fprintf(out, "\n== String Stats\n"); - PL_HashTableEnumerateEntries(gStringInfo, nsStringInfo::ReportEntry, out); - } -} - -PRIntn -nsStringInfo::ReportEntry(PLHashEntry *he, PRIntn i, void *arg) -{ - nsStringInfo* entry = (nsStringInfo*)he->value; - FILE* out = (FILE*)arg; - - fprintf(out, "%d ==> (%d) ", entry->mCount, entry->mStr.mLength); - nsStr::Print(entry->mStr, out, PR_TRUE); - fputc('\n', out); - return HT_ENUMERATE_NEXT; -} - -#endif // NS_STR_STATS - -//////////////////////////////////////////////////////////////////////////////// diff --git a/xpcom/ds/nsStr.h b/xpcom/ds/nsStr.h deleted file mode 100644 index c5e50045f194..000000000000 --- a/xpcom/ds/nsStr.h +++ /dev/null @@ -1,523 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Rick Gessner (original author) - * Scott Collins - */ - -/*********************************************************************** - MODULE NOTES: - - 1. There are two philosophies to building string classes: - A. Hide the underlying buffer & offer API's allow indirect iteration - B. Reveal underlying buffer, risk corruption, but gain performance - - We chose the option B for performance reasons. - - 2 Our internal buffer always holds capacity+1 bytes. - - The nsStr struct is a simple structure (no methods) that contains - the necessary info to be described as a string. This simple struct - is manipulated by the static methods provided in this class. - (Which effectively makes this a library that works on structs). - - There are also object-based versions called nsString and nsAutoString - which use nsStr but makes it look at feel like an object. - - ***********************************************************************/ - -/*********************************************************************** - ASSUMPTIONS: - - 1. nsStrings and nsAutoString are always null terminated. However, - since it maintains a length byte, you can store NULL's inside - the string. Just be careful passing such buffers to 3rd party - API's that assume that NULL always terminate the buffer. - - 2. nsCStrings can be upsampled into nsString without data loss - - 3. Char searching is faster than string searching. Use char interfaces - if your needs will allow it. - - 4. It's easy to use the stack for nsAutostring buffer storage (fast too!). - See the CBufDescriptor class in this file. - - 5. If you don't provide the optional count argument to Append() and Insert(), - the method will assume that the given buffer is terminated by the first - NULL it encounters. - - 6. Downsampling from nsString to nsCString can be lossy -- avoid it if possible! - - 7. Calls to ToNewCString() and ToNewUnicode() should be matched with calls to nsMemory::Free(). - - ***********************************************************************/ - - -/********************************************************************************** - - AND NOW FOR SOME GENERAL DOCUMENTATION ON STRING USAGE... - - The fundamental datatype in the string library is nsStr. It's a structure that - provides the buffer storage and meta-info. It also provides a C-style library - of functions for direct manipulation (for those of you who prefer K&R to Bjarne). - - Here's a diagram of the class hierarchy: - - nsStr - |___nsString - | | - | ------nsAutoString - | - |___nsCString - | - ------nsCAutoString - - Why so many string classes? The 4 variants give you the control you need to - determine the best class for your purpose. There are 2 dimensions to this - flexibility: 1) stack vs. heap; and 2) 1-byte chars vs. 2-byte chars. - - Note: While nsAutoString and nsCAutoString begin life using stack-based storage, - they may not stay that way. Like all nsString classes, autostrings will - automatically grow to contain the data you provide. When autostrings - grow beyond their intrinsic buffer, they switch to heap based allocations. - (We avoid alloca to avoid considerable platform difficulties; see the - GNU documentation for more details). - - I should also briefly mention that all the string classes use a "memory agent" - object to perform memory operations. This class proxies the standard nsMemory - for actual memory calls, but knows the structure of nsStr making heap operations - more localized. - - - CHOOSING A STRING CLASS: - - In order to choose a string class for you purpose, use this handy table: - - heap-based stack-based - ----------------------------------- - ascii data | nsCString nsCAutoString | - |---------------------------------- - unicode data | nsString nsAutoString | - ----------------------------------- - - - Note: The i18n folks will stenuously object if we get too carried away with the - use of nsCString's that pass interface boundaries. Try to limit your - use of these to external interfaces that demand them, or for your own - private purposes in cases where they'll never be seen by humans. - - - --- FAQ --- - - Q. When should I use nsCString instead of nsString? - - A. You should really try to stick with nsString, so that we stay as unicode - compliant as possible. But there are cases where an interface you use requires - a char*. In such cases, it's fair to use nsCString. - - Q. I know that my string is going to be a certain size. Can I pre-size my nsString? - - A. Yup, here's how: - - { - nsString mBuffer; - mBuffer.SetCapacity(aReasonableSize); - } - - Q. Should nsAutoString or nsCAutoString ever live on the heap? - - A. That would be counterproductive. The point of nsAutoStrings is to preallocate your - buffers, and to auto-destroy the string when it goes out of scope. - - Q. I already have a char*. Can I use the nsString functionality on that buffer? - - A. Yes you can -- by using an intermediate class called CBufDescriptor. - The CBufDescriptor class is used to tell nsString about an external buffer (heap or stack) to use - instead of it's own internal buffers. Here's an example: - - { - char theBuffer[256]; - CBufDescritor theBufDecriptor( theBuffer, PR_TRUE, sizeof(theBuffer), 0); - nsCAutoString s3( theBufDescriptor ); - s3="HELLO, my name is inigo montoya, you killed my father, prepare to die!."; - } - - The assignment statment to s3 will cause the given string to be written to your - stack-based buffer via the normal nsString/nsCString interfaces. Cool, huh? - Note however that just like any other nsStringXXX use, if you write more data - than will fit in the buffer, a visit to the heap manager will be in order. - - - Q. What is the simplest way to get from a char* to PRUnichar*? - - A. The simplest way is by construction (or assignment): - - { - char* theBuf = "hello there"; - nsAutoString foo(theBuf); - } - - If you don't want the char* to be copied into the nsAutoString, the use a - CBufDescriptor instead. - - - **********************************************************************************/ - - -#ifndef _nsStr -#define _nsStr - -#include "nscore.h" -#include "nsMemory.h" -#include -#include -#include "plhash.h" - -//---------------------------------------------------------------------------------------- - -enum eCharSize {eOneByte=0,eTwoByte=1}; -#define kDefaultCharSize eTwoByte -#define kRadix10 (10) -#define kRadix16 (16) -#define kAutoDetect (100) -#define kRadixUnknown (kAutoDetect+1) -#define IGNORE_CASE (PR_TRUE) - -const PRInt32 kDefaultStringSize = 64; -const PRInt32 kNotFound = -1; - - -//---------------------------------------------------------------------------------------- - -class NS_COM CBufDescriptor { -public: - CBufDescriptor(char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1); - CBufDescriptor(const char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1); - CBufDescriptor(PRUnichar* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1); - CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1); - - char* mBuffer; - eCharSize mCharSize; - PRUint32 mCapacity; - PRInt32 mLength; - PRBool mStackBased; - PRBool mIsConst; -}; - -//---------------------------------------------------------------------------------------- - - -struct NS_COM nsStr { - - nsStr() { - MOZ_COUNT_CTOR(nsStr); - } - - ~nsStr() { - MOZ_COUNT_DTOR(nsStr); - } - - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,eCharSize aCharSize); - - /** - * This method initializes an nsStr for use - * - * @update gess 01/04/99 - * @param aString is the nsStr to be initialized - * @param aCharSize tells us the requested char size (1 or 2 bytes) - */ - static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer); - - /** - * This method destroys the given nsStr, and *MAY* - * deallocate it's memory depending on the setting - * of the internal mOwnsBUffer flag. - * - * @update gess 01/04/99 - * @param aString is the nsStr to be manipulated - * @param anAgent is the allocator to be used to the nsStr - */ - static void Destroy(nsStr& aDest); - - /** - * These methods are where memory allocation/reallocation occur. - * - * @update gess 01/04/99 - * @param aString is the nsStr to be manipulated - * @param anAgent is the allocator to be used on the nsStr - * @return - */ - static PRBool EnsureCapacity(nsStr& aString,PRUint32 aNewLength); - static PRBool GrowCapacity(nsStr& aString,PRUint32 aNewLength); - - /** - * These methods are used to append content to the given nsStr - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be appended to - * @param aSource is the buffer to be copied from - * @param anOffset tells us where in source to start copying - * @param aCount tells us the (max) # of chars to copy - * @param anAgent is the allocator to be used for alloc/free operations - */ - static void StrAppend(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount); - - /** - * These methods are used to assign contents of a source string to dest string - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be appended to - * @param aSource is the buffer to be copied from - * @param anOffset tells us where in source to start copying - * @param aCount tells us the (max) # of chars to copy - * @param anAgent is the allocator to be used for alloc/free operations - */ - static void StrAssign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount); - - /** - * These methods are used to insert content from source string to the dest nsStr - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be appended to - * @param aDestOffset tells us where in dest to start insertion - * @param aSource is the buffer to be copied from - * @param aSrcOffset tells us where in source to start copying - * @param aCount tells us the (max) # of chars to insert - * @param anAgent is the allocator to be used for alloc/free operations - */ - static void StrInsert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount); - - /** - * This method deletes chars from the given str. - * The given allocator may choose to resize the str as well. - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be deleted from - * @param aDestOffset tells us where in dest to start deleting - * @param aCount tells us the (max) # of chars to delete - * @param anAgent is the allocator to be used for alloc/free operations - */ - static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount); - - /** - * This method is used to truncate the given string. - * The given allocator may choose to resize the str as well (but it's not likely). - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be appended to - * @param aDestOffset tells us where in dest to start insertion - * @param aSource is the buffer to be copied from - * @param aSrcOffset tells us where in source to start copying - * @param anAgent is the allocator to be used for alloc/free operations - */ - static void StrTruncate(nsStr& aDest,PRUint32 aDestOffset); - - /** - * This method is used to perform a case conversion on the given string - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be case shifted - * @param toUpper tells us to go upper vs. lower - */ - static void ChangeCase(nsStr& aDest,PRBool aToUpper); - - - /** - * This method trims chars (given in aSet) from the edges of given buffer - * - * @update gess 01/04/99 - * @param aDest is the buffer to be manipulated - * @param aSet tells us which chars to remove from given buffer - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - */ - static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing); - - /** - * This method compresses duplicate runs of a given char from the given buffer - * - * @update gess 01/04/99 - * @param aDest is the buffer to be manipulated - * @param aSet tells us which chars to compress from given buffer - * @param aChar is the replacement char - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - */ - static void CompressSet(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing); - - /** - * This method removes all occurances of chars in given set from aDest - * - * @update gess 01/04/99 - * @param aDest is the buffer to be manipulated - * @param aSet tells us which chars to compress from given buffer - * @param aChar is the replacement char - * @param aEliminateLeading tells us whether to strip chars from the start of the buffer - * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer - */ - static void StripChars(nsStr& aDest,const char* aSet); - - /** - * This method compares the data bewteen two nsStr's - * - * @update gess 01/04/99 - * @param aStr1 is the first buffer to be compared - * @param aStr2 is the 2nd buffer to be compared - * @param aCount is the number of chars to compare - * @param aIgnorecase tells us whether to use a case-sensitive comparison - * @return -1,0,1 depending on <,==,> - */ - static PRInt32 StrCompare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase); - - /** - * These methods scan the given string for 1 or more chars in a given direction - * - * @update gess 01/04/99 - * @param aDest is the nsStr to be searched to - * @param aSource (or aChar) is the substr we're looking to find - * @param aIgnoreCase tells us whether to search in a case-sensitive manner - * @param anOffset tells us where in the dest string to start searching - * @return the index of the source (substr) in dest, or -1 (kNotFound) if not found. - */ - static PRInt32 FindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); - static PRInt32 FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); - static PRInt32 FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - - static PRInt32 RFindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); - static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset,PRInt32 aCount); - static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset); - - static void Overwrite(nsStr& aDest,const nsStr& aSource,PRInt32 anOffset); - - static PRBool DidAcquireMemory(void); - - /** - * Returns a hash code for the string for use in a PLHashTable. - */ - static PRUint32 HashCode(const nsStr& aDest); - -#ifdef NS_STR_STATS - /** - * Prints an nsStr. If truncate is true, the string is only printed up to - * the first newline. (Note: The current implementation doesn't handle - * non-ascii unicode characters.) - */ - static void Print(const nsStr& aDest, FILE* out, PRBool truncate = PR_FALSE); -#endif - - PRUint32 mLength; - PRUint32 mCapacity; - eCharSize mCharSize; - PRBool mOwnsBuffer; - - union { - char* mStr; - PRUnichar* mUStr; - }; - -private: - static PRBool Alloc(nsStr& aString,PRUint32 aCount); - static PRBool Realloc(nsStr& aString,PRUint32 aCount); - static PRBool Free(nsStr& aString); - -}; - - - - -/************************************************************** - A couple of tiny helper methods used in the string classes. - **************************************************************/ - -inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){ - return (anInt1 - * - * Contributor(s): - * Scott Collins - */ - -#include -#include -#include -#include -#include "nsString.h" -#include "nsDebug.h" -#include "nsCRT.h" -#include "nsDeque.h" - -#ifndef RICKG_TESTBED -#include "prdtoa.h" -#include "nsISizeOfHandler.h" -#endif - -static const char* kPossibleNull = "Error: possible unintended null in string"; -static const char* kNullPointerError = "Error: unexpected null ptr"; -static const char* kWhitespace="\b\t\r\n "; - - -static void CSubsume(nsStr& aDest,nsStr& aSource){ - if(aSource.mStr && aSource.mLength) { - if(aSource.mOwnsBuffer){ - nsStr::Destroy(aDest); - aDest.mStr=aSource.mStr; - aDest.mLength=aSource.mLength; - aDest.mCharSize=aSource.mCharSize; - aDest.mCapacity=aSource.mCapacity; - aDest.mOwnsBuffer=aSource.mOwnsBuffer; - aSource.mOwnsBuffer=PR_FALSE; - aSource.mStr=0; - } - else{ - nsStr::StrAssign(aDest,aSource,0,aSource.mLength); - } - } - else nsStr::StrTruncate(aDest,0); -} - - -/** - * Default constructor. - */ -nsCString::nsCString() { - Initialize(*this,eOneByte); -} - -nsCString::nsCString(const char* aCString) { - Initialize(*this,eOneByte); - Assign(aCString); -} - -/** - * This constructor accepts an ascii string - * @update gess 1/4/99 - * @param aCString is a ptr to a 1-byte cstr - * @param aLength tells us how many chars to copy from given CString - */ -nsCString::nsCString(const char* aCString,PRInt32 aLength) { - Initialize(*this,eOneByte); - Assign(aCString,aLength); -} - -#if 0 -/** - * This constructor accepts a unicode string - * @update gess 1/4/99 - * @param aString is a ptr to a unichar string - * @param aLength tells us how many chars to copy from given aString - */ -nsCString::nsCString(const PRUnichar* aString,PRInt32 aLength) { - Initialize(*this,eOneByte); - AssignWithConversion(aString,aLength); -} - -/** - * This constructor works for all other nsSTr derivatives - * @update gess 1/4/99 - * @param reference to another nsCString - */ -nsCString::nsCString(const nsStr &aString) { - Initialize(*this,eOneByte); - StrAssign(*this,aString,0,aString.mLength); -} -#endif - -/** - * This is our copy constructor - * @update gess 1/4/99 - * @param reference to another nsCString - */ -nsCString::nsCString(const nsCString& aString) { - Initialize(*this,aString.mCharSize); - StrAssign(*this,aString,0,aString.mLength); -} - -/** - * construct from subsumeable string - * @update gess 1/4/99 - * @param reference to a subsumeString - */ -nsCString::nsCString(nsSubsumeCStr& aSubsumeStr) { - CSubsume(*this,aSubsumeStr); -} - -/** - * Destructor - */ -nsCString::~nsCString() { - Destroy(*this); -} - -const char* nsCString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { - switch ( aRequest ) { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mStr) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } -} - -char* nsCString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { - switch ( aRequest ) { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mStr) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } -} - -nsCString::nsCString( const nsAReadableCString& aReadable ) { - Initialize(*this,eOneByte); - Assign(aReadable); -} - -void nsCString::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { - if (aResult) { - *aResult = sizeof(*this) + mCapacity * mCharSize; - } -} - -/** - * This method truncates this string to given length. - * - * @update rickg 03.23.2000 - * @param anIndex -- new length of string - * @return nada - */ -void nsCString::SetLength(PRUint32 anIndex) { - if ( anIndex > mCapacity ) - SetCapacity(anIndex); - // |SetCapacity| normally doesn't guarantee the use we are putting it to here (see its interface comment in nsAWritableString.h), - // we can only use it since our local implementation, |nsCString::SetCapacity|, is known to do what we want - - nsStr::StrTruncate(*this,anIndex); -} - - -/** - * Call this method if you want to force the string to a certain capacity; - * |SetCapacity(0)| discards associated storage. - * - * @param aNewCapacity -- desired minimum capacity - */ -void -nsCString::SetCapacity( PRUint32 aNewCapacity ) - { - if ( aNewCapacity ) - { - if( aNewCapacity > mCapacity ) - GrowCapacity(*this,aNewCapacity); - AddNullTerminator(*this); - } - else - { - nsStr::Destroy(*this); - nsStr::Initialize(*this, eOneByte); - } - } - -/********************************************************************** - Accessor methods... - *********************************************************************/ - -/** - * set a char inside this string at given index - * @param aChar is the char you want to write into this string - * @param anIndex is the ofs where you want to write the given char - * @return TRUE if successful - */ -PRBool nsCString::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ - PRBool result=PR_FALSE; - if(anIndex2)) { - theFirstChar=First(); - theLastChar=Last(); - if(theFirstChar==theLastChar) { - if(('\''==theFirstChar) || ('"'==theFirstChar)) { - Cut(0,1); - Truncate(mLength-1); - theQuotesAreNeeded=PR_TRUE; - } - else theFirstChar=0; - } - } - - nsStr::Trim(*this,aTrimSet,aEliminateLeading,aEliminateTrailing); - - if(aIgnoreQuotes && theQuotesAreNeeded) { - InsertWithConversion(theFirstChar,0); - AppendWithConversion(theLastChar); - } - - } -} - -/** - * This method strips chars in given set from string. - * You can control whether chars are yanked from - * start and end of string as well. - * - * @update gess 3/31/98 - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ -void -nsCString::CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){ - if(aSet){ - ReplaceChar(aSet,aChar); - nsStr::CompressSet(*this,aSet,aEliminateLeading,aEliminateTrailing); - } -} - -/** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @update gess 3/31/98 - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ -void -nsCString::CompressWhitespace( PRBool aEliminateLeading,PRBool aEliminateTrailing){ - CompressSet(kWhitespace,' ',aEliminateLeading,aEliminateTrailing); -} - -/********************************************************************** - string conversion methods... - *********************************************************************/ - -/** - * Creates a duplicate clone (ptr) of this string. - * @update gess 01/04/99 - * @return ptr to clone of this string - */ -nsCString* nsCString::ToNewString() const { - return new nsCString(*this); -} - -/** - * Creates an ascii clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @update gess 02/24/00 - * @return ptr to new ascii string - */ -char* nsCString::ToNewCString() const { - return nsCRT::strdup(mStr); -} - -/** - * Creates an unicode clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @update gess 01/04/99 - * @return ptr to new ascii string - */ -PRUnichar* nsCString::ToNewUnicode() const { - PRUnichar* result = NS_STATIC_CAST(PRUnichar*, nsMemory::Alloc(sizeof(PRUnichar) * (mLength + 1))); - if (result) { - CBufDescriptor desc(result, PR_TRUE, mLength + 1, 0); - nsAutoString temp(desc); - temp.AssignWithConversion(*this); - } - return result; -} - -/** - * Copies contents of this string into he given buffer - * Note that if you provide me a buffer that is smaller than the length of - * this string, only the number of bytes that will fit are copied. - * - * @update gess 01/04/99 - * @param aBuf - * @param aBufLength - * @param anOffset - * @return - */ -char* nsCString::ToCString(char* aBuf, PRUint32 aBufLength,PRUint32 anOffset) const{ - if(aBuf) { - - // NS_ASSERTION(mLength<=aBufLength,"buffer smaller than string"); - - CBufDescriptor theDescr(aBuf,PR_TRUE,aBufLength,0); - nsCAutoString temp(theDescr); - temp.Assign(*this, PR_MIN(mLength, aBufLength-1)); - temp.mStr=0; - } - return aBuf; -} - - -/** - * Perform string to float conversion. - * @update gess 01/04/99 - * @param aErrorCode will contain error if one occurs - * @return float rep of string value - */ -float nsCString::ToFloat(PRInt32* aErrorCode) const { - char buf[100]; - if (mLength > PRInt32(sizeof(buf)-1)) { - *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; - return 0.0f; - } - char* cp = ToCString(buf, sizeof(buf)); - float f = (float) PR_strtod(cp, &cp); - if (*cp != 0) { - *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; - } - *aErrorCode = (PRInt32) NS_OK; - return f; -} - -/** - * Perform decimal numeric string to int conversion. - * NOTE: In this version, we use the radix you give, even if it's wrong. - * @update gess 02/14/00 - * @param aErrorCode will contain error if one occurs - * @param aRadix tells us what base to expect the given string in. kAutoDetect tells us to determine the radix. - * @return int rep of string value - */ -PRInt32 nsCString::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const { - char* cp=mStr; - PRInt32 theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect) - PRInt32 result=0; - PRBool negate=PR_FALSE; - char theChar=0; - - //initial value, override if we find an integer - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - - if(cp) { - - //begin by skipping over leading chars that shouldn't be part of the number... - - char* endcp=cp+mLength; - PRBool done=PR_FALSE; - - while((cp='A') && (theChar<='F')) { - if(10==theRadix) { - if(kAutoDetect==aRadix){ - theRadix=16; - cp=first; //backup - result=0; - } - else { - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - result=0; - break; - } - } - else { - result = (theRadix * result) + ((theChar-'A')+10); - } - } - else if((theChar>='a') && (theChar<='f')) { - if(10==theRadix) { - if(kAutoDetect==aRadix){ - theRadix=16; - cp=first; //backup - result=0; - } - else { - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - result=0; - break; - } - } - else { - result = (theRadix * result) + ((theChar-'a')+10); - } - } - else if(('X'==theChar) || ('x'==theChar) || ('#'==theChar) || ('+'==theChar)) { - continue; - } - else { - //we've encountered a char that's not a legal number or sign - break; - } - } //while - if(negate) - result=-result; - } //if - } - return result; -} - -/********************************************************************** - String manipulation methods... - *********************************************************************/ - - -/** - * assign given unichar* to this string - * @update gess 01/04/99 - * @param aCString: buffer to be assigned to this - * @param aCount -- length of given buffer or -1 if you want me to compute length. - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return this - */ -void nsCString::AssignWithConversion(const PRUnichar* aString,PRInt32 aCount) { - nsStr::StrTruncate(*this,0); - - if(aString && aCount){ - nsStr temp; - nsStr::Initialize(temp,eTwoByte); - temp.mUStr=(PRUnichar*)aString; - - if(0 start; aString.BeginReading(start); - nsReadingIterator end; aString.EndReading(end); - - while (start != end) { - PRUint32 fraglen = start.size_forward(); - - nsStr temp; - nsStr::Initialize(temp,eTwoByte); - temp.mUStr=(PRUnichar*)start.get(); - - temp.mLength=fraglen; - - StrAppend(*this,temp,0,fraglen); - - start += fraglen; - } - } -} - -void nsCString::AppendWithConversion( const nsAReadableString& aString ) { - PRInt32 count = aString.Length(); - - if(count){ - nsReadingIterator start; aString.BeginReading(start); - nsReadingIterator end; aString.EndReading(end); - - while (start != end) { - PRUint32 fraglen = start.size_forward(); - - nsStr temp; - nsStr::Initialize(temp,eTwoByte); - temp.mUStr=(PRUnichar*)start.get(); - - temp.mLength=fraglen; - - StrAppend(*this,temp,0,fraglen); - - start += fraglen; - } - } -} - -/** - * assign given unichar to this string - * @update gess 01/04/99 - * @param aChar: char to be assignd to this - * @return this - */ -void nsCString::AssignWithConversion(PRUnichar aChar) { - nsStr::StrTruncate(*this,0); - AppendWithConversion(aChar); -} - -void nsCString::do_AppendFromReadable( const nsAReadableCString& aReadable ) - { - if ( SameImplementation( NS_STATIC_CAST(const nsAReadableCString&, *this), aReadable) ) - StrAppend(*this, NS_STATIC_CAST(const nsCString&, aReadable), 0, aReadable.Length()); - else - nsAWritableCString::do_AppendFromReadable(aReadable); - } - - -/** - * append given char to this string - * @update gess 01/04/99 - * @param aChar: char to be appended to this - * @return this - */ -void nsCString::AppendWithConversion(PRUnichar aChar) { - PRUnichar buf[2]={0,0}; - buf[0]=aChar; - - nsStr temp; - nsStr::Initialize(temp,eTwoByte); - temp.mUStr=buf; - temp.mLength=1; - StrAppend(*this,temp,0,1); -} - -void nsCString::AppendWithConversion( const PRUnichar* aBuffer, PRInt32 aLength ) - { - nsStr temp; - nsStr::Initialize(temp, eTwoByte); - temp.mUStr = NS_CONST_CAST(PRUnichar*, aBuffer); - - if ( aLength < 0 ) - aLength = nsCharTraits::length(aBuffer); - - if ( aLength > 0 ) - { - temp.mLength = aLength; - StrAppend(*this, temp, 0, aLength); - } - } - -/** - * Append the given integer to this string - * @update gess 01/04/99 - * @param aInteger: - * @param aRadix: - * @return - */ -void nsCString::AppendInt(PRInt32 anInteger,PRInt32 aRadix) { - - PRUint32 theInt=(PRUint32)anInteger; - - char buf[]={'0',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - PRInt32 radices[] = {1000000000,268435456}; - PRInt32 mask1=radices[16==aRadix]; - - PRInt32 charpos=0; - if(anInteger<0) { - theInt*=-1; - if(10==aRadix) { - buf[charpos++]='-'; - } - else theInt=(int)~(theInt-1); - } - - PRBool isfirst=PR_TRUE; - while(mask1>=1) { - PRInt32 theDiv=theInt/mask1; - if((theDiv) || (!isfirst)) { - buf[charpos++]="0123456789abcdef"[theDiv]; - isfirst=PR_FALSE; - } - theInt-=theDiv*mask1; - mask1/=aRadix; - } - Append(buf); -} - - -/** - * Append the given float to this string - * @update gess 01/04/99 - * @param aFloat: - * @return - */ -void nsCString::AppendFloat( double aFloat ){ - char buf[40]; - // *** XX UNCOMMENT THIS LINE - //PR_snprintf(buf, sizeof(buf), "%g", aFloat); - sprintf(buf,"%g",aFloat); - Append(buf); -} - -/** - * append given string to this string; - * @update gess 01/04/99 - * @param aString : string to be appended to this - * @return this - */ -void nsCString::AppendWithConversion(const nsString& aString,PRInt32 aCount) { - - if(aCount<0) - aCount=aString.mLength; - else aCount=MinInt(aCount,aString.mLength); - - if(0= PRInt32(sizeof(buf))) { - cp = aString.ToNewCString(); - } else { - aString.ToCString(cp, len + 1); - } - if(len>0) - ::fwrite(cp, 1, len, out); - if (cp != buf) { - delete[] cp; - } - return (int) len; -} - -/** - * Dumps the contents of the string to stdout - * @update gess 11/15/99 - */ -void nsCString::DebugDump(void) const { - - if(mStr && (eOneByte==mCharSize)) { - printf("\n%s",mStr); - } -} - -//---------------------------------------------------------------------- - -NS_ConvertUCS2toUTF8::NS_ConvertUCS2toUTF8( const nsAReadableString& aString ) - { - nsReadingIterator start; aString.BeginReading(start); - nsReadingIterator end; aString.EndReading(end); - - while (start != end) { - nsReadableFragment frag(start.fragment()); - Append(frag.mStart, frag.mEnd - frag.mStart); - start += start.size_forward(); - } - } - -void -NS_ConvertUCS2toUTF8::Append( const PRUnichar* aString, PRUint32 aLength ) - { - // Handle null string by just leaving us as a brand-new - // uninitialized nsCAutoString. - if (! aString) - return; - - // Caculate how many bytes we need - const PRUnichar* p; - PRInt32 count, utf8len; - for (p = aString, utf8len = 0, count = aLength; 0 != count && 0 != (*p); count--, p++) - { - if (! ((*p) & 0xFF80)) - utf8len += 1; // 0000 0000 - 0000 007F - else if (! ((*p) & 0xF800)) - utf8len += 2; // 0000 0080 - 0000 07FF - else - utf8len += 3; // 0000 0800 - 0000 FFFF - // Note: Surrogate pair needs 4 bytes, but in this calcuation - // we count it as 6 bytes. It will waste 2 bytes per surrogate pair - } - - // Make sure our buffer's big enough, so we don't need to do - // multiple allocations. - if(mLength+PRUint32(utf8len+1) > sizeof(mBuffer)) - SetCapacity(mLength+utf8len+1); - // |SetCapacity| normally doesn't guarantee the use we are putting it to here (see its interface comment in nsAWritableString.h), - // we can only use it since our local implementation, |nsCString::SetCapacity|, is known to do what we want - - char* out = mStr+mLength; - PRUint32 ucs4=0; - - for (p = aString, count = aLength; 0 != count && 0 != (*p); count--, p++) - { - if (0 == ucs4) - { - if (! ((*p) & 0xFF80)) - { - *out++ = (char)*p; - } - else if (! ((*p) & 0xF800)) - { - *out++ = 0xC0 | (char)((*p) >> 6); - *out++ = 0x80 | (char)(0x003F & (*p)); - } - else - { - if (0xD800 == (0xFC00 & (*p))) - { - // D800- DBFF - High Surrogate - // N = (H- D800) *400 + 10000 + ... - ucs4 = 0x10000 | ((0x03FF & (*p)) << 10); - } - else if (0xDC00 == (0xFC00 & (*p))) - { - // DC00- DFFF - Low Surrogate - // error here. We should hit High Surrogate first - // Do not output any thing in this case - } - else - { - *out++ = 0xE0 | (char)((*p) >> 12); - *out++ = 0x80 | (char)(0x003F & (*p >> 6)); - *out++ = 0x80 | (char)(0x003F & (*p) ); - } - } - } - else - { - if (0xDC00 == (0xFC00 & (*p))) - { - // DC00- DFFF - Low Surrogate - // N += ( L - DC00 ) - ucs4 |= (0x03FF & (*p)); - - // 0001 0000-001F FFFF - *out++ = 0xF0 | (char)(ucs4 >> 18); - *out++ = 0x80 | (char)(0x003F & (ucs4 >> 12)); - *out++ = 0x80 | (char)(0x003F & (ucs4 >> 6)); - *out++ = 0x80 | (char)(0x003F & ucs4) ; - } - else - { - // Got a High Surrogate but no low surrogate - // output nothing. - } - ucs4 = 0; - } - } - - *out = '\0'; // null terminate - mLength += utf8len; - } - - -/*********************************************************************** - IMPLEMENTATION NOTES: AUTOSTRING... - ***********************************************************************/ - - -/** - * Default constructor - * - */ -nsCAutoString::nsCAutoString() : nsCString(){ - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - -} - -nsCAutoString::nsCAutoString( const nsCString& aString ) : nsCString(){ - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - -nsCAutoString::nsCAutoString( const nsAReadableCString& aString ) : nsCString(){ - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - -nsCAutoString::nsCAutoString(const char* aCString) : nsCString() { - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aCString); -} - -/** - * Copy construct from ascii c-string - * @param aCString is a ptr to a 1-byte cstr - */ -nsCAutoString::nsCAutoString(const char* aCString,PRInt32 aLength) : nsCString() { - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aCString,aLength); -} - -/** - * Copy construct using an external buffer descriptor - * @param aBuffer -- descibes external buffer - */ -nsCAutoString::nsCAutoString(const CBufDescriptor& aBuffer) : nsCString() { - if(!aBuffer.mBuffer) { - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - } - else { - Initialize(*this,aBuffer.mBuffer,aBuffer.mCapacity,aBuffer.mLength,aBuffer.mCharSize,!aBuffer.mStackBased); - } - if(!aBuffer.mIsConst) - AddNullTerminator(*this); //this isn't really needed, but it guarantees that folks don't pass string constants. -} - -#if 0 -/** - * Copy construct from uni-string - * @param aString is a ptr to a unistr - */ -nsCAutoString::nsCAutoString(const PRUnichar* aString,PRInt32 aLength) : nsCString() { - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString,aLength); -} - -/** - * construct from an nsStr - * @param - */ -nsCAutoString::nsCAutoString(const nsStr& aString) : nsCString() { - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - - - -/** - * construct from a char - * @param - */ -nsCAutoString::nsCAutoString(PRUnichar aChar) : nsCString(){ - Initialize(*this,mBuffer,sizeof(mBuffer)-1,0,eOneByte,PR_FALSE); - AddNullTerminator(*this); - Append(aChar); -} -#endif - - -/** - * construct from a subsumeable string - * @update gess 1/4/99 - * @param reference to a subsumeString - */ -#if defined(AIX) || defined(XP_OS2_VACPP) -nsCAutoString::nsCAutoString(const nsSubsumeCStr& aSubsumeStr) :nsCString() { - nsSubsumeCStr temp(aSubsumeStr); // a temp is needed for the AIX and VAC++ compilers - CSubsume(*this,temp); -#else -nsCAutoString::nsCAutoString( nsSubsumeCStr& aSubsumeStr) :nsCString() { - CSubsume(*this,aSubsumeStr); -#endif // AIX || XP_OS2_VACPP -} - -/** - * deconstructor - * @param - */ -nsCAutoString::~nsCAutoString(){ -} - -void nsCAutoString::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { - if (aResult) { - *aResult = sizeof(*this) + mCapacity * mCharSize; - } -} - -nsSubsumeCStr::nsSubsumeCStr(nsStr& aString) : nsCString() { - CSubsume(*this,aString); -} - -nsSubsumeCStr::nsSubsumeCStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength) : nsCString() { - mUStr=aString; - mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength; - mOwnsBuffer=assumeOwnership; -} - -nsSubsumeCStr::nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength) : nsCString() { - mStr=aString; - mCapacity=mLength=(-1==aLength) ? strlen(aString) : aLength; - mOwnsBuffer=assumeOwnership; -} - - - diff --git a/xpcom/ds/nsString.h b/xpcom/ds/nsString.h deleted file mode 100644 index 1220ac752bcf..000000000000 --- a/xpcom/ds/nsString.h +++ /dev/null @@ -1,584 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Rick Gessner (original author) - * Scott Collins - */ - - -/*********************************************************************** - MODULE NOTES: - - See nsStr.h for a more general description of string classes. - - This version of the nsString class offers many improvements over the - original version: - 1. Wide and narrow chars - 2. Allocators - 3. Much smarter autostrings - 4. Subsumable strings - ***********************************************************************/ - -#ifndef _nsCString_ -#define _nsCString_ - -#include "nsString2.h" -#include "prtypes.h" -#include "nscore.h" -#include -#include "nsStr.h" -#include "nsIAtom.h" - -#include "nsAWritableString.h" - - -class NS_COM nsSubsumeCStr; - -class NS_COM nsCString : - public nsAWritableCString, - public nsStr { - -protected: - virtual const void* Implementation() const { return "nsCString"; } - virtual const char* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - virtual char* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); - -public: - /** - * Default constructor. - */ - nsCString(); - - /** - * This is our copy constructor - * @param reference to another nsCString - */ - nsCString(const nsCString& aString); - - explicit nsCString( const nsAReadableCString& ); - - explicit nsCString(const char*); - nsCString(const char*, PRInt32); - - /** - * This constructor takes a subsumestr - * @param reference to subsumestr - */ - explicit nsCString(nsSubsumeCStr& aSubsumeStr); - - /** - * Destructor - * - */ - virtual ~nsCString(); - - /** - * Retrieve the length of this string - * @return string length - */ - virtual PRUint32 Length() const { return mLength; } - - /** - * Retrieve the size of this string - * @return string length - */ - virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; - - - /** - * Call this method if you want to force a different string capacity - * @update gess7/30/98 - * @param aLength -- contains new length for mStr - * @return - */ - void SetLength(PRUint32 aLength); - - /** - * Sets the new length of the string. - * @param aLength is new string length. - * @return nada - */ - void SetCapacity(PRUint32 aLength); - - /********************************************************************** - Accessor methods... - *********************************************************************/ - - - /** - * Retrieve const ptr to internal buffer; DO NOT TRY TO FREE IT! - */ - const char* GetBuffer() const { return get(); } // to be deprecated, prefer |get()| - - const char* get() const { return mStr; } - - PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex); - - /********************************************************************** - Lexomorphic transforms... - *********************************************************************/ - - /** - * Converts chars in this to lowercase - * @update gess 7/27/98 - */ - void ToLowerCase(); - - - /** - * Converts chars in this to lowercase, and - * stores them in aOut - * @update gess 7/27/98 - * @param aOut is a string to contain result - */ - void ToLowerCase(nsCString& aString) const; - - /** - * Converts chars in this to uppercase - * @update gess 7/27/98 - */ - void ToUpperCase(); - - /** - * Converts chars in this to lowercase, and - * stores them in a given output string - * @update gess 7/27/98 - * @param aOut is a string to contain result - */ - void ToUpperCase(nsCString& aString) const; - - - /** - * This method is used to remove all occurances of the - * characters found in aSet from this string. - * - * @param aSet -- characters to be cut from this - * @return *this - */ - void StripChars(const char* aSet); - void StripChar(PRUnichar aChar,PRInt32 anOffset=0); - void StripChar(char aChar,PRInt32 anOffset=0) { StripChar((PRUnichar) (unsigned char)aChar,anOffset); } - - /** - * This method strips whitespace throughout the string - * - * @return this - */ - void StripWhitespace(); - - /** - * swaps occurence of 1 string for another - * - * @return this - */ - void ReplaceChar(PRUnichar aOldChar,PRUnichar aNewChar); - void ReplaceChar(const char* aSet,PRUnichar aNewChar); - - void ReplaceSubstring(const nsCString& aTarget,const nsCString& aNewValue); - void ReplaceSubstring(const char* aTarget,const char* aNewValue); - - /** - * This method trims characters found in aTrimSet from - * either end of the underlying string. - * - * @param aTrimSet -- contains chars to be trimmed from - * both ends - * @param aEliminateLeading - * @param aEliminateTrailing - * @param aIgnoreQuotes - * @return this - */ - void Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE,PRBool aIgnoreQuotes=PR_FALSE); - - /** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ - void CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE); - - /** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ - void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE); - - /********************************************************************** - string conversion methods... - *********************************************************************/ -//#ifndef STANDALONE_STRING_TESTS - operator char*() {return mStr;} - operator const char*() const {return (const char*)mStr;} -//#endif - - /** - * This method constructs a new nsCString that is a clone - * of this string. - * - */ - nsCString* ToNewString() const; - - /** - * Creates an ISOLatin1 clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @return ptr to new isolatin1 string - */ - char* ToNewCString() const; - - /** - * Creates a unicode clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @return ptr to new unicode string - */ - PRUnichar* ToNewUnicode() const; - - /** - * Copies data from internal buffer onto given char* buffer - * NOTE: This only copies as many chars as will fit in given buffer (clips) - * @param aBuf is the buffer where data is stored - * @param aBuflength is the max # of chars to move to buffer - * @return ptr to given buffer - */ - char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const; - - /** - * Perform string to float conversion. - * @param aErrorCode will contain error if one occurs - * @return float rep of string value - */ - float ToFloat(PRInt32* aErrorCode) const; - - - /** - * Perform string to int conversion. - * @param aErrorCode will contain error if one occurs - * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. - * @return int rep of string value, and possible (out) error code - */ - PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const; - - - /********************************************************************** - String manipulation methods... - *********************************************************************/ - - /** - * assign given string to this string - * @param aStr: buffer to be assigned to this - * @param aCount is the length of the given str (or -1) if you want me to determine its length - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return this - */ - - nsCString& operator=( const nsCString& aString ) { Assign(aString); return *this; } - nsCString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - nsCString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } - nsCString& operator=( char aChar ) { Assign(aChar); return *this; } - - void AssignWithConversion(const PRUnichar*,PRInt32=-1); - void AssignWithConversion( const nsString& aString ); - void AssignWithConversion( const nsAReadableString& aString ); - void AssignWithConversion(PRUnichar); - - /* - * Appends n characters from given string to this, - * - * @param aString is the source to be appended to this - * @param aCount -- number of chars to copy; -1 tells us to compute the strlen for you - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return number of chars copied - */ - - void AppendWithConversion(const nsString&, PRInt32=-1); - void AppendWithConversion(PRUnichar aChar); - void AppendWithConversion( const nsAReadableString& aString ); - void AppendWithConversion(const PRUnichar*, PRInt32=-1); - // Why no |AppendWithConversion(const PRUnichar*, PRInt32)|? --- now I know, because implicit construction hid the need for this routine - void AppendInt(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16 - void AppendFloat( double aFloat ); - - virtual void do_AppendFromReadable( const nsAReadableCString& ); - - void InsertWithConversion(PRUnichar aChar,PRUint32 anOffset); - // Why no |InsertWithConversion(PRUnichar*)|? - - virtual void do_InsertFromReadable( const nsAReadableCString&, PRUint32 ); - - - /********************************************************************** - Searching methods... - *********************************************************************/ - - - /** - * 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 - * @return offset in string, or -1 (kNotFound) - */ - PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - - /** - * Search for given char within this string - * - * @param aString is substring to be sought in this - * @param anOffset tells us where in this strig to start searching - * @param aIgnoreCase selects case sensitivity - * @param aCount tells us how many iterations to make starting at the given offset - * @return find pos in string, or -1 (kNotFound) - */ - PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - - /** - * This method searches this string for the first character - * found in the given charset - * @param aString contains set of chars to be found - * @param anOffset tells us where to start searching in this - * @return -1 if not found, else the offset in this - */ - PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=0) const; - - - /** - * This methods scans the string backwards, looking for the given string - * @param aString is substring to be sought in this - * @param aIgnoreCase tells us whether or not to do caseless compare - * @param aCount tells us how many iterations to make starting at the given offset - * @return offset in string, or -1 (kNotFound) - */ - PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - - - /** - * Search for given char within this string - * - * @param aString is substring to be sought in this - * @param anOffset tells us where in this strig to start searching - * @param aIgnoreCase selects case sensitivity - * @return find pos in string, or -1 (kNotFound) - */ - PRInt32 RFindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - - /** - * This method searches this string for the last character - * found in the given string - * @param aString contains set of chars to be found - * @param anOffset tells us where to start searching in this - * @return -1 if not found, else the offset in this - */ - PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const; - PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const; - PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const; - - - - /********************************************************************** - Comparison methods... - *********************************************************************/ - - /** - * Compares a given string type to this string. - * @update gess 7/27/98 - * @param S is the string to be compared - * @param aIgnoreCase tells us how to treat case - * @param aCount tells us how many chars to compare - * @return -1,0,1 - */ - PRInt32 CompareWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRInt32 CompareWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - - PRBool EqualsWithConversion(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRBool EqualsWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRBool EqualsWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - - PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const; - PRBool EqualsIgnoreCase(const PRUnichar* aString,PRInt32 aCount=-1) const; - - - void DebugDump(void) const; - - - static void Recycle(nsCString* aString); - static nsCString* CreateString(void); - -private: - // NOT TO BE IMPLEMENTED - // these signatures help clients not accidentally call the wrong thing helped by C++ automatic integral promotion - void operator=( PRUnichar ); - void AssignWithConversion( char ); - void AssignWithConversion( const char*, PRInt32=-1 ); - void AppendWithConversion( char ); - void InsertWithConversion( char, PRUint32 ); -}; - -// NS_DEF_STRING_COMPARISON_OPERATORS(nsCString, char) -NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCString, char) - -extern NS_COM int fputs(const nsCString& aString, FILE* out); -//ostream& operator<<(ostream& aStream,const nsCString& aString); -//virtual void DebugDump(ostream& aStream) const; - - -/************************************************************** - Here comes the AutoString class which uses internal memory - (typically found on the stack) for its default buffer. - If the buffer needs to grow, it gets reallocated on the heap. - **************************************************************/ - -class NS_COM nsCAutoString : public nsCString { -public: - - virtual ~nsCAutoString(); - - nsCAutoString(); - explicit nsCAutoString(const nsCString& ); - explicit nsCAutoString(const nsAReadableCString& aString); - explicit nsCAutoString(const char* aString); - nsCAutoString(const char* aString,PRInt32 aLength); - explicit nsCAutoString(const CBufDescriptor& aBuffer); - -#if defined(AIX) || defined(XP_OS2_VACPP) - explicit nsCAutoString(const nsSubsumeCStr& aSubsumeStr); // AIX and VAC++ require a const -#else - explicit nsCAutoString(nsSubsumeCStr& aSubsumeStr); -#endif // AIX || XP_OS2_VACPP - - - nsCAutoString& operator=( const nsCAutoString& aString ) { Assign(aString); return *this; } - private: - void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED - public: - nsCAutoString& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsCAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - nsCAutoString& operator=( const char* aPtr ) { Assign(aPtr); return *this; } - nsCAutoString& operator=( char aChar ) { Assign(aChar); return *this; } - - /** - * Retrieve the size of this string - * @return string length - */ - virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; - - char mBuffer[kDefaultStringSize]; -}; - -NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsCAutoString, char) - -/** - * A helper class that converts a UCS2 string to UTF8 - */ -class NS_COM NS_ConvertUCS2toUTF8 - : public nsCAutoString - /* - ... - */ - { - public: - explicit - NS_ConvertUCS2toUTF8( const PRUnichar* aString ) - { - Append( aString, ~PRUint32(0) /* MAXINT */); - } - - NS_ConvertUCS2toUTF8( const PRUnichar* aString, PRUint32 aLength ) - { - Append( aString, aLength ); - } - - explicit - NS_ConvertUCS2toUTF8( PRUnichar aChar ) - { - Append( &aChar, 1 ); - } - - explicit NS_ConvertUCS2toUTF8( const nsAReadableString& aString ); - - const char* get() const - { - return mStr; - } - - operator const char*() const // to be deprecated, prefer |get()| - { - return get(); - } - - protected: - void Append( const PRUnichar* aString, PRUint32 aLength ); - - private: - // NOT TO BE IMPLEMENTED - NS_ConvertUCS2toUTF8( char ); - }; - - -/*************************************************************** - The subsumestr class is very unusual. - It differs from a normal string in that it doesn't use normal - copy semantics when another string is assign to this. - Instead, it "steals" the contents of the source string. - - This is very handy for returning nsString classes as part of - an operator+(...) for example, in that it cuts down the number - of copy operations that must occur. - - You should probably not use this class unless you really know - what you're doing. - ***************************************************************/ -class NS_COM nsSubsumeCStr : public nsCString { -public: - explicit nsSubsumeCStr(nsStr& aString); - nsSubsumeCStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1); - nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1); - - nsSubsumeCStr& operator=( const nsSubsumeCStr& aString ) { Assign(aString); return *this; } - nsSubsumeCStr& operator=( const nsAReadableCString& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeCStr& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeCStr& operator=( const char* aPtr ) { Assign(aPtr); return *this; } - nsSubsumeCStr& operator=( char aChar ) { Assign(aChar); return *this; } -private: - void operator=( PRUnichar ); // NOT TO BE IMPLEMENTED -}; - - -#endif - - diff --git a/xpcom/ds/nsString2.cpp b/xpcom/ds/nsString2.cpp deleted file mode 100644 index c07c3aec7032..000000000000 --- a/xpcom/ds/nsString2.cpp +++ /dev/null @@ -1,1987 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Rick Gessner (original author) - * Scott Collins - */ - -#include -#include -#include -#include "nsString.h" -#include "nsDebug.h" -#include "nsDeque.h" - -#ifndef RICKG_TESTBED -#include "prdtoa.h" -#include "nsISizeOfHandler.h" -#endif - - -static const char* kPossibleNull = "Error: possible unintended null in string"; -static const char* kNullPointerError = "Error: unexpected null ptr"; -static const char* kWhitespace="\b\t\r\n "; - - -static void Subsume(nsStr& aDest,nsStr& aSource){ - if(aSource.mStr && aSource.mLength) { - if(aSource.mOwnsBuffer){ - nsStr::Destroy(aDest); - aDest.mStr=aSource.mStr; - aDest.mLength=aSource.mLength; - aDest.mCharSize=aSource.mCharSize; - aDest.mCapacity=aSource.mCapacity; - aDest.mOwnsBuffer=aSource.mOwnsBuffer; - aSource.mOwnsBuffer=PR_FALSE; - aSource.mStr=0; - } - else{ - nsStr::StrAssign(aDest,aSource,0,aSource.mLength); - } - } - else nsStr::StrTruncate(aDest,0); -} - - -/** - * Default constructor. - */ -nsString::nsString() { - Initialize(*this,eTwoByte); -} - -nsString::nsString(const PRUnichar* aString) { - Initialize(*this,eTwoByte); - Assign(aString); -} - -/** - * This constructor accepts a unicode string - * @update gess 1/4/99 - * @param aString is a ptr to a unichar string - * @param aLength tells us how many chars to copy from given aString - */ -nsString::nsString(const PRUnichar* aString,PRInt32 aCount) { - Initialize(*this,eTwoByte); - Assign(aString,aCount); -} - -/** - * This is our copy constructor - * @update gess 1/4/99 - * @param reference to another nsString - */ -nsString::nsString(const nsString& aString) { - Initialize(*this,eTwoByte); - StrAssign(*this,aString,0,aString.mLength); -} - -/** - * construct from subsumeable string - * @update gess 1/4/99 - * @param reference to a subsumeString - */ -#if defined(AIX) || defined(XP_OS2_VACPP) -nsString::nsString(const nsSubsumeStr& aSubsumeStr) { - Initialize(*this,eTwoByte); - - nsSubsumeStr temp(aSubsumeStr); // a temp is needed for the AIX and VAC++ compilers - Subsume(*this,temp); -#else -nsString::nsString(nsSubsumeStr& aSubsumeStr) { - Initialize(*this,eTwoByte); - - Subsume(*this,aSubsumeStr); -#endif /* AIX || XP_OS2_VACPP */ -} - -/** - * Destructor - * Make sure we call nsStr::Destroy. - */ -nsString::~nsString() { - nsStr::Destroy(*this); -} - -const PRUnichar* nsString::GetReadableFragment( nsReadableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const { - switch ( aRequest ) { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mUStr) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } -} - -PRUnichar* nsString::GetWritableFragment( nsWritableFragment& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) { - switch ( aRequest ) { - case kFirstFragment: - case kLastFragment: - case kFragmentAt: - aFragment.mEnd = (aFragment.mStart = mUStr) + mLength; - return aFragment.mStart + aOffset; - - case kPrevFragment: - case kNextFragment: - default: - return 0; - } -} - - -void -nsString::do_AppendFromElement( PRUnichar inChar ) - { - PRUnichar buf[2] = { 0, 0 }; - buf[0] = inChar; - - nsStr temp; - nsStr::Initialize(temp, eTwoByte); - temp.mUStr = buf; - temp.mLength = 1; - StrAppend(*this, temp, 0, 1); - } - - -nsString::nsString( const nsAReadableString& aReadable ) { - Initialize(*this,eTwoByte); - Assign(aReadable); -} - -void nsString::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { - if (aResult) { - *aResult = sizeof(*this) + mCapacity * mCharSize; - } -} - -/** - * This method truncates this string to given length. - * - * @update gess 01/04/99 - * @param anIndex -- new length of string - * @return nada - */ -void nsString::SetLength(PRUint32 anIndex) { - if ( anIndex > mCapacity ) - SetCapacity(anIndex); - // |SetCapacity| normally doesn't guarantee the use we are putting it to here (see its interface comment in nsAWritableString.h), - // we can only use it since our local implementation, |nsString::SetCapacity|, is known to do what we want - nsStr::StrTruncate(*this,anIndex); -} - - -/** - * Call this method if you want to force the string to a certain capacity; - * |SetCapacity(0)| discards associated storage. - * - * @param aNewCapacity -- desired minimum capacity - */ -void -nsString::SetCapacity( PRUint32 aNewCapacity ) - { - if ( aNewCapacity ) - { - if( aNewCapacity > mCapacity ) - GrowCapacity(*this, aNewCapacity); - AddNullTerminator(*this); - } - else - { - nsStr::Destroy(*this); - nsStr::Initialize(*this, eTwoByte); - } - } - -/********************************************************************** - Accessor methods... - *********************************************************************/ - - -//static char gChar=0; -/** - * - * @update gess1/4/99 - * @return ptr to internal buffer (if 1-byte), otherwise NULL - */ -const char* nsString::GetBuffer(void) const { - const char* result=(eOneByte==mCharSize) ? mStr : 0; - return result; -} - - -/** - * This method returns the internal unicode buffer. - * Now that we've factored the string class, this should never - * be able to return a 1 byte string. - * - * @update gess1/4/99 - * @return ptr to internal (2-byte) buffer; - */ -const PRUnichar* nsString::GetUnicode(void) const { - const PRUnichar* result=(eOneByte==mCharSize) ? 0 : mUStr; - return result; -} - -/** - * set a char inside this string at given index - * @param aChar is the char you want to write into this string - * @param anIndex is the ofs where you want to write the given char - * @return TRUE if successful - */ -PRBool nsString::SetCharAt(PRUnichar aChar,PRUint32 anIndex){ - PRBool result=PR_FALSE; - if(anIndex2)) { - theFirstChar=First(); - theLastChar=Last(); - if(theFirstChar==theLastChar) { - if(('\''==theFirstChar) || ('"'==theFirstChar)) { - Cut(0,1); - Truncate(mLength-1); - theQuotesAreNeeded=PR_TRUE; - } - else theFirstChar=0; - } - } - - nsStr::Trim(*this,aTrimSet,aEliminateLeading,aEliminateTrailing); - - if(aIgnoreQuotes && theQuotesAreNeeded) { - Insert(theFirstChar,0); - Append(theLastChar); - } - - } -} - -/** - * This method strips chars in given set from string. - * You can control whether chars are yanked from - * start and end of string as well. - * - * @update gess 3/31/98 - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ -void -nsString::CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading,PRBool aEliminateTrailing){ - if(aSet){ - ReplaceChar(aSet,aChar); - nsStr::CompressSet(*this,aSet,aEliminateLeading,aEliminateTrailing); - } -} - -/** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @update gess 3/31/98 - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ -void -nsString::CompressWhitespace( PRBool aEliminateLeading,PRBool aEliminateTrailing){ - CompressSet(kWhitespace,' ',aEliminateLeading,aEliminateTrailing); -} - -/********************************************************************** - string conversion methods... - *********************************************************************/ - -/** - * Creates a duplicate clone (ptr) of this string. - * @update gess 01/04/99 - * @return ptr to clone of this string - */ -nsString* nsString::ToNewString() const { - return new nsString(*this); -} - -/** - * Creates an ascii clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @update gess 02/24/00 - * @WARNING! Potential i18n issue here, since we're stepping down from 2byte chars to 1byte chars! - * @return ptr to new ascii string - */ -char* nsString::ToNewCString() const { - char* result = NS_STATIC_CAST(char*, nsMemory::Alloc(mLength + 1)); - if (result) { - CBufDescriptor desc(result, PR_TRUE, mLength + 1, 0); - nsCAutoString temp(desc); - temp.AssignWithConversion(*this); - } - return result; -} - -/** - * Creates an UTF8 clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @update ftang 09/10/99 - * @return ptr to new UTF8 string - * http://www.cis.ohio-state.edu/htbin/rfc/rfc2279.html - */ -char* nsString::ToNewUTF8String() const { - NS_ConvertUCS2toUTF8 temp(mUStr); - - char* result; - if (temp.mOwnsBuffer) { - // We allocated. Trick the string into not freeing its buffer to - // avoid an extra allocation. - result = temp.mStr; - - temp.mStr=0; - temp.mOwnsBuffer = PR_FALSE; - } - else { - // We didn't allocate a buffer, so we need to copy it out of the - // nsCAutoString's storage. - result = nsCRT::strdup(temp.mStr); - } - - return result; -} - -/** - * Creates an ascii clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @update gess 02/24/00 - * @return ptr to new ascii string - */ -PRUnichar* nsString::ToNewUnicode() const { - return nsCRT::strdup(mUStr); -} - -/** - * Copies contents of this string into he given buffer - * Note that if you provide me a buffer that is smaller than the length of - * this string, only the number of bytes that will fit are copied. - * - * @update gess 01/04/99 - * @param aBuf - * @param aBufLength -- size of your external buffer (including null) - * @param anOffset -- THIS IS NOT USED AT THIS TIME! - * @return - */ -char* nsString::ToCString(char* aBuf, PRUint32 aBufLength,PRUint32 anOffset) const{ - if(aBuf) { - - // NS_ASSERTION(mLength<=aBufLength,"buffer smaller than string"); - - CBufDescriptor theDescr(aBuf,PR_TRUE,aBufLength,0); - nsCAutoString temp(theDescr); - nsStr::StrAssign(temp, *this, anOffset, PR_MIN(mLength, aBufLength-1)); - temp.mStr=0; - } - return aBuf; -} - -/** - * Perform string to float conversion. - * @update gess 01/04/99 - * @param aErrorCode will contain error if one occurs - * @return float rep of string value - */ -float nsString::ToFloat(PRInt32* aErrorCode) const { - char buf[100]; - if (mLength > PRInt32(sizeof(buf)-1)) { - *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; - return 0.0f; - } - char* cp = ToCString(buf, sizeof(buf)); - float f = (float) PR_strtod(cp, &cp); - if (*cp != 0) { - *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE; - } - *aErrorCode = (PRInt32) NS_OK; - return f; -} - - -/** - * Perform decimal numeric string to int conversion. - * NOTE: In this version, we use the radix you give, even if it's wrong. - * @update gess 02/14/00 - * @param aErrorCode will contain error if one occurs - * @param aRadix tells us what base to expect the given string in. kAutoDetect tells us to determine the radix. - * @return int rep of string value - */ -PRInt32 nsString::ToInteger(PRInt32* anErrorCode,PRUint32 aRadix) const { - PRUnichar* cp=mUStr; - PRInt32 theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect) - PRInt32 result=0; - PRBool negate=PR_FALSE; - PRUnichar theChar=0; - - //initial value, override if we find an integer - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - - if(cp) { - - //begin by skipping over leading chars that shouldn't be part of the number... - - PRUnichar* endcp=cp+mLength; - PRBool done=PR_FALSE; - - while((cp='A') && (theChar<='F')) { - if(10==theRadix) { - if(kAutoDetect==aRadix){ - theRadix=16; - cp=first; //backup - result=0; - } - else { - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - result=0; - break; - } - } - else { - result = (theRadix * result) + ((theChar-'A')+10); - } - } - else if((theChar>='a') && (theChar<='f')) { - if(10==theRadix) { - if(kAutoDetect==aRadix){ - theRadix=16; - cp=first; //backup - result=0; - } - else { - *anErrorCode=NS_ERROR_ILLEGAL_VALUE; - result=0; - break; - } - } - else { - result = (theRadix * result) + ((theChar-'a')+10); - } - } - else if(('X'==theChar) || ('x'==theChar) || ('#'==theChar) || ('+'==theChar)) { - continue; - } - else { - //we've encountered a char that's not a legal number or sign - break; - } - } //while - if(negate) - result=-result; - } //if - } - return result; -} - -/********************************************************************** - String manipulation methods... - *********************************************************************/ - - - -/** - * assign given char* to this string - * @update gess 01/04/99 - * @param aCString: buffer to be assigned to this - * @param aCount -- length of given buffer or -1 if you want me to compute length. - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return this - */ -void nsString::AssignWithConversion(const char* aCString,PRInt32 aCount) { - nsStr::StrTruncate(*this,0); - if(aCString){ - AppendWithConversion(aCString,aCount); - } -} - -void nsString::AssignWithConversion(const char* aCString) { - nsStr::StrTruncate(*this,0); - if(aCString){ - AppendWithConversion(aCString); - } -} - - -/** - * assign given char to this string - * @update gess 01/04/99 - * @param aChar: char to be assignd to this - * @return this - */ -void nsString::AssignWithConversion(char aChar) { - nsStr::StrTruncate(*this,0); - AppendWithConversion(aChar); -} - - -/** - * append given c-string to this string - * @update gess 01/04/99 - * @param aString : string to be appended to this - * @param aCount -- length of given buffer or -1 if you want me to compute length. - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return this - */ -void nsString::AppendWithConversion(const char* aCString,PRInt32 aCount) { - if(aCString && aCount){ //if astring is null or count==0 there's nothing to do - nsStr temp; - nsStr::Initialize(temp,eOneByte); - temp.mStr=(char*)aCString; - - if(0=1) { - PRInt32 theDiv=theInt/mask1; - if((theDiv) || (!isfirst)) { - buf[charpos++]="0123456789abcdef"[theDiv]; - isfirst=PR_FALSE; - } - theInt-=theDiv*mask1; - mask1/=aRadix; - } - AppendWithConversion(buf); -} - - -/** - * Append the given float to this string - * @update gess 01/04/99 - * @param aFloat: - * @return - */ -void nsString::AppendFloat(double aFloat){ - char buf[40]; - // *** XX UNCOMMENT THIS LINE - //PR_snprintf(buf, sizeof(buf), "%g", aFloat); - sprintf(buf,"%g",aFloat); - AppendWithConversion(buf); -} - - - -/** - * Insert a char* into this string at a specified offset. - * - * @update gess4/22/98 - * @param char* aCString to be inserted into this string - * @param anOffset is insert pos in str - * @param aCount -- length of given buffer or -1 if you want me to compute length. - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - * - * @return this - */ -void nsString::InsertWithConversion(const char* aCString,PRUint32 anOffset,PRInt32 aCount){ - if(aCString && aCount){ - nsStr temp; - nsStr::Initialize(temp,eOneByte); - temp.mStr=(char*)aCString; - - if(0GetUnicode(&unicode) != NS_OK || unicode == nsnull) - return PR_FALSE; - if (aIgnoreCase) - cmp=nsCRT::strcasecmp(mUStr,unicode); - else - cmp=nsCRT::strcmp(mUStr,unicode); - result=PRBool(0==cmp); - } - - return result; -} - -PRBool nsString::EqualsIgnoreCase(/*FIX: const */nsIAtom *aAtom) const { - return EqualsAtom(aAtom,PR_TRUE); -} - - -/** - * Determine if given char in valid alpha range - * - * @update gess 3/31/98 - * @param aChar is character to be tested - * @return TRUE if in alpha range - */ -PRBool nsString::IsAlpha(PRUnichar aChar) { - // XXX i18n - if (((aChar >= 'A') && (aChar <= 'Z')) || ((aChar >= 'a') && (aChar <= 'z'))) { - return PR_TRUE; - } - return PR_FALSE; -} - -/** - * Determine if given char is a valid space character - * - * @update gess 3/31/98 - * @param aChar is character to be tested - * @return TRUE if is valid space char - */ -PRBool nsString::IsSpace(PRUnichar aChar) { - // XXX i18n - if ((aChar == ' ') || (aChar == '\r') || (aChar == '\n') || (aChar == '\t')) { - return PR_TRUE; - } - return PR_FALSE; -} - -/** - * Determine if given buffer contains plain ascii - * - * @param aBuffer -- if null, then we test *this, otherwise we test given buffer - * @return TRUE if is all ascii chars, or if strlen==0 - */ -PRBool nsString::IsASCII(const PRUnichar* aBuffer) { - - if(!aBuffer) { - if(eOneByte==mCharSize) { - char* aByte = mStr; - while(*aByte) { - if(*aByte & 0x80) { // don't use (*aByte > 0x7F) since char is signed - return PR_FALSE; - } - aByte++; - } - return PR_TRUE; - } else { - aBuffer=mUStr; // let the following code handle it - } - } - if(aBuffer) { - while(*aBuffer) { - if(*aBuffer>0x007F){ - return PR_FALSE; - } - aBuffer++; - } - } - return PR_TRUE; -} - - -/** - * Determine if given char is valid digit - * - * @update gess 3/31/98 - * @param aChar is character to be tested - * @return TRUE if char is a valid digit - */ -PRBool nsString::IsDigit(PRUnichar aChar) { - // XXX i18n - return PRBool((aChar >= '0') && (aChar <= '9')); -} - -#ifndef RICKG_TESTBED -/************************************************************** - Define the string deallocator class... - **************************************************************/ -class nsStringDeallocator: public nsDequeFunctor{ -public: - virtual void* operator()(void* anObject) { - nsString* aString= (nsString*)anObject; - if(aString){ - delete aString; - } - return 0; - } -}; - -/**************************************************************************** - * This class, appropriately enough, creates and recycles nsString objects.. - ****************************************************************************/ - -class nsStringRecycler { -public: - nsStringRecycler() : mDeque(0) { - } - - ~nsStringRecycler() { - nsStringDeallocator theDeallocator; - mDeque.ForEach(theDeallocator); //now delete the strings - } - - void Recycle(nsString* aString) { - mDeque.Push(aString); - } - - nsString* CreateString(void){ - nsString* result=(nsString*)mDeque.Pop(); - if(!result) - result=new nsString(); - return result; - } - nsDeque mDeque; -}; -static nsStringRecycler& GetRecycler(void); - -/** - * - * @update gess 01/04/99 - * @param - * @return - */ -nsStringRecycler& GetRecycler(void){ - static nsStringRecycler gRecycler; - return gRecycler; -} -#endif - - -/** - * Call this mehod when you're done - * @update gess 01/04/99 - * @param - * @return - */ -nsString* nsString::CreateString(void){ - nsString* result=0; -#ifndef RICKG_TESTBED - GetRecycler().CreateString(); -#endif - return result; -} - -/** - * Call this mehod when you're done - * @update gess 01/04/99 - * @param - * @return - */ -void nsString::Recycle(nsString* aString){ -#ifndef RICKG_TESTBED - GetRecycler().Recycle(aString); -#else - delete aString; -#endif -} - -#if 0 - -/** - * - * @update gess8/8/98 - * @param - * @return - */ -ostream& operator<<(ostream& aStream,const nsString& aString){ - if(eOneByte==aString.mCharSize) { - aStream<= PRInt32(sizeof(buf))) { - cp = aString.ToNewCString(); - } else { - aString.ToCString(cp, len + 1); - } - if(len>0) - ::fwrite(cp, 1, len, out); - if (cp != buf) { - Recycle(cp); - } - return (int) len; -} - -/** - * Dumps the contents of the string to stdout - * @update gess 11/15/99 - */ -void nsString::DebugDump(void) const { - - const char* theBuffer=mStr; - nsCAutoString temp; - - if(eTwoByte==mCharSize) { - nsStr::StrAssign(temp, *this, 0, mLength); - theBuffer=temp.GetBuffer(); - } - - if(theBuffer) { - printf("\n%s",theBuffer); - } -} - - - -/*********************************************************************** - IMPLEMENTATION NOTES: AUTOSTRING... - ***********************************************************************/ - - -/** - * Default constructor - * - */ -nsAutoString::nsAutoString() : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); -} - -nsAutoString::nsAutoString(const PRUnichar* aString) : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - -/** - * Copy construct from uni-string - * @param aString is a ptr to a unistr - * @param aLength tells us how many chars to copy from aString - */ -nsAutoString::nsAutoString(const PRUnichar* aString,PRInt32 aLength) : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString,aLength); -} - -nsAutoString::nsAutoString( const nsString& aString ) - : nsString() -{ - Initialize(*this, mBuffer, (sizeof(mBuffer)>>eTwoByte)-1, 0, eTwoByte, PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - -nsAutoString::nsAutoString( const nsAReadableString& aString ) - : nsString() -{ - Initialize(*this, mBuffer, (sizeof(mBuffer)>>eTwoByte)-1, 0, eTwoByte, PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - - - -/** - * constructor that uses external buffer - * @param aBuffer describes the external buffer - */ -nsAutoString::nsAutoString(const CBufDescriptor& aBuffer) : nsString() { - if(!aBuffer.mBuffer) { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - } - else { - Initialize(*this,aBuffer.mBuffer,aBuffer.mCapacity,aBuffer.mLength,aBuffer.mCharSize,!aBuffer.mStackBased); - } - if(!aBuffer.mIsConst) - AddNullTerminator(*this); -} - -NS_ConvertASCIItoUCS2::NS_ConvertASCIItoUCS2( const char* aCString, PRUint32 aLength ) - { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - AppendWithConversion(aCString,aLength); - } - -NS_ConvertASCIItoUCS2::NS_ConvertASCIItoUCS2( const char* aCString ) - { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - AppendWithConversion(aCString); - } - -NS_ConvertASCIItoUCS2::NS_ConvertASCIItoUCS2( char aChar ) - { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - AppendWithConversion(aChar); - } - -void -NS_ConvertUTF8toUCS2::Init( const char* aCString, PRUint32 aLength ) -{ - // Handle null string by just leaving us as a brand-new - // uninitialized nsAutoString. - if (! aCString) - return; - - // Compute space required: do this once so we don't incur multiple - // allocations. This "optimization" is probably of dubious value... - const char* p; - PRUint32 count; - for (p = aCString, count = 0; *p && count < aLength; ++count) { - if ( 0 == (*p & 0x80) ) - p += 1; // ASCII - else if ( 0xC0 == (*p & 0xE0) ) - p += 2; // 2 byte UTF8 - else if ( 0xE0 == (*p & 0xF0) ) - p += 3; // 3 byte UTF8 - else if ( 0xF0 == (*p & 0xF8) ) - p += 4; // 4 byte UTF8 - else if ( 0xF8 == (*p & 0xFC) ) - p += 5; // 5 byte UTF8 - else if ( 0xFC == (*p & 0xFE) ) - p += 6; - else { - NS_ERROR("not a UTF-8 string"); - return; - } - } - - // Grow the buffer if we need to. - if ((count * sizeof(PRUnichar)) >= sizeof(mBuffer)) - SetCapacity(count + 1); - // |SetCapacity| normally doesn't guarantee the use we are putting it to here (see its interface comment in nsAWritableString.h), - // we can only use it since our local implementation, |nsString::SetCapacity|, is known to do what we want - - // We'll write directly into the new string's buffer - PRUnichar* out = mUStr; - - // Convert the characters. - for (p = aCString, count = 0; *p && count < aLength; ++count) { - char c = *p++; - - if( 0 == (0x80 & c)) { // ASCII - *out++ = PRUnichar(c); - continue; - } - - PRUint32 ucs4; - PRInt32 state = 0; - - if ( 0xC0 == (0xE0 & c) ) { // 2 bytes UTF8 - ucs4 = (PRUint32(c) << 6) & 0x000007C0L; - state = 1; - } - else if ( 0xE0 == (0xF0 & c) ) { // 3 bytes UTF8 - ucs4 = (PRUint32(c) << 12) & 0x0000F000L; - state = 2; - } - else if ( 0xF0 == (0xF8 & c) ) { // 4 bytes UTF8 - ucs4 = (PRUint32(c) << 18) & 0x001F0000L; - state = 3; - } - else if ( 0xF8 == (0xFC & c) ) { // 5 bytes UTF8 - ucs4 = (PRUint32(c) << 24) & 0x03000000L; - state = 4; - } - else if ( 0xFC == (0xFE & c) ) { // 6 bytes UTF8 - ucs4 = (PRUint32(c) << 30) & 0x40000000L; - state = 5; - } - else { - NS_ERROR("not a UTF8 string"); - break; - } - - while (state--) { - c = *p++; - - if ( 0x80 == (0xC0 & c) ) { - PRInt32 shift = state * 6; - ucs4 |= (PRUint32(c) & 0x3F) << shift; - } - else { - NS_ERROR("not a UTF8 string"); - goto done; // so we minimally clean up - } - } - - if (ucs4 >= 0x00010000) { - if (ucs4 >= 0x001F0000) { - *out++ = 0xFFFD; - } - else { - ucs4 -= 0x00010000; - *out++ = 0xD800 | (0x000003FF & (ucs4 >> 10)); - *out++ = 0xDC00 | (0x000003FF & ucs4); - } - } - else { - if (0xfeff != ucs4) // ignore BOM - *out++ = ucs4; - } - } - - done: - *out = '\0'; // null terminate - mLength = count; -} - -#if 0 -/** - * Copy construct from ascii c-string - * @param aCString is a ptr to a 1-byte cstr - * @param aLength tells us how many chars to copy from aCString - */ -nsAutoString::nsAutoString(const char* aCString,PRInt32 aLength) : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aCString,aLength); -} - -/** - * Copy construct from an nsStr - * @param - */ -nsAutoString::nsAutoString(const nsStr& aString) : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} -#endif - -/** - * Default copy constructor - */ -nsAutoString::nsAutoString(const nsAutoString& aString) : nsString() { - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aString); -} - - -/** - * Copy construct from a unichar - * @param - */ -nsAutoString::nsAutoString(PRUnichar aChar) : nsString(){ - Initialize(*this,mBuffer,(sizeof(mBuffer)>>eTwoByte)-1,0,eTwoByte,PR_FALSE); - AddNullTerminator(*this); - Append(aChar); -} - -/** - * construct from a subsumeable string - * @update gess 1/4/99 - * @param reference to a subsumeString - */ -#if defined(AIX) || defined(XP_OS2_VACPP) -nsAutoString::nsAutoString(const nsSubsumeStr& aSubsumeStr) :nsString() { - nsSubsumeStr temp(aSubsumeStr); // a temp is needed for the AIX and VAC++ compilers - Subsume(*this,temp); -#else -nsAutoString::nsAutoString( nsSubsumeStr& aSubsumeStr) :nsString() { - Subsume(*this,aSubsumeStr); -#endif // AIX || XP_OS2_VACPP -} - -/** - * deconstruct the autstring - * @param - */ -nsAutoString::~nsAutoString(){ -} - -void nsAutoString::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { - if (aResult) { - *aResult = sizeof(*this) + mCapacity * mCharSize; - } -} - -nsSubsumeStr::nsSubsumeStr() : nsString() { -} - -nsSubsumeStr::nsSubsumeStr(nsStr& aString) : nsString() { - ::Subsume(*this,aString); -} - -nsSubsumeStr::nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength) : nsString() { - mUStr=aString; - mCharSize=eTwoByte; - mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength; - mOwnsBuffer=assumeOwnership; -} - -nsSubsumeStr::nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength) : nsString() { - mStr=aString; - mCharSize=eOneByte; - mCapacity=mLength=(-1==aLength) ? strlen(aString) : aLength; - mOwnsBuffer=assumeOwnership; -} - -int nsSubsumeStr::Subsume(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength) { - mUStr=aString; - mCharSize=eTwoByte; - mCapacity=mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength; - mOwnsBuffer=assumeOwnership; - return 0; -} - diff --git a/xpcom/ds/nsString2.h b/xpcom/ds/nsString2.h deleted file mode 100644 index a5c9b65d6a65..000000000000 --- a/xpcom/ds/nsString2.h +++ /dev/null @@ -1,693 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * Rick Gessner (original author) - * Scott Collins - */ - - - -/*********************************************************************** - MODULE NOTES: - - See nsStr.h for a more general description of string classes. - - This version of the nsString class offers many improvements over the - original version: - 1. Wide and narrow chars - 2. Allocators - 3. Much smarter autostrings - 4. Subsumable strings - ***********************************************************************/ - -#ifndef _nsString_ -#define _nsString_ - -#include "prtypes.h" -#include "nscore.h" -#include -#include "nsString.h" -#include "nsIAtom.h" -#include "nsStr.h" -#include "nsCRT.h" - -#include "nsAWritableString.h" - -#ifdef STANDALONE_MI_STRING_TESTS - class nsAReadableString { public: virtual ~nsAReadableString() { } }; - class nsAWritableString : public nsAReadableString { public: virtual ~nsAWritableString() { } }; -#endif - -class nsISizeOfHandler; - - -#define nsString2 nsString -#define nsAutoString2 nsAutoString - -class NS_COM nsSubsumeStr; - -class NS_COM nsString : - public nsAWritableString, - public nsStr { - -protected: - virtual const void* Implementation() const { return "nsString"; } - virtual const PRUnichar* GetReadableFragment( nsReadableFragment&, nsFragmentRequest, PRUint32 ) const; - virtual PRUnichar* GetWritableFragment( nsWritableFragment&, nsFragmentRequest, PRUint32 ); - - -public: - /** - * Default constructor. - */ - nsString(); - - /** - * This is our copy constructor - * @param reference to another nsString - */ - nsString(const nsString& aString); - - explicit nsString(const nsAReadableString&); - - explicit nsString(const PRUnichar*); - nsString(const PRUnichar*, PRInt32); - - - /** - * This constructor takes a subsumestr - * @param reference to subsumestr - */ -#if defined(AIX) || defined(XP_OS2_VACPP) - explicit nsString(const nsSubsumeStr& aSubsumeStr); // AIX and VAC++ require a const here -#else - explicit nsString(nsSubsumeStr& aSubsumeStr); -#endif - - /** - * Destructor - * - */ - virtual ~nsString(); - - /** - * Retrieve the length of this string - * @return string length - */ - virtual PRUint32 Length() const { return mLength; } - - /** - * Retrieve the size of this string - * @return string length - */ - virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; - - - /** - * Call this method if you want to force a different string length - * @update gess7/30/98 - * @param aLength -- contains new length for mStr - * @return - */ - void SetLength(PRUint32 aLength); - - /** - * Sets the new length of the string. - * @param aLength is new string length. - * @return nada - */ - void SetCapacity(PRUint32 aLength); - - - /** - * Determine whether or not the characters in this - * string are in store as 1 or 2 byte (unicode) strings. - * - * @return TRUE if ordered. - */ - PRBool IsUnicode(void) const { - PRBool result=PRBool(mCharSize==eTwoByte); - return result; - } - - /********************************************************************** - Getters/Setters... - *********************************************************************/ - - /** - * Retrieve const ptr to internal buffer; DO NOT TRY TO FREE IT! - */ - const char* GetBuffer(void) const; - const PRUnichar* GetUnicode(void) const; - - /** - * Set nth character. - */ - PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex); - - - - /********************************************************************** - Lexomorphic transforms... - *********************************************************************/ - - - /** - * Converts chars in this to lowercase - * @update gess 7/27/98 - */ - void ToLowerCase(); - - - /** - * Converts chars in this to lowercase, and - * stores them in aOut - * @update gess 7/27/98 - * @param aOut is a string to contain result - */ - void ToLowerCase(nsString& aString) const; - - /** - * Converts chars in this to uppercase - * @update gess 7/27/98 - */ - void ToUpperCase(); - - /** - * Converts chars in this to lowercase, and - * stores them in a given output string - * @update gess 7/27/98 - * @param aOut is a string to contain result - */ - void ToUpperCase(nsString& aString) const; - - - /** - * This method is used to remove all occurances of the - * characters found in aSet from this string. - * - * @param aSet -- characters to be cut from this - * @return *this - */ - void StripChars( const char* aSet ); - void StripChar( PRUnichar aChar, PRInt32 anOffset=0 ); - void StripChar( char aChar, PRInt32 anOffset=0 ) { StripChar((PRUnichar) (unsigned char)aChar,anOffset); } - void StripChar( PRInt32 anInt, PRInt32 anOffset=0 ) { StripChar((PRUnichar)anInt,anOffset); } - - /** - * This method strips whitespace throughout the string - * - * @return this - */ - void StripWhitespace(); - - /** - * swaps occurence of 1 string for another - * - * @return this - */ - void ReplaceChar( PRUnichar anOldChar, PRUnichar aNewChar ); - void ReplaceChar( const char* aSet, PRUnichar aNewChar ); - - void ReplaceSubstring( const nsString& aTarget, const nsString& aNewValue ); - void ReplaceSubstring( const PRUnichar* aTarget, const PRUnichar* aNewValue ); - - /** - * This method trims characters found in aTrimSet from - * either end of the underlying string. - * - * @param aTrimSet -- contains chars to be trimmed from - * both ends - * @param aEliminateLeading - * @param aEliminateTrailing - * @param aIgnoreQuotes - * @return this - */ - void Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE,PRBool aIgnoreQuotes=PR_FALSE); - - /** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ - void CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE); - - /** - * This method strips whitespace from string. - * You can control whether whitespace is yanked from - * start and end of string as well. - * - * @param aEliminateLeading controls stripping of leading ws - * @param aEliminateTrailing controls stripping of trailing ws - * @return this - */ - void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE); - - /********************************************************************** - string conversion methods... - *********************************************************************/ - - /** - * This method constructs a new nsString is a clone of this string. - * - */ - nsString* ToNewString() const; - - /** - * Creates an ISOLatin1 clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @return ptr to new isolatin1 string - */ - char* ToNewCString() const; - - /** - * Creates an UTF8 clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @return ptr to new null-terminated UTF8 string - */ - char* ToNewUTF8String() const; - - /** - * Creates a unicode clone of this string - * Note that calls to this method should be matched with calls to Recycle(). - * @return ptr to new unicode string - */ - PRUnichar* ToNewUnicode() const; - - /** - * Copies data from internal buffer onto given char* buffer - * NOTE: This only copies as many chars as will fit in given buffer (clips) - * @param aBuf is the buffer where data is stored - * @param aBuflength is the max # of chars to move to buffer - * @return ptr to given buffer - */ - char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const; - - /** - * Perform string to float conversion. - * @param aErrorCode will contain error if one occurs - * @return float rep of string value - */ - float ToFloat(PRInt32* aErrorCode) const; - - /** - * Perform string to int conversion. - * @param aErrorCode will contain error if one occurs - * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you. - * @return int rep of string value, and possible (out) error code - */ - PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const; - - - /********************************************************************** - String manipulation methods... - *********************************************************************/ - - /** - * assign given string to this string - * @param aStr: buffer to be assigned to this - * @param aCount is the length of the given str (or -1) if you want me to determine its length - * NOTE: IFF you pass -1 as aCount, then your buffer must be null terminated. - - * @return this - */ - - nsString& operator=( const nsString& aString ) { Assign(aString); return *this; } - nsString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - nsString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } - nsString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } - - void AssignWithConversion(char); - void AssignWithConversion(const char*); - void AssignWithConversion(const char*, PRInt32); - - - /* - * Appends n characters from given string to this, - * This version computes the length of your given string - * - * @param aString is the source to be appended to this - * @return number of chars copied - */ - - void AppendInt(PRInt32, PRInt32=10); //radix=8,10 or 16 - void AppendFloat(double); - void AppendWithConversion(const char*, PRInt32=-1); - void AppendWithConversion(char); - - virtual void do_AppendFromElement( PRUnichar ); - - -//void InsertWithConversion(char); - void InsertWithConversion(const char*, PRUint32, PRInt32=-1); - - - /********************************************************************** - Searching methods... - *********************************************************************/ - - /** - * 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 - * @return offset in string, or -1 (kNotFound) - */ - PRInt32 Find(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - - - /** - * Search for given char within this string - * - * @param aString is substring to be sought in this - * @param anOffset tells us where in this strig to start searching - * @param aIgnoreCase selects case sensitivity - * @param aCount tells us how many iterations to make starting at the given offset - * @return find pos in string, or -1 (kNotFound) - */ - //PRInt32 Find(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const; - PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=0,PRInt32 aCount=-1) const; - - /** - * This method searches this string for the first character - * found in the given charset - * @param aString contains set of chars to be found - * @param anOffset tells us where to start searching in this - * @return -1 if not found, else the offset in this - */ - PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=0) const; - PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=0) const; - - - /** - * This methods scans the string backwards, looking for the given string - * @param aString is substring to be sought in this - * @param aIgnoreCase tells us whether or not to do caseless compare - * @param anOffset tells us where in this strig to start searching (counting from left) - * @param aCount tells us how many iterations to make starting at the given offset - * @return offset in string, or -1 (kNotFound) - */ - PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - PRInt32 RFind(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - - - /** - * Search for given char within this string - * - * @param aString is substring to be sought in this - * @param anOffset tells us where in this strig to start searching (counting from left) - * @param aIgnoreCase selects case sensitivity - * @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,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1,PRInt32 aCount=-1) const; - - /** - * This method searches this string for the last character - * found in the given string - * @param aString contains set of chars to be found - * @param anOffset tells us where in this strig to start searching (counting from left) - * @return -1 if not found, else the offset in this - */ - PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const; - PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const; - PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const; - - - /********************************************************************** - Comparison methods... - *********************************************************************/ - - /** - * Compares a given string type to this string. - * @update gess 7/27/98 - * @param S is the string to be compared - * @param aIgnoreCase tells us how to treat case - * @param aCount tells us how many chars to compare - * @return -1,0,1 - */ - - PRInt32 CompareWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRInt32 CompareWithConversion(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRInt32 CompareWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - - PRBool EqualsWithConversion(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRBool EqualsWithConversion(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRBool EqualsWithConversion(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const; - PRBool EqualsAtom(/*FIX: const */nsIAtom* anAtom,PRBool aIgnoreCase) const; - - PRBool EqualsIgnoreCase(const nsString& aString) const; - PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const; - PRBool EqualsIgnoreCase(/*FIX: const */nsIAtom *aAtom) const; - - - /** - * Determine if given buffer is plain ascii - * - * @param aBuffer -- if null, then we test *this, otherwise we test given buffer - * @return TRUE if is all ascii chars or if strlen==0 - */ - PRBool IsASCII(const PRUnichar* aBuffer=0); - - void DebugDump(void) const; - - /** - * Determine if given char is a valid space character - * - * @param aChar is character to be tested - * @return TRUE if is valid space char - */ - static PRBool IsSpace(PRUnichar ch); - - /** - * Determine if given char in valid alpha range - * - * @param aChar is character to be tested - * @return TRUE if in alpha range - */ - static PRBool IsAlpha(PRUnichar ch); - - /** - * Determine if given char is valid digit - * - * @param aChar is character to be tested - * @return TRUE if char is a valid digit - */ - static PRBool IsDigit(PRUnichar ch); - - static void Recycle(nsString* aString); - static nsString* CreateString(void); - -private: - // NOT TO BE IMPLEMENTED - // these signatures help clients not accidentally call the wrong thing helped by C++ automatic integral promotion - void operator=( char ); - void AssignWithConversion( PRUnichar ); - void AssignWithConversion( const PRUnichar*, PRInt32=-1 ); - void AppendWithConversion( PRUnichar ); - void AppendWithConversion( const PRUnichar*, PRInt32=-1 ); - void InsertWithConversion( const PRUnichar*, PRUint32, PRInt32=-1 ); -}; - -// NS_DEF_STRING_COMPARISON_OPERATORS(nsString, PRUnichar) -NS_DEF_DERIVED_STRING_OPERATOR_PLUS(nsString, PRUnichar) - -extern NS_COM int fputs(const nsString& aString, FILE* out); -//ostream& operator<<(ostream& aStream,const nsString& aString); -//virtual void DebugDump(ostream& aStream) const; - -/************************************************************** - Here comes the AutoString class which uses internal memory - (typically found on the stack) for its default buffer. - If the buffer needs to grow, it gets reallocated on the heap. - **************************************************************/ - -class NS_COM nsAutoString : public nsString { -public: - - virtual ~nsAutoString(); - nsAutoString(); - nsAutoString(const nsAutoString& aString); - explicit nsAutoString(const nsAReadableString& aString); - explicit nsAutoString(const nsString& aString); - explicit nsAutoString(const PRUnichar* aString); - nsAutoString(const PRUnichar* aString,PRInt32 aLength); - explicit nsAutoString(PRUnichar aChar); - explicit nsAutoString(const CBufDescriptor& aBuffer); - -#if defined(AIX) || defined(XP_OS2_VACPP) - explicit nsAutoString(const nsSubsumeStr& aSubsumeStr); // AIX and VAC++ requires a const -#else - explicit nsAutoString(nsSubsumeStr& aSubsumeStr); -#endif // AIX || XP_OS2_VACPP - - - nsAutoString& operator=( const nsAutoString& aString ) { Assign(aString); return *this; } - private: - void operator=( char ); // NOT TO BE IMPLEMENTED - public: - nsAutoString& operator=( const nsAReadableString& aReadable ) { Assign(aReadable); return *this; } - nsAutoString& operator=( const nsPromiseReadable& aReadable ) { Assign(aReadable); return *this; } - nsAutoString& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } - nsAutoString& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } - - /** - * Retrieve the size of this string - * @return string length - */ - virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; - - char mBuffer[kDefaultStringSize<& aReadable ) { Assign(aReadable); return *this; } - nsSubsumeStr& operator=( const PRUnichar* aPtr ) { Assign(aPtr); return *this; } - nsSubsumeStr& operator=( PRUnichar aChar ) { Assign(aChar); return *this; } -private: - void operator=( char ); // NOT TO BE IMPLEMENTED -}; - - -#endif - - diff --git a/xpcom/ds/nsXPIDLString.cpp b/xpcom/ds/nsXPIDLString.cpp deleted file mode 100644 index 0c59e6b581e8..000000000000 --- a/xpcom/ds/nsXPIDLString.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -#include "nsDebug.h" -#include "nsMemory.h" -#include "nsXPIDLString.h" -#include "plstr.h" - -// If the allocator changes, fix it here. -#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsMemory::Alloc((__len) * sizeof(PRUnichar))) -#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsMemory::Alloc((__len) * sizeof(char))) -#define XPIDL_FREE(__ptr) (nsMemory::Free(__ptr)) - -//////////////////////////////////////////////////////////////////////// -// nsXPIDLString - -nsXPIDLString::~nsXPIDLString() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); -} - - -PRUnichar* -nsXPIDLString::Copy(const PRUnichar* aString) -{ - NS_ASSERTION(aString, "null ptr"); - if (! aString) - return 0; - - PRInt32 len = 0; - - { - const PRUnichar* p = aString; - while (*p++) - len++; - } - - PRUnichar* result = XPIDL_STRING_ALLOC(len + 1); - if (result) { - PRUnichar* q = result; - while (*aString) { - *q = *aString; - q++; - aString++; - } - *q = '\0'; - } - return result; -} - - -PRUnichar** -nsXPIDLString::StartAssignmentByValue() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); - - mBuf = 0; - mBufOwner = PR_TRUE; - return &mBuf; -} - - -const PRUnichar** -nsXPIDLString::StartAssignmentByReference() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); - - mBuf = 0; - mBufOwner = PR_FALSE; - return (const PRUnichar**) &mBuf; -} - - -//////////////////////////////////////////////////////////////////////// -// nsXPIDLCString - -nsXPIDLCString::~nsXPIDLCString() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); -} - - -nsXPIDLCString& nsXPIDLCString::operator =(const char* aCString) -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); - - if (aCString) { - mBuf = Copy(aCString); - mBufOwner = PR_TRUE; - } - else { - mBuf = 0; - mBufOwner = PR_FALSE; - } - - return *this; -} - - -char* -nsXPIDLCString::Copy(const char* aCString) -{ - NS_ASSERTION(aCString, "null ptr"); - if (! aCString) - return 0; - - PRInt32 len = PL_strlen(aCString); - char* result = XPIDL_CSTRING_ALLOC(len + 1); - if (result) - PL_strcpy(result, aCString); - - return result; -} - - -char** -nsXPIDLCString::StartAssignmentByValue() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); - - mBuf = 0; - mBufOwner = PR_TRUE; - return &mBuf; -} - - -const char** -nsXPIDLCString::StartAssignmentByReference() -{ - if (mBufOwner && mBuf) - XPIDL_FREE(mBuf); - - mBuf = 0; - mBufOwner = PR_FALSE; - return (const char**) &mBuf; -} - - diff --git a/xpcom/ds/nsXPIDLString.h b/xpcom/ds/nsXPIDLString.h deleted file mode 100644 index 9f99d1a4a96b..000000000000 --- a/xpcom/ds/nsXPIDLString.h +++ /dev/null @@ -1,382 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * - * The contents of this file are subject to the Netscape Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/NPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1998 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - */ - -/* - - A set of string wrapper classes that ease transition to use of XPIDL - interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring' - and `string' out params as nsCOMPtr is to generic XPCOM interface - pointers. They help you deal with object ownership. - - Consider the following interface: - - interface nsIFoo { - attribute string Bar; - }; - - This will generate the following C++ header file: - - class nsIFoo { - NS_IMETHOD SetBar(const PRUnichar* aValue); - NS_IMETHOD GetBar(PRUnichar* *aValue); - }; - - The GetBar() method will allocate a copy of the nsIFoo object's - "bar" attribute, and leave you to deal with freeing it: - - nsIFoo* aFoo; // assume we get this somehow - PRUnichar* bar; - aFoo->GetFoo(&bar); - // Use bar here... - printf("bar is %s!\n", bar); - nsMemory::Free(bar); - - This makes your life harder, because you need to convolute your code - to ensure that you don't leak `bar'. - - Enter nsXPIDLString, which manages the ownership of the allocated - string, and automatically destroys it when the nsXPIDLString goes - out of scope: - - nsIFoo* aFoo; - nsXPIDLString bar; - aFoo->GetFoo( getter_Copies(bar) ); - // Use bar here... - printf("bar is %s!\n", (const char*) bar); - // no need to remember to nsMemory::Free(). - - Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it - painfully clear exactly what the code expects. You need to wrap an - nsXPIDLString object with either `getter_Copies()' or - `getter_Shares()' before passing it to a getter: these tell the - nsXPIDLString how ownership is being handled. - - In the case of `getter_Copies()', the callee is allocating a copy - (which is usually the case). In the case of `getter_Shares()', the - callee is returning a const reference to `the real deal' (this can - be done using the [shared] attribute in XPIDL). - - */ - -#ifndef nsXPIDLString_h__ -#define nsXPIDLString_h__ - -#include "nscore.h" -#include "nsCom.h" -#include "prtypes.h" - -#ifndef __PRUNICHAR__ -#define __PRUNICHAR__ -typedef PRUint16 PRUnichar; -#endif /* __PRUNICHAR__ */ - -//////////////////////////////////////////////////////////////////////// -// nsXPIDLString -// -// A wrapper for Unicode strings. With the |getter_Copies()| and -// |getter_Shares()| helper functions, this can be used instead of -// the "naked" |PRUnichar*| interface for |wstring| parameters in -// XPIDL interfaces. -// - -class NS_COM nsXPIDLString { -private: - PRUnichar* mBuf; - PRBool mBufOwner; - - PRUnichar** StartAssignmentByValue(); - const PRUnichar** StartAssignmentByReference(); - -public: - /** - * Construct a new, uninitialized wrapper for a Unicode string. - */ - nsXPIDLString() : mBuf(0), mBufOwner(PR_FALSE) {} - - virtual ~nsXPIDLString(); - - /** - * Return a reference to the immutable Unicode string. - */ - operator const PRUnichar*() const { return get(); } - - /** - * Return a reference to the immutable Unicode string. - */ - const PRUnichar* get() const { return mBuf; } - - /** - * Make a copy of the Unicode string. Use this function in the - * callee to ensure that the correct memory allocator is used. - */ - static PRUnichar* Copy(const PRUnichar* aString); - - // A helper class for assignment-by-value. This class is an - // implementation detail and should not be considered part of the - // public interface. - class NS_COM GetterCopies { - private: - nsXPIDLString& mXPIDLString; - - public: - GetterCopies(nsXPIDLString& aXPIDLString) - : mXPIDLString(aXPIDLString) {} - - operator PRUnichar**() { - return mXPIDLString.StartAssignmentByValue(); - } - - friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString); - }; - - friend class GetterCopies; - - // A helper class for assignment-by-reference. This class is an - // implementation detail and should not be considered part of the - // public interface. - class NS_COM GetterShares { - private: - nsXPIDLString& mXPIDLString; - - public: - GetterShares(nsXPIDLString& aXPIDLString) - : mXPIDLString(aXPIDLString) {} - - operator const PRUnichar**() { - return mXPIDLString.StartAssignmentByReference(); - } - - friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString); - }; - - friend class GetterShares; - -private: - // not to be implemented - nsXPIDLString(nsXPIDLString& /* aXPIDLString */) {} - void operator=(nsXPIDLString& /* aXPIDLString */) {} -}; - - -/** - * Use this function to "wrap" the nsXPIDLString object that is to - * receive an |out| value. - */ -inline nsXPIDLString::GetterCopies -getter_Copies(nsXPIDLString& aXPIDLString) -{ - return nsXPIDLString::GetterCopies(aXPIDLString); -} - -/** - * Use this function to "wrap" the nsXPIDLString object that is to - * receive a |[shared] out| value. - */ -inline nsXPIDLString::GetterShares -getter_Shares(nsXPIDLString& aXPIDLString) -{ - return nsXPIDLString::GetterShares(aXPIDLString); -} - - -// XXX THESE ARE NOT strcmp()! DON'T TRY TO USE THEM AS SUCH! -inline -PRBool -operator==(const PRUnichar* lhs, const nsXPIDLString& rhs) -{ - return lhs == NS_STATIC_CAST(const PRUnichar*, rhs); -} - -inline -PRBool -operator==(const nsXPIDLString& lhs, const PRUnichar* rhs) -{ - return NS_STATIC_CAST(const PRUnichar*, lhs) == rhs; -} - - -#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO - -inline -PRBool -operator==(int lhs, const nsXPIDLString& rhs) -{ - return NS_REINTERPRET_CAST(PRUnichar*, lhs) == NS_STATIC_CAST(const PRUnichar*, rhs); -} - -inline -PRBool -operator==(const nsXPIDLString& lhs, int rhs) -{ - return NS_STATIC_CAST(const PRUnichar*, lhs) == NS_REINTERPRET_CAST(PRUnichar*, rhs); -} - -#endif - -//////////////////////////////////////////////////////////////////////// -// nsXPIDLCString -// -// A wrapper for Unicode strings. With the |getter_Copies()| and -// |getter_Shares()| helper functions, this can be used instead of -// the "naked" |char*| interface for |string| parameters in XPIDL -// interfaces. -// - -class NS_COM nsXPIDLCString { -private: - char* mBuf; - PRBool mBufOwner; - - char** StartAssignmentByValue(); - const char** StartAssignmentByReference(); - -public: - /** - * Construct a new, uninitialized wrapper for a single-byte string. - */ - nsXPIDLCString() : mBuf(0), mBufOwner(PR_FALSE) {} - - virtual ~nsXPIDLCString(); - - /** - * Assign a single-byte string to this wrapper. Copies - * and owns the result. - */ - nsXPIDLCString& operator=(const char* aString); - - /** - * Return a reference to the immutable single-byte string. - */ - operator const char*() const { return get(); } - - /** - * Return a reference to the immutable single-byte string. - */ - const char* get() const { return mBuf; } - - /** - * Make a copy of the single-byte string. Use this function in the - * callee to ensure that the correct memory allocator is used. - */ - static char* Copy(const char* aString); - - // A helper class for assignment-by-value. This class is an - // implementation detail and should not be considered part of the - // public interface. - class NS_COM GetterCopies { - private: - nsXPIDLCString& mXPIDLString; - - public: - GetterCopies(nsXPIDLCString& aXPIDLString) - : mXPIDLString(aXPIDLString) {} - - operator char**() { - return mXPIDLString.StartAssignmentByValue(); - } - - friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString); - }; - - friend class GetterCopies; - - // A helper class for assignment-by-reference. This class is an - // implementation detail and should not be considered part of the - // public interface. - class NS_COM GetterShares { - private: - nsXPIDLCString& mXPIDLString; - - public: - GetterShares(nsXPIDLCString& aXPIDLString) - : mXPIDLString(aXPIDLString) {} - - operator const char**() { - return mXPIDLString.StartAssignmentByReference(); - } - - friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString); - }; - - friend class GetterShares; - -private: - // not to be implemented - nsXPIDLCString(nsXPIDLCString& /* aXPIDLString */) {} - void operator=(nsXPIDLCString& /* aXPIDLCString */) {} -}; - -/** - * Use this function to "wrap" the nsXPIDLCString object that is to - * receive an |out| value. - */ -inline nsXPIDLCString::GetterCopies -getter_Copies(nsXPIDLCString& aXPIDLString) -{ - return nsXPIDLCString::GetterCopies(aXPIDLString); -} - - -/** - * Use this function to "wrap" the nsXPIDLCString object that is to - * receive a |[shared] out| value. - */ -inline nsXPIDLCString::GetterShares -getter_Shares(nsXPIDLCString& aXPIDLString) -{ - return nsXPIDLCString::GetterShares(aXPIDLString); -} - -// XXX THESE ARE NOT strcmp()! DON'T TRY TO USE THEM AS SUCH! -inline -PRBool -operator==(const char* lhs, const nsXPIDLCString& rhs) -{ - return lhs == NS_STATIC_CAST(const char*, rhs); -} - -inline -PRBool -operator==(const nsXPIDLCString& lhs, const char* rhs) -{ - return NS_STATIC_CAST(const char*, lhs) == rhs; -} - -#ifdef HAVE_CPP_TROUBLE_COMPARING_TO_ZERO - -inline -PRBool -operator==(int lhs, const nsXPIDLCString& rhs) -{ - return NS_REINTERPRET_CAST(char*, lhs) == NS_STATIC_CAST(const char*, rhs); -} - -inline -PRBool -operator==(const nsXPIDLCString& lhs, int rhs) -{ - return NS_STATIC_CAST(const char*, lhs) == NS_REINTERPRET_CAST(char*, rhs); -} - -#endif - -#endif // nsXPIDLString_h__