// Lightweight object returned by wxString::c_str() and implicitly convertible
// to either const char* or const wchar_t*.
-class WXDLLIMPEXP_BASE wxCStrData
+class wxCStrData
{
private:
// Ctors; for internal use by wxString and wxCStrData only
wxCStrData operator-(ptrdiff_t n) const
{
wxASSERT_MSG( n <= (ptrdiff_t)m_offset,
- _T("attempt to construct address before the beginning of the string") );
+ wxT("attempt to construct address before the beginning of the string") );
return wxCStrData(m_str, m_offset - n, m_owned);
}
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
// "non dll-interface class 'wxStringPrintfMixin' used as base interface
// for dll-interface class 'wxString'" -- this is OK in our case
+ #pragma warning (push)
#pragma warning (disable:4275)
#endif
{ return iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); }
private:
- iterator(wxString *str, underlying_iterator ptr)
- : m_cur(ptr), m_node(str, &m_cur) {}
+ iterator(wxString *wxstr, underlying_iterator ptr)
+ : m_cur(ptr), m_node(wxstr, &m_cur) {}
wxString* str() const { return const_cast<wxString*>(m_node.m_str); }
private:
// for internal wxString use only:
- const_iterator(const wxString *str, underlying_iterator ptr)
- : m_cur(ptr), m_node(str, &m_cur) {}
+ const_iterator(const wxString *wxstr, underlying_iterator ptr)
+ : m_cur(ptr), m_node(wxstr, &m_cur) {}
const wxString* str() const { return m_node.m_str; }
// get last character
wxUniChar Last() const
{
- wxASSERT_MSG( !empty(), _T("wxString: index out of bounds") );
+ wxASSERT_MSG( !empty(), wxT("wxString: index out of bounds") );
return *rbegin();
}
// get writable last character
wxUniCharRef Last()
{
- wxASSERT_MSG( !empty(), _T("wxString: index out of bounds") );
+ wxASSERT_MSG( !empty(), wxT("wxString: index out of bounds") );
return *rbegin();
}
{
#if WXWIN_COMPATIBILITY_2_8 && !wxUSE_STL_BASED_WXSTRING && !wxUSE_UNICODE_UTF8
wxASSERT_MSG( s.IsValid(),
- _T("did you forget to call UngetWriteBuf()?") );
+ wxT("did you forget to call UngetWriteBuf()?") );
#endif
append(s);
// stream-like functions
// insert an int into string
wxString& operator<<(int i)
- { return (*this) << Format(_T("%d"), i); }
+ { return (*this) << Format(wxT("%d"), i); }
// insert an unsigned int into string
wxString& operator<<(unsigned int ui)
- { return (*this) << Format(_T("%u"), ui); }
+ { return (*this) << Format(wxT("%u"), ui); }
// insert a long into string
wxString& operator<<(long l)
- { return (*this) << Format(_T("%ld"), l); }
+ { return (*this) << Format(wxT("%ld"), l); }
// insert an unsigned long into string
wxString& operator<<(unsigned long ul)
- { return (*this) << Format(_T("%lu"), ul); }
+ { return (*this) << Format(wxT("%lu"), ul); }
#if defined wxLongLong_t && !defined wxLongLongIsLong
// insert a long long if they exist and aren't longs
wxString& operator<<(wxLongLong_t ll)
{
- const wxChar *fmt = _T("%") wxLongLongFmtSpec _T("d");
- return (*this) << Format(fmt, ll);
+ return (*this) << Format("%" wxLongLongFmtSpec "d", ll);
}
// insert an unsigned long long
wxString& operator<<(wxULongLong_t ull)
{
- const wxChar *fmt = _T("%") wxLongLongFmtSpec _T("u");
- return (*this) << Format(fmt , ull);
+ return (*this) << Format("%" wxLongLongFmtSpec "u" , ull);
}
#endif // wxLongLong_t && !wxLongLongIsLong
// insert a float into string
wxString& operator<<(float f)
- { return (*this) << Format(_T("%f"), f); }
+ { return (*this) << Format(wxT("%f"), f); }
// insert a double into string
wxString& operator<<(double d)
- { return (*this) << Format(_T("%g"), d); }
+ { return (*this) << Format(wxT("%g"), d); }
// string comparison
// case-sensitive comparison (returns a value < 0, = 0 or > 0)
// convert to a double
bool ToCDouble(double *val) const;
#endif
-
+
#ifndef wxNEEDS_WXSTRING_PRINTF_MIXIN
// formatted input/output
// as sprintf(), returns the number of characters written or < 0 on error
CreateConstIterator(last).impl())
{
wxASSERT_MSG( first.m_str == last.m_str,
- _T("pointers must be into the same string") );
+ wxT("pointers must be into the same string") );
}
#endif // WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER
// about it and doing it like this, i.e. having a separate AsChar(),
// allows us to avoid the creation and destruction of a temporary buffer
// when using wxCStrData without duplicating any code
- AsChar(conv);
+ if ( !AsChar(conv) )
+ {
+ // although it would be probably more correct to return NULL buffer
+ // from here if the conversion fails, a lot of existing code doesn't
+ // expect mb_str() (or wc_str()) to ever return NULL so return an
+ // empty string otherwise to avoid crashes in it
+ //
+ // also, some existing code does check for the conversion success and
+ // so asserting here would be bad too -- even if it does mean that
+ // silently losing data is possible for badly written code
+ return wxScopedCharBuffer::CreateNonOwned("", 0);
+ }
return m_convertedToChar.AsScopedBuffer();
}
// wc_str() implementation helper
wxScopedWCharBuffer AsWCharBuf(const wxMBConv& conv) const
{
- AsWChar(conv);
+ if ( !AsWChar(conv) )
+ return wxScopedWCharBuffer::CreateNonOwned(L"", 0);
return m_convertedToWChar.AsScopedBuffer();
}
};
#ifdef wxNEEDS_WXSTRING_PRINTF_MIXIN
- #pragma warning (default:4275)
+ #pragma warning (pop)
#endif
// string iterator operators that satisfy STL Random Access Iterator
inline wxUniChar wxCStrData::operator*() const
{
if ( m_str->empty() )
- return wxUniChar(_T('\0'));
+ return wxUniChar(wxT('\0'));
else
return (*m_str)[m_offset];
}