X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a1db4ad4a44c45644d4b4dd6dea701233f01d422..3bb63e5c806e7ef549673822dc6e4d40aa9dbec9:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index 32a0adab79..42863abaa8 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 licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -79,7 +79,7 @@ static const struct } g_strEmpty = { {-1, 0, 0}, wxT('\0') }; // empty C style string: points to 'string data' byte of g_strEmpty -extern const wxChar WXDLLEXPORT *wxEmptyString = &g_strEmpty.dummy; +extern const wxChar WXDLLIMPEXP_BASE *wxEmptyString = &g_strEmpty.dummy; // ---------------------------------------------------------------------------- // global functions @@ -160,6 +160,18 @@ wxSTD ostream& operator<<(wxSTD ostream& os, const wxString& str) #define STATISTICS_ADD(av, val) #endif // WXSTRING_STATISTICS +// =========================================================================== +// wxStringData class deallocation +// =========================================================================== + +#if defined(__VISUALC__) && defined(_MT) && !defined(_DLL) +# pragma message (__FILE__ ": building with Multithreaded non DLL runtime has a performance impact on wxString!") +void wxStringData::Free() +{ + free(this); +} +#endif + // =========================================================================== // wxString class core // =========================================================================== @@ -229,24 +241,39 @@ wxString::wxString(const void *pStart, const void *pEnd) // from multibyte string wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength) { - // first get necessary size - size_t nLen = psz ? conv.MB2WC((wchar_t *) NULL, psz, 0) : 0; + // first get the size of the buffer we need + size_t nLen; + if ( psz ) + { + // calculate the needed size ourselves or use a provide one + nLen = nLength == wxSTRING_MAXLEN ? conv.MB2WC(NULL, psz, 0) : nLength; + } + else + { + // nothing to convert + nLen = 0; + } - // nLength is number of *Unicode* characters here! - if ((nLen != (size_t)-1) && (nLen > nLength)) - nLen = nLength; + // anything to do? + if ( (nLen != 0) && (nLen != (size_t)-1) ) + { + if ( !AllocBuffer(nLen) ) + { + wxFAIL_MSG( _T("out of memory in wxString::wxString") ); + return; + } - // empty? - if ( (nLen != 0) && (nLen != (size_t)-1) ) { - if ( !AllocBuffer(nLen) ) { - wxFAIL_MSG( _T("out of memory in wxString::wxString") ); - return; + // MB2WC wants the buffer size, not the string length + if ( conv.MB2WC(m_pchData, psz, nLen + 1) != (size_t)-1 ) + { + // initialized ok + m_pchData[nLen] = 0; + return; + } + //else: the conversion failed -- leave the string empty (what else?) } - conv.MB2WC(m_pchData, psz, nLen); - } - else { + Init(); - } } #else // ANSI @@ -255,27 +282,38 @@ wxString::wxString(const char *psz, wxMBConv& conv, size_t nLength) // from wide string wxString::wxString(const wchar_t *pwz, wxMBConv& conv, size_t nLength) { - // first get necessary size - size_t nLen = 0; - if (pwz) - { - if (nLength == wxSTRING_MAXLEN) - nLen = conv.WC2MB((char *) NULL, pwz, 0); + // first get the size of the buffer we need + size_t nLen; + if ( pwz ) + { + // calculate the needed size ourselves or use a provide one + nLen = nLength == wxSTRING_MAXLEN ? conv.WC2MB(NULL, pwz, 0) : nLength; + } else - nLen = nLength; - } + { + // nothing to convert + nLen = 0; + } - // empty? - if ( (nLen != 0) && (nLen != (size_t)-1) ) { - if ( !AllocBuffer(nLen) ) { - wxFAIL_MSG( _T("out of memory in wxString::wxString") ); - return; + // anything to do? + if ( (nLen != 0) && (nLen != (size_t)-1) ) + { + if ( !AllocBuffer(nLen) ) + { + wxFAIL_MSG( _T("out of memory in wxString::wxString") ); + return; + } + + // WC2MB wants the buffer size, not the string length + if ( conv.WC2MB(m_pchData, pwz, nLen + 1) != (size_t)-1 ) + { + // initialized ok + return; + } + //else: the conversion failed -- leave the string empty (what else?) } - conv.WC2MB(m_pchData, pwz, nLen); - } - else { + Init(); - } } #endif // wxUSE_WCHAR_T @@ -583,7 +621,7 @@ wxString& wxString::operator=(const wchar_t *pwz) // --------------------------------------------------------------------------- // add something to this string -bool wxString::ConcatSelf(int nSrcLen, const wxChar *pszSrcData) +bool wxString::ConcatSelf(size_t nSrcLen, const wxChar *pszSrcData) { STATISTICS_ADD(SummandLength, nSrcLen); @@ -730,6 +768,16 @@ wxString wxString::FromAscii(const char *ascii) return res; } +wxString wxString::FromAscii(const char ascii) +{ + // What do we do with '\0' ? + + wxString res; + res += (wchar_t)(unsigned char) ascii; + + return res; +} + const wxCharBuffer wxString::ToAscii() const { // this will allocate enough space for the terminating NUL too @@ -910,8 +958,13 @@ wxString wxString::AfterFirst(wxChar ch) const } // replace first (or all) occurences of some substring with another one -size_t wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll) +size_t +wxString::Replace(const wxChar *szOld, const wxChar *szNew, bool bReplaceAll) { + // if we tried to replace an empty string we'd enter an infinite loop below + wxCHECK_MSG( szOld && *szOld && szNew, 0, + _T("wxString::Replace(): invalid parameter") ); + size_t uiCount = 0; // count of replacements made size_t uiOldLen = wxStrlen(szOld); @@ -1700,6 +1753,10 @@ wxString& wxString::replace(size_t nStart, size_t nLen, // ArrayString // ============================================================================ +#if !wxUSE_STL + +#include "wx/arrstr.h" + // size increment = min(50% of current size, ARRAY_MAXSIZE_INCREMENT) #define ARRAY_MAXSIZE_INCREMENT 4096 @@ -1752,7 +1809,7 @@ void wxArrayString::Copy(const wxArrayString& src) void wxArrayString::Grow(size_t nIncrement) { // only do it if no more place - if ( m_nCount == m_nSize ) { + if ( (m_nSize - m_nCount) < nIncrement ) { // if ARRAY_DEFAULT_INITIAL_SIZE were set to 0, the initially empty would // be never resized! #if ARRAY_DEFAULT_INITIAL_SIZE == 0 @@ -1853,6 +1910,8 @@ void wxArrayString::Shrink() } } +#if WXWIN_COMPATIBILITY_2_4 + // return a wxString[] as required for some control ctors. wxString* wxArrayString::GetStringArray() const { @@ -1868,6 +1927,8 @@ wxString* wxArrayString::GetStringArray() const return array; } +#endif // WXWIN_COMPATIBILITY_2_4 + // searches the array for an item (forward or backwards) int wxArrayString::Index(const wxChar *sz, bool bCase, bool bFromEnd) const { @@ -1998,7 +2059,7 @@ void wxArrayString::SetCount(size_t count) } // removes item from array (by index) -void wxArrayString::Remove(size_t nIndex, size_t nRemove) +void wxArrayString::RemoveAt(size_t nIndex, size_t nRemove) { wxCHECK_RET( nIndex < m_nCount, wxT("bad index in wxArrayString::Remove") ); wxCHECK_RET( nIndex + nRemove <= m_nCount, @@ -2021,7 +2082,7 @@ void wxArrayString::Remove(const wxChar *sz) wxCHECK_RET( iIndex != wxNOT_FOUND, wxT("removing inexistent element in wxArrayString::Remove") ); - Remove(iIndex); + RemoveAt(iIndex); } // ---------------------------------------------------------------------------- @@ -2056,7 +2117,7 @@ static wxArrayString::CompareFunction gs_compareFunction = NULL; static bool gs_sortAscending = TRUE; // function which is called by quick sort -extern "C" int LINKAGEMODE +extern "C" int wxC_CALLING_CONV // LINKAGEMODE wxStringCompareFunction(const void *first, const void *second) { wxString *strFirst = (wxString *)first; @@ -2089,16 +2150,16 @@ void wxArrayString::Sort(CompareFunction compareFunction) END_SORT(); } -void wxArrayString::Sort(bool reverseOrder) -{ - START_SORT(); +typedef int (wxC_CALLING_CONV * wxStringCompareFn)(const void *first, const void *second); - wxASSERT( !gs_compareFunction ); // must have been reset to NULL - gs_sortAscending = !reverseOrder; - - DoSort(); +void wxArrayString::Sort(CompareFunction2 compareFunction) +{ + qsort(m_pItems, m_nCount, sizeof(wxChar *), (wxStringCompareFn)compareFunction); +} - END_SORT(); +void wxArrayString::Sort(bool reverseOrder) +{ + Sort(reverseOrder ? wxStringSortDescending : wxStringSortAscending); } void wxArrayString::DoSort() @@ -2124,3 +2185,14 @@ bool wxArrayString::operator==(const wxArrayString& a) const return TRUE; } +#endif // !wxUSE_STL + +int wxStringSortAscending(wxString* s1, wxString* s2) +{ + return wxStrcmp(s1->c_str(), s2->c_str()); +} + +int wxStringSortDescending(wxString* s1, wxString* s2) +{ + return -wxStrcmp(s1->c_str(), s2->c_str()); +}