wxString *str = wxConstCast(m_str, wxString);
// convert the string:
+ //
+ // FIXME-UTF8: we'd like to do the conversion in the existing buffer (if we
+ // have it) but it's unfortunately not obvious to implement
+ // because we don't know how big buffer do we need for the
+ // given string length (in case of multibyte encodings, e.g.
+ // ISO-2022-JP or UTF-8 when internal representation is wchar_t)
+ //
+ // One idea would be to store more than just m_convertedToChar
+ // in wxString: then we could record the length of the string
+ // which was converted the last time and try to reuse the same
+ // buffer if the current length is not greater than it (this
+ // could still fail because string could have been modified in
+ // place but it would work most of the time, so we'd do it and
+ // only allocate the new buffer if in-place conversion returned
+ // an error). We could also store a bit saying if the string
+ // was modified since the last conversion (and update it in all
+ // operation modifying the string, of course) to avoid unneeded
+ // consequential conversions. But both of these ideas require
+ // adding more fields to wxString and require profiling results
+ // to be sure that we really gain enough from them to justify
+ // doing it.
wxCharBuffer buf(str->mb_str());
- // FIXME-UTF8: do the conversion in-place in the existing buffer
+ // if it failed, return empty string and not NULL to avoid crashes in code
+ // written with either wxWidgets 2 wxString or std::string behaviour in
+ // mind: neither of them ever returns NULL and so we shouldn't neither
+ if ( !buf )
+ return "";
+
if ( str->m_convertedToChar &&
strlen(buf) == strlen(str->m_convertedToChar) )
{
// convert the string:
wxWCharBuffer buf(str->wc_str());
+ // notice that here, unlike above in AsChar(), conversion can't fail as our
+ // internal UTF-8 is always well-formed -- or the string was corrupted and
+ // all bets are off anyhow
+
// FIXME-UTF8: do the conversion in-place in the existing buffer
if ( str->m_convertedToWChar &&
wxWcslen(buf) == wxWcslen(str->m_convertedToWChar) )
if ( !wcLen )
return wxCharBuffer("");
- return conv.cWC2MB(wcBuf, wcLen, NULL);
+ return conv.cWC2MB(wcBuf, wcLen+1, NULL);
}
#else // ANSI
{
// FIXME-UTF8: use wxUniChar::ToLower/ToUpper once added
- size_t idx = 0;
const_iterator i1 = begin();
const_iterator end1 = end();
const_iterator i2 = s.begin();
const_iterator end2 = s.end();
- for ( ; i1 != end1 && i2 != end2; ++idx, ++i1, ++i2 )
+ for ( ; i1 != end1 && i2 != end2; ++i1, ++i2 )
{
wxUniChar lower1 = (wxChar)wxTolower(*i1);
wxUniChar lower2 = (wxChar)wxTolower(*i2);
return FromAscii(ascii, wxStrlen(ascii));
}
-wxString wxString::FromAscii(const char ascii)
+wxString wxString::FromAscii(char ascii)
{
// What do we do with '\0' ?
// find last non-space character
reverse_iterator psz = rbegin();
while ( (psz != rend()) && wxSafeIsspace(*psz) )
- psz++;
+ ++psz;
// truncate at trailing space start
erase(psz.base(), end());
// find first non-space character
iterator psz = begin();
while ( (psz != end()) && wxSafeIsspace(*psz) )
- psz++;
+ ++psz;
// fix up data and length
erase(begin(), psz);