diff --git a/docs/changes.txt b/docs/changes.txt index b122f1f371..33af0034d8 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -94,6 +94,8 @@ Major new features in 2.8 release All (Unix): - Handle socket shutdown by the peer correctly in wxSocket (Tim Kosse) +- Added wxString::char_str() and wchar_str() methods for forward + compatiblity with wxWidgets 3 wxMSW: diff --git a/docs/latex/wx/wxstring.tex b/docs/latex/wx/wxstring.tex index ff14f5ff40..c74bfb6884 100644 --- a/docs/latex/wx/wxstring.tex +++ b/docs/latex/wx/wxstring.tex @@ -573,11 +573,35 @@ Returns the empty string if {\it ch} is not found. Returns a pointer to the string data ({\tt const char*} in ANSI build, {\tt const wchar\_t*} in Unicode build). +Note that the returned value will not be convertible to {\tt char*} or +{\tt wchar\_t*} in wxWidgets 3, consider using +\helpref{char\_str}{wxstringcharstr} or +\helpref{wchar\_string}{wxstringwcharstr} if you need to pass string value +to a function expecting non-const pointer. + \wxheading{See also} \helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr}, -\helpref{fn\_str}{wxstringfnstr} +\helpref{fn\_str}{wxstringfnstr}, \helpref{char\_str}{wxstringcharstr}, +\helpref{wchar\_string}{wxstringwcharstr} +\membersection{wxString::char\_str}\label{wxstringcharstr} + +\constfunc{wxWritableCharBuffer}{char\_str}{\void} + +Returns an object with string data that is implicitly convertible to +{\tt char*} pointer. Note that any change to the returned buffer is lost and so +this function is only usable for passing strings to legacy libraries that +don't have const-correct API. Use \helpref{wxStringBuffer}{wxstringbuffer} if +you want to modify the string. + +\newsince{2.8.4} + +\wxheading{See also} + +\helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr}, +\helpref{fn\_str}{wxstringfnstr}, \helpref{c\_str}{wxstringcstr}, +\helpref{wchar\_str}{wxstringwcharstr} \membersection{wxString::Clear}\label{wxstringclear} @@ -937,7 +961,7 @@ The macro wxWX2MBbuf is defined as the correct return type (without const). \helpref{wxMBConv}{wxmbconv}, \helpref{c\_str}{wxstringcstr}, \helpref{wc\_str}{wxstringwcstr}, -\helpref{fn\_str}{wxstringfnstr} +\helpref{fn\_str}{wxstringfnstr}, \helpref{char\_str}{wxstringcharstr} \membersection{wxString::Mid}\label{wxstringmid} @@ -1264,7 +1288,25 @@ The macro wxWX2WCbuf is defined as the correct return type (without const). \helpref{wxMBConv}{wxmbconv}, \helpref{c\_str}{wxstringcstr}, \helpref{mb\_str}{wxstringwcstr}, -\helpref{fn\_str}{wxstringfnstr} +\helpref{fn\_str}{wxstringfnstr}, \helpref{wchar\_str}{wxstringwcharstr} + +\membersection{wxString::wchar\_str}\label{wxstringwcharstr} + +\constfunc{wxWritableWCharBuffer}{wchar\_str}{\void} + +Returns an object with string data that is implicitly convertible to +{\tt char*} pointer. Note that any change to the returned buffer is lost and so +this function is only usable for passing strings to legacy libraries that +don't have const-correct API. Use \helpref{wxStringBuffer}{wxstringbuffer} if +you want to modify the string. + +\newsince{2.8.4} + +\wxheading{See also} + +\helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr}, +\helpref{fn\_str}{wxstringfnstr}, \helpref{c\_str}{wxstringcstr}, +\helpref{char\_str}{wxstringcharstr} \membersection{wxString::operator!}\label{wxstringoperatornot} diff --git a/include/wx/buffer.h b/include/wx/buffer.h index f17aa0c1ab..51c837336f 100644 --- a/include/wx/buffer.h +++ b/include/wx/buffer.h @@ -111,15 +111,29 @@ private: \ chartype *m_str; \ } +// needed for wxString::char_str() and wchar_str() +#define DEFINE_WRITABLE_BUFFER(classname, baseclass, chartype) \ +class WXDLLIMPEXP_BASE classname : public baseclass \ +{ \ +public: \ + classname(const baseclass& src) : baseclass(src) {} \ + classname(const chartype *str = NULL) : baseclass(str) {} \ + \ + operator chartype*() { return this->data(); } \ +} + DEFINE_BUFFER(wxCharBuffer, char, wxStrdupA); +DEFINE_WRITABLE_BUFFER(wxWritableCharBuffer, wxCharBuffer, char); #if wxUSE_WCHAR_T DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxStrdupW); +DEFINE_WRITABLE_BUFFER(wxWritableWCharBuffer, wxWCharBuffer, wchar_t); #endif // wxUSE_WCHAR_T #undef DEFINE_BUFFER +#undef DEFINE_WRITABLE_BUFFER #if wxUSE_UNICODE typedef wxWCharBuffer wxWxCharBuffer; diff --git a/include/wx/string.h b/include/wx/string.h index fb73ad8757..eb11c399a3 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -836,6 +836,14 @@ public: // identical to c_str(), for MFC compatibility const wxChar* GetData() const { return c_str(); } + // conversion to *non-const* multibyte or widestring buffer; modifying + // returned buffer won't affect the string, these methods are only useful + // for passing values to const-incorrect functions + wxWritableCharBuffer char_str() const { return mb_str(wxConvLibc); } +#if wxUSE_WCHAR_T + wxWritableWCharBuffer wchar_str() const { return wc_str(wxConvLibc); } +#endif + // conversion to/from plain (i.e. 7 bit) ASCII: this is useful for // converting numbers or strings which are certain not to contain special // chars (typically system functions, X atoms, environment variables etc.) diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 85e91dad86..37a7840bba 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -53,6 +53,7 @@ private: #endif // wxLongLong_t CPPUNIT_TEST( ToDouble ); CPPUNIT_TEST( WriteBuf ); + CPPUNIT_TEST( CharStr ); CPPUNIT_TEST_SUITE_END(); void String(); @@ -76,6 +77,7 @@ private: #endif // wxLongLong_t void ToDouble(); void WriteBuf(); + void CharStr(); DECLARE_NO_COPY_CLASS(StringTestCase) }; @@ -630,3 +632,15 @@ void StringTestCase::WriteBuf() } } + +static bool IsFoo(/* non-const */ char *s) +{ + return strcmp(s, "foo") == 0; +} + +void StringTestCase::CharStr() +{ + wxString s(_T("foo")); + + CPPUNIT_ASSERT( IsFoo(s.char_str()) ); +} diff --git a/version-script.in b/version-script.in index 2956ab10c9..43e9c4bc35 100644 --- a/version-script.in +++ b/version-script.in @@ -24,6 +24,16 @@ # and once released its version cannot be changed. +# public symbols added in 2.8.4 (please keep in alphabetical order): +@WX_VERSION_TAG@.4 { + global: + # wxString::[w]char_str() + *wxString*char_str*; + # wxWritable[W]CharBuffer + *wxWritableCharBuffer*; + *wxWritableWCharBuffer*; +}; + # public symbols added in 2.8.2 (please keep in alphabetical order): @WX_VERSION_TAG@.2 { global: