X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e66eb2dfae8805989fddd8ad5ffceb3333f5cfdc..f24b783af3785e748b775409d926361e87e8eb13:/src/common/string.cpp?ds=sidebyside diff --git a/src/common/string.cpp b/src/common/string.cpp index 5770917d5f..78008c79a7 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -35,6 +35,11 @@ #endif #include + +#ifndef __WXWINCE__ + #include +#endif + #include #include @@ -174,8 +179,16 @@ void wxStringBase::InitWith(const wxChar *psz, size_t nPos, size_t nLength) // poor man's iterators are "void *" pointers wxStringBase::wxStringBase(const void *pStart, const void *pEnd) { - InitWith((const wxChar *)pStart, 0, - (const wxChar *)pEnd - (const wxChar *)pStart); + if ( pEnd >= pStart ) + { + InitWith((const wxChar *)pStart, 0, + (const wxChar *)pEnd - (const wxChar *)pStart); + } + else + { + wxFAIL_MSG( _T("pStart is not before pEnd") ); + Init(); + } } wxStringBase::wxStringBase(size_type n, wxChar ch) @@ -1064,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 @@ -1595,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()); } @@ -1666,45 +1684,87 @@ int wxString::Find(const wxChar *pszSub) const // conversion to numbers // ---------------------------------------------------------------------------- -bool wxString::ToLong(long *val, int base) const +// the implementation of all the functions below is exactly the same so factor +// it out + +template +bool wxStringToIntType(const wxChar *start, + T *val, + int base, + F func) { - wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToLong") ); + wxCHECK_MSG( val, false, _T("NULL output pointer") ); wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") ); - const wxChar *start = c_str(); +#ifndef __WXWINCE__ + errno = 0; +#endif + wxChar *end; - *val = wxStrtol(start, &end, base); + *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 - return !*end && (end != start); + // string was not empty to start with and no under/overflow occurred + return !*end && (end != start) +#ifndef __WXWINCE__ + && (errno != ERANGE) +#endif + ; +} + +bool wxString::ToLong(long *val, int base) const +{ + return wxStringToIntType(c_str(), val, base, wxStrtol); } bool wxString::ToULong(unsigned long *val, int base) const { - wxCHECK_MSG( val, false, _T("NULL pointer in wxString::ToULong") ); - wxASSERT_MSG( !base || (base > 1 && base <= 36), _T("invalid base") ); + return wxStringToIntType(c_str(), val, base, wxStrtoul); +} - const wxChar *start = c_str(); - wxChar *end; - *val = wxStrtoul(start, &end, base); +bool wxString::ToLongLong(wxLongLong_t *val, int base) const +{ +#ifdef wxHAS_STRTOLL + return wxStringToIntType(c_str(), val, base, wxStrtoll); +#else + // TODO: implement this ourselves + wxUnusedVar(val); + wxUnusedVar(base); + return false; +#endif // wxHAS_STRTOLL +} - // return true only if scan was stopped by the terminating NUL and if the - // string was not empty to start with - return !*end && (end != start); +bool wxString::ToULongLong(wxULongLong_t *val, int base) const +{ +#ifdef wxHAS_STRTOLL + return wxStringToIntType(c_str(), val, base, wxStrtoull); +#else + // TODO: implement this ourselves + wxUnusedVar(val); + wxUnusedVar(base); + return false; +#endif } 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; *val = wxStrtod(start, &end); // return true only if scan was stopped by the terminating NUL and if the - // string was not empty to start with - return !*end && (end != start); + // string was not empty to start with and no under/overflow occurred + return !*end && (end != start) +#ifndef __WXWINCE__ + && (errno != ERANGE) +#endif + ; } // --------------------------------------------------------------------------- @@ -1777,13 +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 ) + else if ( len >= size ) { - size = len; +#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 { @@ -2128,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]; + wxChar **pNew = new 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