From dd1eaa89dd33ca69086b8a4f3f350d36f8a922f0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 15 Jul 1998 17:10:23 +0000 Subject: [PATCH] optimizations: more functions made inline, added Alloc()/Shrink() function for more precise control over string's memory git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@275 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/string.h | 247 ++++++++++++++++++++++++++---------------- src/common/string.cpp | 191 ++++++++++++-------------------- 2 files changed, 218 insertions(+), 220 deletions(-) diff --git a/include/wx/string.h b/include/wx/string.h index 1145fffbf4..e07f95d74d 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -6,7 +6,7 @@ // Created: 29/01/98 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifndef __WXSTRINGH__ @@ -26,17 +26,20 @@ #include #include #include +#include #ifndef WX_PRECOMP #include "wx/defs.h" // Robert Roebling - #include "wx/object.h" + #ifdef WXSTRING_IS_WXOBJECT + #include "wx/object.h" + #endif #endif #include "wx/debug.h" /** @name wxString library @memo Efficient wxString class [more or less] compatible with MFC CString, - wxWindows wxString and std::string and some handy functions + wxWindows wxString and std::string and some handy functions missing from string.h. */ //@{ @@ -45,7 +48,7 @@ // macros // --------------------------------------------------------------------------- -/** @name Macros +/** @name Macros @memo You can switch off wxString/std::string compatibility if desired */ /// compile the std::string compatibility functions @@ -65,7 +68,7 @@ #define ASSERT_VALID_INDEX(i) wxASSERT( (unsigned)(i) < Len() ) // --------------------------------------------------------------------------- -/** @name Global functions complementing standard C string library +/** @name Global functions complementing standard C string library @memo replacements for strlen() and portable strcasecmp() */ // --------------------------------------------------------------------------- @@ -78,7 +81,31 @@ inline size_t WXDLLEXPORT Strlen(const char *psz) { return psz ? strlen(psz) : 0; } /// portable strcasecmp/_stricmp -int WXDLLEXPORT Stricmp(const char *, const char *); +inline int WXDLLEXPORT Stricmp(const char *psz1, const char *psz2) +{ +#if defined(_MSC_VER) + return _stricmp(psz1, psz2); +#elif defined(__BORLANDC__) + return stricmp(psz1, psz2); +#elif defined(__UNIX__) || defined(__GNUWIN32__) + return strcasecmp(psz1, psz2); +#else + // almost all compilers/libraries provide this function (unfortunately under + // different names), that's why we don't implement our own which will surely + // be more efficient than this code (uncomment to use): + /* + register char c1, c2; + do { + c1 = tolower(*psz1++); + c2 = tolower(*psz2++); + } while ( c1 && (c1 == c2) ); + + return c1 - c2; + */ + + #error "Please define string case-insensitive compare for your OS/compiler" +#endif // OS/compiler +} // ---------------------------------------------------------------------------- // global data @@ -102,17 +129,17 @@ struct WXDLLEXPORT wxStringData nAllocLength; // allocated memory size // mimics declaration 'char data[nAllocLength]' - char* data() const { return (char*)(this + 1); } + char* data() const { return (char*)(this + 1); } // empty string has a special ref count so it's never deleted bool IsEmpty() const { return nRefs == -1; } bool IsShared() const { return nRefs > 1; } // lock/unlock - void Lock() { if ( !IsEmpty() ) nRefs++; } - void Unlock() { if ( !IsEmpty() && --nRefs == 0) delete (char *)this; } + void Lock() { if ( !IsEmpty() ) nRefs++; } + void Unlock() { if ( !IsEmpty() && --nRefs == 0) free(this); } - // if we had taken control over string memory (GetWriteBuf), it's + // if we had taken control over string memory (GetWriteBuf), it's // intentionally put in invalid state void Validate(bool b) { nRefs = b ? 1 : 0; } bool IsValid() const { return nRefs != 0; } @@ -129,9 +156,9 @@ struct WXDLLEXPORT wxStringData This class aims to be as compatible as possible with the new standard std::string class, but adds some additional functions and should be at least as efficient than the standard implementation. - - Performance note: it's more efficient to write functions which take - "const String&" arguments than "const char *" if you assign the argument + + Performance note: it's more efficient to write functions which take + "const String&" arguments than "const char *" if you assign the argument to another string. It was compiled and tested under Win32, Linux (libc 5 & 6), Solaris 5.5. @@ -140,7 +167,7 @@ struct WXDLLEXPORT wxStringData - ressource support (string tables in ressources) - more wide character (UNICODE) support - regular expressions support - + @memo A non-template portable wxString class implementing copy-on-write. @author VZ @version 1.3 @@ -157,15 +184,24 @@ struct WXDLLEXPORT wxStringData friend class wxArrayString; + // NB: this data must be here (before all other functions) to be sure that all + // inline functions are really inlined by all compilers +private: + // points to data preceded by wxStringData structure with ref count info + char *m_pchData; + + // accessor to string data + wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; } + public: /** @name constructors & dtor */ //@{ /// ctor for an empty string wxString(); /// copy ctor - wxString(const wxString& stringSrc); + wxString(const wxString& stringSrc); /// string containing nRepeat copies of ch - wxString(char ch, size_t nRepeat = 1); + wxString(char ch, size_t nRepeat = 1); /// ctor takes first nLength characters from C string wxString(const char *psz, size_t nLength = STRING_MAXLEN); /// from C string (for compilers using unsigned char) @@ -179,11 +215,19 @@ public: /** @name generic attributes & operations */ //@{ /// as standard strlen() - size_t Len() const { return GetStringData()->nDataLength; } + uint Len() const { return GetStringData()->nDataLength; } /// string contains any characters? - bool IsEmpty() const; + bool IsEmpty() const { return Len() == 0; } /// reinitialize string (and free data!) - void Empty(); + void Empty() + { + if ( GetStringData()->nDataLength != 0 ) + Reinit(); + + wxASSERT( GetStringData()->nDataLength == 0 ); + wxASSERT( GetStringData()->nAllocLength == 0 ); + } + /// Is an ascii value bool IsAscii() const; /// Is a number @@ -196,10 +240,10 @@ public: //@{ /// read access char GetChar(size_t n) const - { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } + { ASSERT_VALID_INDEX( n ); return m_pchData[n]; } /// read/write access char& GetWritableChar(size_t n) - { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } + { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } /// write access void SetChar(size_t n, char ch) { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); m_pchData[n] = ch; } @@ -208,7 +252,7 @@ public: char Last() const { wxASSERT( !IsEmpty() ); return m_pchData[Len() - 1]; } /// get writable last character - char& Last() + char& Last() { wxASSERT( !IsEmpty() ); CopyBeforeWrite(); return m_pchData[Len()-1]; } /// operator version of GetChar @@ -222,7 +266,7 @@ public: { ASSERT_VALID_INDEX( n ); CopyBeforeWrite(); return m_pchData[n]; } /// implicit conversion to C string - operator const char*() const { return m_pchData; } + operator const char*() const { return m_pchData; } /// explicit conversion to C string (use this with printf()!) const char* c_str() const { return m_pchData; } /// @@ -242,30 +286,37 @@ public: /// wxString& operator=(const wchar_t *pwz); //@} - + /** @name string concatenation */ //@{ /** @name in place concatenation */ //@{ /// string += string - void operator+=(const wxString& string); + void operator+=(const wxString& s) { (void)operator<<(s); } /// string += C string - void operator+=(const char *psz); + void operator+=(const char *psz) { (void)operator<<(psz); } /// string += char - void operator+=(char ch); + void operator+=(char ch) { (void)operator<<(ch); } //@} /** @name concatenate and return the result - left to right associativity of << allows to write + left to right associativity of << allows to write things like "str << str1 << str2 << ..." */ //@{ /// as += - wxString& operator<<(const wxString& string); + wxString& operator<<(const wxString& s) + { + wxASSERT( s.GetStringData()->IsValid() ); + + ConcatSelf(s.Len(), s); + return *this; + } /// as += - wxString& operator<<(char ch); + wxString& operator<<(const char *psz) + { ConcatSelf(Strlen(psz), psz); return *this; } /// as += - wxString& operator<<(const char *psz); + wxString& operator<<(char ch) { ConcatSelf(1, &ch); return *this; } //@} - + /** @name return resulting string */ //@{ /// @@ -280,10 +331,10 @@ public: friend wxString operator+(const char *psz, const wxString& string); //@} //@} - + /** @name string comparison */ //@{ - /** + /** case-sensitive comparaison @return 0 if equal, +1 if greater or -1 if less @see CmpNoCase, IsSameAs @@ -300,20 +351,20 @@ public: @return TRUE if strings are equal, FALSE otherwise @see Cmp, CmpNoCase */ - bool IsSameAs(const char *psz, bool bCase = TRUE) const + bool IsSameAs(const char *psz, bool bCase = TRUE) const { return !(bCase ? Cmp(psz) : CmpNoCase(psz)); } //@} - + /** @name other standard string operations */ //@{ /** @name simple sub-string extraction */ //@{ - /** - return substring starting at nFirst of length + /** + return substring starting at nFirst of length nCount (or till the end if nCount = default value) */ - wxString Mid(size_t nFirst, size_t nCount = STRING_MAXLEN) const; + wxString Mid(size_t nFirst, size_t nCount = STRING_MAXLEN) const; /// get first nCount characters wxString Left(size_t nCount) const; /// get all characters before the first occurence of ch @@ -331,9 +382,9 @@ public: /// (returns the whole string if ch not found) wxString Right(char ch) const; //@} - + /** @name case conversion */ - //@{ + //@{ /// wxString& MakeUpper(); /// @@ -349,7 +400,7 @@ public: /// truncate string to given length wxString& Truncate(size_t uiLen); //@} - + /** @name searching and replacing */ //@{ /// searching (return starting index, or -1 if not found) @@ -375,15 +426,21 @@ public: /// as vprintf(), returns the number of characters written or < 0 on error int PrintfV(const char* pszFormat, va_list argptr); //@} - + /** @name raw access to string memory */ //@{ - /** - get writable buffer of at least nLen bytes. + /// ensure that string has space for at least nLen characters + // only works if the data of this string is not shared + void Alloc(uint nLen); + /// minimize the string's memory + // only works if the data of this string is not shared + void Shrink(); + /** + get writable buffer of at least nLen bytes. Unget() *must* be called a.s.a.p. to put string back in a reasonable state! */ - char *GetWriteBuf(int nLen); + char *GetWriteBuf(uint nLen); /// call this immediately after GetWriteBuf() has been used void UngetWriteBuf(); //@} @@ -434,9 +491,9 @@ public: wxString& RemoveLast() { return Truncate(Len() - 1); } // Robert Roebling - + wxString& Remove(size_t nStart, size_t nLen) { return erase( nStart, nLen ); } - + size_t First( const char ch ) const { return find(ch); } size_t First( const char* psz ) const { return find(psz); } size_t First( const wxString &str ) const { return find(str); } @@ -451,10 +508,10 @@ public: #ifdef STD_STRING_COMPATIBILITY /** @name std::string compatibility functions */ - + /// an 'invalid' value for string index static const size_t npos; - + //@{ /** @name constructors */ //@{ @@ -470,7 +527,7 @@ public: /// return the length of the string size_t length() const { return Len(); } /// return the maximum size of the string - size_t max_size() const { return STRING_MAXLEN; } + size_t max_size() const { return STRING_MAXLEN; } /// resize the string, filling the space with c if c != 0 void resize(size_t nSize, char ch = '\0'); /// delete the contents of the string @@ -490,58 +547,58 @@ public: /** @name append something to the end of this one */ //@{ /// append a string - wxString& append(const wxString& str) + wxString& append(const wxString& str) { *this += str; return *this; } /// append elements str[pos], ..., str[pos+n] - wxString& append(const wxString& str, size_t pos, size_t n) + wxString& append(const wxString& str, size_t pos, size_t n) { ConcatSelf(n, str.c_str() + pos); return *this; } /// append first n (or all if n == npos) characters of sz - wxString& append(const char *sz, size_t n = npos) + wxString& append(const char *sz, size_t n = npos) { ConcatSelf(n == npos ? Strlen(sz) : n, sz); return *this; } /// append n copies of ch wxString& append(size_t n, char ch) { return Pad(n, ch); } //@} - + /** @name replaces the contents of this string with another one */ //@{ /// same as `this_string = str' wxString& assign(const wxString& str) { return (*this) = str; } /// same as ` = str[pos..pos + n] - wxString& assign(const wxString& str, size_t pos, size_t n) + wxString& assign(const wxString& str, size_t pos, size_t n) { return *this = wxString((const char *)str + pos, n); } /// same as `= first n (or all if n == npos) characters of sz' - wxString& assign(const char *sz, size_t n = npos) + wxString& assign(const char *sz, size_t n = npos) { return *this = wxString(sz, n); } /// same as `= n copies of ch' - wxString& assign(size_t n, char ch) + wxString& assign(size_t n, char ch) { return *this = wxString(ch, n); } //@} - - /** @name inserts something at position nPos into this one */ + + /** @name inserts something at position nPos into this one */ //@{ /// insert another string wxString& insert(size_t nPos, const wxString& str); /// insert n chars of str starting at nStart (in str) wxString& insert(size_t nPos, const wxString& str, size_t nStart, size_t n) - { return insert(nPos, wxString((const char *)str + nStart, n)); } + { return insert(nPos, wxString((const char *)str + nStart, n)); } /// insert first n (or all if n == npos) characters of sz wxString& insert(size_t nPos, const char *sz, size_t n = npos) { return insert(nPos, wxString(sz, n)); } /// insert n copies of ch - wxString& insert(size_t nPos, size_t n, char ch) + wxString& insert(size_t nPos, size_t n, char ch) { return insert(nPos, wxString(ch, n)); } //@} - + /** @name deletes a part of the string */ //@{ /// delete characters from nStart to nStart + nLen wxString& erase(size_t nStart = 0, size_t nLen = npos); //@} - + /** @name replaces a substring of this string with another one */ //@{ /// replaces the substring of length nLen starting at nStart @@ -549,14 +606,14 @@ public: /// replaces the substring with nCount copies of ch wxString& replace(size_t nStart, size_t nLen, size_t nCount, char ch); /// replaces a substring with another substring - wxString& replace(size_t nStart, size_t nLen, + wxString& replace(size_t nStart, size_t nLen, const wxString& str, size_t nStart2, size_t nLen2); /// replaces the substring with first nCount chars of sz - wxString& replace(size_t nStart, size_t nLen, + wxString& replace(size_t nStart, size_t nLen, const char* sz, size_t nCount); //@} //@} - + /// swap two strings void swap(wxString& str); @@ -564,14 +621,14 @@ public: //@{ /** All find() functions take the nStart argument which specifies the position to start the search on, the default value is 0. - + All functions return npos if there were no match. - - @name string search + + @name string search */ //@{ /** - @name find a match for the string/character in this string + @name find a match for the string/character in this string */ //@{ /// find a substring @@ -585,12 +642,12 @@ public: /// find the first occurence of character ch after nStart size_t find(char ch, size_t nStart = 0) const; - // wxWin compatibility - inline bool Contains(const wxString& str) { return (Find(str) != -1); } + // wxWin compatibility + inline bool Contains(const wxString& str) { return Find(str) != -1; } //@} - - /** + + /** @name rfind() family is exactly like find() but works right to left */ //@{ @@ -599,13 +656,13 @@ public: /// as find, but from the end // VC++ 1.5 can't cope with this syntax. #if ! (defined(_MSC_VER) && !defined(__WIN32__)) - size_t rfind(const char* sz, size_t nStart = npos, + size_t rfind(const char* sz, size_t nStart = npos, size_t n = npos) const; /// as find, but from the end size_t rfind(char ch, size_t nStart = npos) const; #endif //@} - + /** @name find first/last occurence of any character in the set */ @@ -616,7 +673,7 @@ public: size_t find_first_of(const char* sz, size_t nStart = 0) const; /// same as find(char, size_t) size_t find_first_of(char c, size_t nStart = 0) const; - + /// size_t find_last_of (const wxString& str, size_t nStart = npos) const; /// @@ -624,7 +681,7 @@ public: /// same as rfind(char, size_t) size_t find_last_of (char c, size_t nStart = npos) const; //@} - + /** @name find first/last occurence of any character not in the set */ @@ -635,7 +692,7 @@ public: size_t find_first_not_of(const char* s, size_t nStart = 0) const; /// size_t find_first_not_of(char ch, size_t nStart = 0) const; - + /// size_t find_last_not_of(const wxString& str, size_t nStart=npos) const; /// @@ -644,11 +701,11 @@ public: size_t find_last_not_of(char ch, size_t nStart = npos) const; //@} //@} - - /** - All compare functions return -1, 0 or 1 if the [sub]string + + /** + All compare functions return -1, 0 or 1 if the [sub]string is less, equal or greater than the compare() argument. - + @name comparison */ //@{ @@ -668,13 +725,9 @@ public: wxString substr(size_t nStart = 0, size_t nLen = npos) const; //@} #endif - -protected: - // points to data preceded by wxStringData structure with ref count info - char *m_pchData; - // accessor to string data - wxStringData* GetStringData() const { return (wxStringData*)m_pchData - 1; } +private: + // string (re)initialization functions // initializes the string to the empty value (must be called only from @@ -683,7 +736,7 @@ protected: // initializaes the string with (a part of) C-string void InitWith(const char *psz, size_t nPos = 0, size_t nLen = STRING_MAXLEN); // as Init, but also frees old data - inline void Reinit(); + void Reinit() { GetStringData()->Unlock(); Init(); } // memory allocation // allocates memory for string of lenght nLen @@ -692,12 +745,12 @@ protected: void AllocCopy(wxString&, int, int) const; // effectively copies data to string void AssignCopy(size_t, const char *); - + // append a (sub)string void ConcatCopy(int nLen1, const char *src1, int nLen2, const char *src2); void ConcatSelf(int nLen, const char *src); - // functions called before writing to the string: they copy it if there + // functions called before writing to the string: they copy it if there // other references (should be the only owner when writing) void CopyBeforeWrite(); void AllocBeforeWrite(size_t); @@ -710,7 +763,7 @@ protected: sizeof(char *)) we store these pointers instead. The cast to "String *" is really all we need to turn such pointer into a string! - Of course, it can be called a dirty hack, but we use twice less memory + Of course, it can be called a dirty hack, but we use twice less memory and this approach is also more speed efficient, so it's probably worth it. Usage notes: when a string is added/inserted, a new copy of it is created, @@ -744,6 +797,8 @@ public: void Clear(); /// preallocates memory for given number of items void Alloc(size_t nCount); + /// minimzes the memory usage (by freeing all extra memory) + void Shrink(); //@} /** @name simple accessors */ @@ -805,7 +860,7 @@ private: // Put back into class, since BC++ can't create precompiled header otherwise // --------------------------------------------------------------------------- -/** @name wxString comparaison functions +/** @name wxString comparaison functions @memo Comparaisons are case sensitive */ // --------------------------------------------------------------------------- @@ -848,7 +903,7 @@ inline bool operator>=(const char * s1, const wxString& s2) { return s2.Cmp(s1) //@} // --------------------------------------------------------------------------- -/** @name Global functions complementing standard C string library +/** @name Global functions complementing standard C string library @memo replacements for strlen() and portable strcasecmp() */ // --------------------------------------------------------------------------- diff --git a/src/common/string.cpp b/src/common/string.cpp index 3031ae6daf..bb02779aee 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -6,7 +6,7 @@ // Created: 29/01/98 // RCS-ID: $Id$ // Copyright: (c) 1998 Vadim Zeitlin -// Licence: wxWindows license +// Licence: wxWindows license ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -99,7 +99,7 @@ NAMESPACE istream& operator>>(NAMESPACE istream& is, wxString& WXUNUSED(str)) sb->sungetc(); break; } - + str += ch; if ( --w == 1 ) break; @@ -174,7 +174,7 @@ void wxString::InitWith(const char *psz, size_t nPos, size_t nLength) memcpy(m_pchData, psz + nPos, nLength*sizeof(char)); } } - + // take first nLength characters of C string psz // (default value of STRING_MAXLEN means take all the string) wxString::wxString(const char *psz, size_t nLength) @@ -186,8 +186,8 @@ wxString::wxString(const char *psz, size_t nLength) wxString::wxString(const unsigned char* psz, size_t nLength) { InitWith((const char *)psz, 0, nLength); -} - +} + #ifdef STD_STRING_COMPATIBILITY // ctor from a substring @@ -201,7 +201,7 @@ wxString::wxString(const wxString& str, size_t nPos, size_t nLen) // poor man's iterators are "void *" pointers wxString::wxString(const void *pStart, const void *pEnd) { - InitWith((const char *)pStart, 0, + InitWith((const char *)pStart, 0, (const char *)pEnd - (const char *)pStart); } @@ -236,8 +236,8 @@ void wxString::AllocBuffer(size_t nLen) // allocate memory: // 1) one extra character for '\0' termination // 2) sizeof(wxStringData) for housekeeping info - wxStringData* pData = (wxStringData*)new char[sizeof(wxStringData) + - (nLen + 1)*sizeof(char)]; + wxStringData* pData = (wxStringData*)malloc(sizeof(wxStringData) + + (nLen + 1)*sizeof(char)); pData->nRefs = 1; pData->data()[nLen] = '\0'; pData->nDataLength = nLen; @@ -245,23 +245,6 @@ void wxString::AllocBuffer(size_t nLen) m_pchData = pData->data(); // data starts after wxStringData } -// releases the string memory and reinits it -void wxString::Reinit() -{ - GetStringData()->Unlock(); - Init(); -} - -// wrapper around wxString::Reinit -void wxString::Empty() -{ - if ( GetStringData()->nDataLength != 0 ) - Reinit(); - - wxASSERT( GetStringData()->nDataLength == 0 ); - wxASSERT( GetStringData()->nAllocLength == 0 ); -} - // must be called before changing this string void wxString::CopyBeforeWrite() { @@ -292,8 +275,44 @@ void wxString::AllocBeforeWrite(size_t nLen) wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner } +// allocate enough memory for nLen characters +void wxString::Alloc(uint nLen) +{ + wxStringData *pData = GetStringData(); + if ( pData->nAllocLength <= nLen ) { + if ( pData->IsEmpty() ) + AllocBuffer(nLen); + else { + wxStringData *p = (wxStringData *) + realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(char)); + if ( p != NULL && p != pData ) { + // the call succeeded but the pointer changed + pData->Unlock(); + free(pData); + + p->nRefs = 1; + p->nAllocLength = nLen; + m_pchData = p->data(); + } + //else: do nothing: either the call failed or the pointer is unchanged + } + } + //else: we've already got enough +} + +// shrink to minimal size (releasing extra memory) +void wxString::Shrink() +{ + wxStringData *pData = GetStringData(); + void *p = realloc(pData, sizeof(wxStringData) + + (pData->nDataLength + 1)*sizeof(char)); + if ( p == NULL ) // huh? can't unallocate memory? unlikely but possible. + return; + wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move! +} + // get the pointer to writable buffer of (at least) nLen bytes -char *wxString::GetWriteBuf(int nLen) +char *wxString::GetWriteBuf(uint nLen) { AllocBeforeWrite(nLen); @@ -326,7 +345,7 @@ wxString::~wxString() // assignment operators // --------------------------------------------------------------------------- -// helper function: does real copy +// helper function: does real copy void wxString::AssignCopy(size_t nSrcLen, const char *pszSrcData) { if ( nSrcLen == 0 ) { @@ -396,7 +415,7 @@ wxString& wxString::operator=(const wchar_t *pwz) // concatenate two sources // NB: assume that 'this' is a new wxString object void wxString::ConcatCopy(int nSrc1Len, const char *pszSrc1Data, - int nSrc2Len, const char *pszSrc2Data) + int nSrc2Len, const char *pszSrc2Data) { int nNewLen = nSrc1Len + nSrc2Len; if ( nNewLen != 0 ) @@ -415,7 +434,7 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData) register wxStringData *pData = GetStringData(); // alloc new buffer if current is too small - if ( pData->IsShared() || + if ( pData->IsShared() || pData->nDataLength + nSrcLen > pData->nAllocLength ) { // we have to grow the buffer, use the ConcatCopy routine // (which will allocate memory) @@ -437,51 +456,6 @@ void wxString::ConcatSelf(int nSrcLen, const char *pszSrcData) } /* - * string may be concatenated with other string, C string or a character - */ - -void wxString::operator+=(const wxString& string) -{ - wxASSERT( string.GetStringData()->IsValid() ); - - ConcatSelf(string.Len(), string); -} - -void wxString::operator+=(const char *psz) -{ - ConcatSelf(Strlen(psz), psz); -} - -void wxString::operator+=(char ch) -{ - ConcatSelf(1, &ch); -} - -/* - * Same as above but return the result - */ - -wxString& wxString::operator<<(const wxString& string) -{ - wxASSERT( string.GetStringData()->IsValid() ); - - ConcatSelf(string.Len(), string); - return *this; -} - -wxString& wxString::operator<<(const char *psz) -{ - ConcatSelf(Strlen(psz), psz); - return *this; -} - -wxString& wxString::operator<<(char ch) -{ - ConcatSelf(1, &ch); - return *this; -} - -/* * concatenation functions come in 5 flavours: * string + string * char + string and string + char @@ -657,7 +631,7 @@ uint wxString::Replace(const char *szOld, const char *szNew, bool bReplaceAll) wxString strTemp; const char *pCurrent = m_pchData; - const char *pSubstr; + const char *pSubstr; while ( *pCurrent != '\0' ) { pSubstr = strstr(pCurrent, szOld); if ( pSubstr == NULL ) { @@ -699,7 +673,7 @@ bool wxString::IsAscii() const } return(TRUE); } - + bool wxString::IsWord() const { const char *s = (const char*) *this; @@ -709,7 +683,7 @@ bool wxString::IsWord() const } return(TRUE); } - + bool wxString::IsNumber() const { const char *s = (const char*) *this; @@ -720,10 +694,6 @@ bool wxString::IsNumber() const return(TRUE); } -// kludge: we don't have declaraton of wxStringData here, so we add offsets -// manually to get to the "length" field of wxStringData structure -bool wxString::IsEmpty() const { return Len() == 0; } - wxString wxString::Strip(stripType w) const { wxString s = *this; @@ -732,33 +702,6 @@ wxString wxString::Strip(stripType w) const return s; } -/// case-insensitive strcmp() (platform independent) -int Stricmp(const char *psz1, const char *psz2) -{ -#if defined(_MSC_VER) - return _stricmp(psz1, psz2); -#elif defined(__BORLANDC__) - return stricmp(psz1, psz2); -#elif defined(__UNIX__) || defined(__GNUWIN32__) - return strcasecmp(psz1, psz2); -#else - // almost all compilers/libraries provide this function (unfortunately under - // different names), that's why we don't implement our own which will surely - // be more efficient than this code (uncomment to use): - /* - register char c1, c2; - do { - c1 = tolower(*psz1++); - c2 = tolower(*psz2++); - } while ( c1 && (c1 == c2) ); - - return c1 - c2; - */ - - #error "Please define string case-insensitive compare for your OS/compiler" -#endif // OS/compiler -} - // --------------------------------------------------------------------------- // case conversion // --------------------------------------------------------------------------- @@ -776,7 +719,7 @@ wxString& wxString::MakeUpper() wxString& wxString::MakeLower() { CopyBeforeWrite(); - + for ( char *p = m_pchData; *p; p++ ) *p = (char)tolower(*p); @@ -993,8 +936,8 @@ wxString& wxString::insert(size_t nPos, const wxString& str) strcpy(pc + nPos + str.Len(), c_str() + nPos); strTmp.UngetWriteBuf(); *this = strTmp; - - return *this; + + return *this; } size_t wxString::find(const wxString& str, size_t nStart) const @@ -1003,7 +946,7 @@ size_t wxString::find(const wxString& str, size_t nStart) const wxASSERT( nStart <= Len() ); const char *p = strstr(c_str() + nStart, str); - + return p == NULL ? npos : p - c_str(); } @@ -1014,13 +957,13 @@ size_t wxString::find(const char* sz, size_t nStart, size_t n) const return find(wxString(sz, n == npos ? 0 : n), nStart); } #endif - + size_t wxString::find(char ch, size_t nStart) const { wxASSERT( nStart <= Len() ); const char *p = strchr(c_str() + nStart, ch); - + return p == NULL ? npos : p - c_str(); } @@ -1036,10 +979,10 @@ size_t wxString::rfind(const wxString& str, size_t nStart) const return p - str.Len() - c_str(); p--; } - + return npos; } - + // VC++ 1.5 can't cope with the default argument in the header. #if ! (defined(_MSC_VER) && !defined(__WIN32__)) size_t wxString::rfind(const char* sz, size_t nStart, size_t n) const @@ -1052,7 +995,7 @@ size_t wxString::rfind(char ch, size_t nStart) const wxASSERT( nStart <= Len() ); const char *p = strrchr(c_str() + nStart, ch); - + return p == NULL ? npos : p - c_str(); } #endif @@ -1090,7 +1033,7 @@ wxString& wxString::replace(size_t nStart, size_t nLen, const char *sz) strTmp.append(c_str(), nStart); strTmp += sz; strTmp.append(c_str() + nStart + nLen); - + *this = strTmp; return *this; } @@ -1100,13 +1043,13 @@ wxString& wxString::replace(size_t nStart, size_t nLen, size_t nCount, char ch) return replace(nStart, nLen, wxString(ch, nCount)); } -wxString& wxString::replace(size_t nStart, size_t nLen, +wxString& wxString::replace(size_t nStart, size_t nLen, const wxString& str, size_t nStart2, size_t nLen2) { return replace(nStart, nLen, str.substr(nStart2, nLen2)); } -wxString& wxString::replace(size_t nStart, size_t nLen, +wxString& wxString::replace(size_t nStart, size_t nLen, const char* sz, size_t nCount) { return replace(nStart, nLen, wxString(sz, nCount)); @@ -1158,7 +1101,7 @@ wxArrayString& wxArrayString::operator=(const wxArrayString& src) m_nCount = src.m_nCount; if ( m_nSize != 0 ) - m_pItems = new char *[m_nSize]; + m_pItems = new char *[m_nCount]; else m_pItems = NULL; @@ -1217,7 +1160,7 @@ void wxArrayString::Clear() { Free(); - m_nSize = + m_nSize = m_nCount = 0; DELETEA(m_pItems); @@ -1295,7 +1238,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex) Grow(); - memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex], + memmove(&m_pItems[nIndex + 1], &m_pItems[nIndex], (m_nCount - nIndex)*sizeof(char *)); str.GetStringData()->Lock(); @@ -1312,7 +1255,7 @@ void wxArrayString::Remove(size_t nIndex) // release our lock Item(nIndex).GetStringData()->Unlock(); - memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1], + memmove(&m_pItems[nIndex], &m_pItems[nIndex + 1], (m_nCount - nIndex - 1)*sizeof(char *)); m_nCount--; } -- 2.45.2