// function wxVsnprintfA (A for ANSI), should also find one for Unicode
// strings in Unicode build
#ifdef __WXMSW__
- #ifdef __VISUALC__
+ #if defined(__VISUALC__) || defined(wxUSE_NORLANDER_HEADERS)
#define wxVsnprintfA _vsnprintf
#endif
#else // !Windows
return iLen;
#else // ANSI
- return wxVsnprintfA(buf, len, format, argptr);
+ // vsnprintf() will not terminate the string with '\0' if there is not
+ // enough place, but we want the string to always be NUL terminated
+ int rc = wxVsnprintfA(buf, len - 1, format, argptr);
+ if ( rc == -1 )
+ {
+ buf[len] = 0;
+ }
+
+ return rc;
#endif // Unicode/ANSI
}
// must not share string and must have enough space
wxStringData* pData = GetStringData();
- if ( pData->IsShared() || (nLen > pData->nAllocLength) ) {
+ if ( pData->IsShared() || pData->IsEmpty() ) {
// can't work with old buffer, get new one
pData->Unlock();
AllocBuffer(nLen);
}
else {
- // update the string length
+ if ( nLen > pData->nAllocLength ) {
+ // realloc the buffer instead of calling malloc() again, this is more
+ // efficient
+ STATISTICS_ADD(Length, nLen);
+
+ nLen += EXTRA_ALLOC;
+
+ wxStringData *pDataOld = pData;
+ pData = (wxStringData*)
+ realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(wxChar));
+ if ( !pData ) {
+ // out of memory
+ free(pDataOld);
+
+ // FIXME we're going to crash...
+ return;
+ }
+
+ pData->nAllocLength = nLen;
+ m_pchData = pData->data();
+ }
+
+ // now we have enough space, just update the string length
pData->nDataLength = nLen;
}
else {
nLen += EXTRA_ALLOC;
+ wxStringData *pDataOld = pData;
wxStringData *p = (wxStringData *)
realloc(pData, sizeof(wxStringData) + (nLen + 1)*sizeof(wxChar));
if ( p == NULL ) {
- // @@@ what to do on memory error?
+ // don't leak memory
+ free(pDataOld);
+
+ // FIXME what to do on memory error?
return;
}
{
wxStringData *pData = GetStringData();
- // this variable is unused in release build, so avoid the compiler warning by
- // just not declaring it
+ // this variable is unused in release build, so avoid the compiler warning
+ // by just not declaring it
#ifdef __WXDEBUG__
void *p =
#endif
realloc(pData, sizeof(wxStringData) + (pData->nDataLength + 1)*sizeof(wxChar));
+ // we rely on a reasonable realloc() implementation here - so far I haven't
+ // seen any which wouldn't behave like this
+
wxASSERT( p != NULL ); // can't free memory?
wxASSERT( p == pData ); // we're decrementing the size - block shouldn't move!
}
return npos;
}
-wxString wxString::substr(size_t nStart, size_t nLen) const
-{
- // npos means 'take all'
- if ( nLen == npos )
- nLen = 0;
-
- wxASSERT( nStart + nLen <= Len() );
-
- return wxString(c_str() + nStart, nLen == npos ? 0 : nLen);
-}
-
wxString& wxString::erase(size_t nStart, size_t nLen)
{
wxString strTmp(c_str(), nStart);