X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bca6a3a5553884d5e210706b144dc3855798934d..6fe7685d0cab06a5a7bc3d43e6845b2146db1af0:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index 6bfe815b8e..9b8823d05f 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -35,7 +35,11 @@ #endif #include -#include + +#ifndef __WXWINCE__ + #include +#endif + #include #include @@ -1073,16 +1077,21 @@ wxChar *wxString::GetWriteBuf(size_t nLen) // put string back in a reasonable state after GetWriteBuf void wxString::UngetWriteBuf() { - GetStringData()->nDataLength = wxStrlen(m_pchData); - GetStringData()->Validate(true); + UngetWriteBuf(wxStrlen(m_pchData)); } void wxString::UngetWriteBuf(size_t nLen) { - GetStringData()->nDataLength = nLen; - GetStringData()->Validate(true); + wxStringData * const pData = GetStringData(); + + wxASSERT_MSG( nLen < pData->nAllocLength, _T("buffer overrun") ); + + // the strings we store are always NUL-terminated + pData->data()[nLen] = _T('\0'); + pData->nDataLength = nLen; + pData->Validate(true); } -#endif +#endif // !wxUSE_STL // --------------------------------------------------------------------------- // data access @@ -1604,7 +1613,7 @@ wxString& wxString::Trim(bool bFromRight) reverse_iterator psz = rbegin(); while ( (psz != rend()) && wxSafeIsspace(*psz) ) psz++; - + // truncate at trailing space start erase(psz.base(), end()); } @@ -1677,68 +1686,46 @@ int wxString::Find(const wxChar *pszSub) const // the implementation of all the functions below is exactly the same so factor // it out -#ifndef __WATCOMC__ -template +template bool wxStringToIntType(const wxChar *start, T *val, int base, - T (*func)(const wxChar *, wxChar **, int)) + F func) { wxCHECK_MSG( val, false, _T("NULL output pointer") ); wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") ); +#ifndef __WXWINCE__ errno = 0; +#endif wxChar *end; *val = (*func)(start, &end, base); // return true only if scan was stopped by the terminating NUL and if the // string was not empty to start with and no under/overflow occurred - return !*end && (end != start) && (errno != ERANGE); -} - -#else - -// FIXME, TODO, ASAP !!! - ugly trick to make release for Open Watcom possible -// without changing code flow for other compilers - -#define wxStringToIntType(start, val, base, func) \ - wxCHECK_MSG( val, false, _T("NULL output pointer") ); \ - wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") ); \ - \ - errno = 0; \ - \ - wxChar *end; \ - *val = (*func)(start, &end, base); \ - \ - return !*end && (end != start) && (errno != ERANGE) - + return !*end && (end != start) +#ifndef __WXWINCE__ + && (errno != ERANGE) #endif + ; +} bool wxString::ToLong(long *val, int base) const { -#ifndef __WATCOMC__ - return -#endif - wxStringToIntType(c_str(), val, base, wxStrtol); + return wxStringToIntType(c_str(), val, base, wxStrtol); } bool wxString::ToULong(unsigned long *val, int base) const { -#ifndef __WATCOMC__ - return -#endif - wxStringToIntType(c_str(), val, base, wxStrtoul); + return wxStringToIntType(c_str(), val, base, wxStrtoul); } bool wxString::ToLongLong(wxLongLong_t *val, int base) const { #ifdef wxHAS_STRTOLL -#ifndef __WATCOMC__ - return -#endif - wxStringToIntType(c_str(), val, base, wxStrtoll); + return wxStringToIntType(c_str(), val, base, wxStrtoll); #else // TODO: implement this ourselves wxUnusedVar(val); @@ -1750,10 +1737,7 @@ bool wxString::ToLongLong(wxLongLong_t *val, int base) const bool wxString::ToULongLong(wxULongLong_t *val, int base) const { #ifdef wxHAS_STRTOLL -#ifndef __WATCOMC__ - return -#endif - wxStringToIntType(c_str(), val, base, wxStrtoull); + return wxStringToIntType(c_str(), val, base, wxStrtoull); #else // TODO: implement this ourselves wxUnusedVar(val); @@ -1766,7 +1750,9 @@ bool wxString::ToDouble(double *val) const { wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToDouble") ); +#ifndef __WXWINCE__ errno = 0; +#endif const wxChar *start = c_str(); wxChar *end; @@ -1774,7 +1760,11 @@ bool wxString::ToDouble(double *val) const // return true only if scan was stopped by the terminating NUL and if the // string was not empty to start with and no under/overflow occurred - return !*end && (end != start) && (errno != ERANGE); + return !*end && (end != start) +#ifndef __WXWINCE__ + && (errno != ERANGE) +#endif + ; } // --------------------------------------------------------------------------- @@ -1847,15 +1837,29 @@ int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) // buffer were large enough (newer standards such as Unix98) if ( len < 0 ) { +#if wxUSE_WXVSNPRINTF + // we know that our own implementation of wxVsnprintf() returns -1 + // only for a format error - thus there's something wrong with + // the user's format string + return -1; +#else // assume that system version only returns error if not enough space // still not enough, as we don't know how much we need, double the // current size of the buffer size *= 2; +#endif // wxUSE_WXVSNPRINTF/!wxUSE_WXVSNPRINTF } else if ( len >= size ) { +#if wxUSE_WXVSNPRINTF + // we know that our own implementation of wxVsnprintf() returns + // size+1 when there's not enough space but that's not the size + // of the required buffer! + size *= 2; // so we just double the current size of the buffer +#else // some vsnprintf() implementations NUL-terminate the buffer and // some don't in len == size case, to be safe always add 1 size = len + 1; +#endif } else // ok, there was enough space { @@ -2080,7 +2084,7 @@ void wxArrayString::Init(bool autoSort) { m_nSize = m_nCount = 0; - m_pItems = (wxChar **) NULL; + m_pItems = (const wxChar **) NULL; m_autoSort = autoSort; } @@ -2130,7 +2134,7 @@ void wxArrayString::Grow(size_t nIncrement) m_nSize = ARRAY_DEFAULT_INITIAL_SIZE; if (m_nSize < nIncrement) m_nSize = nIncrement; - m_pItems = new wxChar *[m_nSize]; + m_pItems = new const wxChar *[m_nSize]; } else { // otherwise when it's called for the first time, nIncrement would be 0 @@ -2143,7 +2147,7 @@ void wxArrayString::Grow(size_t nIncrement) if ( nIncrement < ndefIncrement ) nIncrement = ndefIncrement; m_nSize += nIncrement; - wxChar **pNew = new wxChar *[m_nSize]; + const wxChar **pNew = new const wxChar *[m_nSize]; // copy data to new location memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *)); @@ -2200,13 +2204,16 @@ void wxArrayString::Alloc(size_t nSize) { // only if old buffer was not big enough if ( nSize > m_nSize ) { - Free(); - wxDELETEA(m_pItems); - m_pItems = new wxChar *[nSize]; + const wxChar **pNew = new const wxChar *[nSize]; + if ( !pNew ) + return; + + memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *)); + delete [] m_pItems; + + m_pItems = pNew; m_nSize = nSize; } - - m_nCount = 0; } // minimizes the memory usage by freeing unused memory @@ -2215,7 +2222,7 @@ void wxArrayString::Shrink() // only do it if we have some memory to free if( m_nCount < m_nSize ) { // allocates exactly as much memory as we need - wxChar **pNew = new wxChar *[m_nCount]; + const wxChar **pNew = new const wxChar *[m_nCount]; // copy data to new location memcpy(pNew, m_pItems, m_nCount*sizeof(wxChar *)); @@ -2337,7 +2344,7 @@ size_t wxArrayString::Add(const wxString& str, size_t nInsert) str.GetStringData()->Lock(); // just append - m_pItems[m_nCount + i] = (wxChar *)str.c_str(); // const_cast + m_pItems[m_nCount + i] = str.c_str(); } size_t ret = m_nCount; m_nCount += nInsert; @@ -2362,7 +2369,7 @@ void wxArrayString::Insert(const wxString& str, size_t nIndex, size_t nInsert) for (size_t i = 0; i < nInsert; i++) { str.GetStringData()->Lock(); - m_pItems[nIndex + i] = (wxChar *)str.c_str(); + m_pItems[nIndex + i] = str.c_str(); } m_nCount += nInsert; } @@ -2398,7 +2405,7 @@ void wxArrayString::SetCount(size_t count) wxString s; while ( m_nCount < count ) - m_pItems[m_nCount++] = (wxChar *)s.c_str(); + m_pItems[m_nCount++] = s.c_str(); } // removes item from array (by index)