// 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
// the implementation of all the functions below is exactly the same so factor
// it out
-#ifndef __WATCOMC__
-template <typename T>
+template <typename T, typename F>
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") );
;
}
-#define wxSTR2INT(val, b, func) return wxStringToIntType(c_str(), val, b, func)
-
-#else // __WATCOMC__
-
-// FIXME, TODO, ASAP !!! - ugly trick to make release for Open Watcom possible
-// without changing code flow for other compilers
-
-#define wxSTR2INT(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)(c_str(), &end, base); \
- \
- return !*end && (end != c_str()) && (errno != ERANGE)
-
-#endif // !__WATCOMC__/__WATCOMC__
-
bool wxString::ToLong(long *val, int base) const
{
- wxSTR2INT(val, base, wxStrtol);
+ return wxStringToIntType(c_str(), val, base, wxStrtol);
}
bool wxString::ToULong(unsigned long *val, int base) const
{
- wxSTR2INT(val, base, wxStrtoul);
+ return wxStringToIntType(c_str(), val, base, wxStrtoul);
}
bool wxString::ToLongLong(wxLongLong_t *val, int base) const
{
#ifdef wxHAS_STRTOLL
- wxSTR2INT(val, base, wxStrtoll);
+ return wxStringToIntType(c_str(), val, base, wxStrtoll);
#else
// TODO: implement this ourselves
wxUnusedVar(val);
bool wxString::ToULongLong(wxULongLong_t *val, int base) const
{
#ifdef wxHAS_STRTOLL
- wxSTR2INT(val, base, wxStrtoull);
+ return wxStringToIntType(c_str(), val, base, wxStrtoull);
#else
// TODO: implement this ourselves
wxUnusedVar(val);
// 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
{
{
// 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