added char_str() and wchar_str() methods to wxString for obtaining char*/wchar_t* pointers

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45175 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2007-03-30 20:09:02 +00:00
parent 6af350d428
commit ef0f138756
5 changed files with 123 additions and 11 deletions

View File

@@ -30,6 +30,12 @@ Changes in behaviour which may result in compilation errors
in vast majority of cases because of conversion operators, but it can break in vast majority of cases because of conversion operators, but it can break
code that depends on the result being wxChar. code that depends on the result being wxChar.
- The value returned by wxString::c_str() cannot be casted to non-const char*
or wchar_t* anymore. The solution is to use newly added wxString methods
char_str() (which returns a buffer convertible to char*) or wchar_str()
(which returns a buffer convertible to wchar_t*). These methods are
available in wxWidgets 2.8 series beginning with 2.8.4 as well.
- The value returned by wxString::operator[] or wxString::iterator cannot be - The value returned by wxString::operator[] or wxString::iterator cannot be
used in switch statements anymore, because it's a class instance. Code like used in switch statements anymore, because it's a class instance. Code like
this won't compile: this won't compile:

View File

@@ -573,10 +573,32 @@ Returns the empty string if {\it ch} is not found.
Returns a pointer to the string data ({\tt const char*} in ANSI build, Returns a pointer to the string data ({\tt const char*} in ANSI build,
{\tt const wchar\_t*} in Unicode build). {\tt const wchar\_t*} in Unicode build).
Note that the returned value is not convertible to {\tt char*} or
{\tt wchar\_t*}, use \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} \wxheading{See also}
\helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr}, \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.
\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} \membersection{wxString::Clear}\label{wxstringclear}
@@ -941,7 +963,7 @@ The macro wxWX2MBbuf is defined as the correct return type (without const).
\helpref{wxMBConv}{wxmbconv}, \helpref{wxMBConv}{wxmbconv},
\helpref{c\_str}{wxstringcstr}, \helpref{wc\_str}{wxstringwcstr}, \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} \membersection{wxString::Mid}\label{wxstringmid}
@@ -1272,7 +1294,23 @@ The macro wxWX2WCbuf is defined as the correct return type (without const).
\helpref{wxMBConv}{wxmbconv}, \helpref{wxMBConv}{wxmbconv},
\helpref{c\_str}{wxstringcstr}, \helpref{mb\_str}{wxstringwcstr}, \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.
\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} \membersection{wxString::operator!}\label{wxstringoperatornot}

View File

@@ -146,6 +146,27 @@ public:
}; };
#endif // wxUSE_WCHAR_T #endif // wxUSE_WCHAR_T
// wxCharTypeBuffer<T> implicitly convertible to T*
template <typename T>
class wxWritableCharTypeBuffer : wxCharTypeBuffer<T>
{
public:
typedef typename wxCharTypeBuffer<T>::CharType CharType;
wxWritableCharTypeBuffer(const wxCharTypeBuffer<T>& src)
: wxCharTypeBuffer<T>(src) {}
// FIXME-UTF8: this won't be needed after converting mb_str()/wc_str() to
// always return a buffer
wxWritableCharTypeBuffer(const CharType *str = NULL)
: wxCharTypeBuffer<T>(str) {}
operator CharType*() { return this->data(); }
};
typedef wxWritableCharTypeBuffer<char> wxWritableCharBuffer;
typedef wxWritableCharTypeBuffer<wchar_t> wxWritableWCharBuffer;
#if wxUSE_UNICODE #if wxUSE_UNICODE
#define wxWxCharBuffer wxWCharBuffer #define wxWxCharBuffer wxWCharBuffer

View File

@@ -923,6 +923,12 @@ public:
// wchar_t*, UTF-8-encoded char*, depending on the build): // wchar_t*, UTF-8-encoded char*, depending on the build):
const_pointer wx_str() const { return m_impl.c_str(); } const_pointer wx_str() const { return m_impl.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(); }
wxWritableWCharBuffer wchar_str() const { return wc_str(); }
// conversion to/from plain (i.e. 7 bit) ASCII: this is useful for // conversion to/from plain (i.e. 7 bit) ASCII: this is useful for
// converting numbers or strings which are certain not to contain special // converting numbers or strings which are certain not to contain special
// chars (typically system functions, X atoms, environment variables etc.) // chars (typically system functions, X atoms, environment variables etc.)
@@ -972,7 +978,7 @@ public:
const wxWX2MBbuf mbc_str() const { return mb_str(); } const wxWX2MBbuf mbc_str() const { return mb_str(); }
#if wxUSE_WCHAR_T #if wxUSE_WCHAR_T
const wxWCharBuffer wc_str(const wxMBConv& conv) const; const wxWCharBuffer wc_str(const wxMBConv& conv = wxConvLibc) const;
#endif // wxUSE_WCHAR_T #endif // wxUSE_WCHAR_T
#ifdef __WXOSX__ #ifdef __WXOSX__
const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); } const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); }

View File

@@ -53,7 +53,9 @@ private:
#endif // wxLongLong_t #endif // wxLongLong_t
CPPUNIT_TEST( ToDouble ); CPPUNIT_TEST( ToDouble );
CPPUNIT_TEST( WriteBuf ); CPPUNIT_TEST( WriteBuf );
CPPUNIT_TEST( CStrData ); CPPUNIT_TEST( CStrDataTernaryOperator );
CPPUNIT_TEST( CStrDataImplicitConversion );
CPPUNIT_TEST( ExplicitConversion );
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
void String(); void String();
@@ -77,8 +79,10 @@ private:
#endif // wxLongLong_t #endif // wxLongLong_t
void ToDouble(); void ToDouble();
void WriteBuf(); void WriteBuf();
void CStrData(); void CStrDataTernaryOperator();
void DoCStrData(bool cond); void DoCStrDataTernaryOperator(bool cond);
void CStrDataImplicitConversion();
void ExplicitConversion();
DECLARE_NO_COPY_CLASS(StringTestCase) DECLARE_NO_COPY_CLASS(StringTestCase)
}; };
@@ -657,10 +661,10 @@ void StringTestCase::WriteBuf()
void StringTestCase::CStrData() void StringTestCase::CStrDataTernaryOperator()
{ {
DoCStrData(true); DoCStrDataTernaryOperator(true);
DoCStrData(false); DoCStrDataTernaryOperator(false);
} }
template<typename T> bool CheckStr(const wxString& expected, T s) template<typename T> bool CheckStr(const wxString& expected, T s)
@@ -668,7 +672,7 @@ template<typename T> bool CheckStr(const wxString& expected, T s)
return expected == wxString(s); return expected == wxString(s);
} }
void StringTestCase::DoCStrData(bool cond) void StringTestCase::DoCStrDataTernaryOperator(bool cond)
{ {
// test compilation of wxCStrData when used with operator?: (the asserts // test compilation of wxCStrData when used with operator?: (the asserts
// are not very important, we're testing if the code compiles at all): // are not very important, we're testing if the code compiles at all):
@@ -691,3 +695,40 @@ void StringTestCase::DoCStrData(bool cond)
CPPUNIT_ASSERT( CheckStr(s, (cond ? "foo" : s.c_str())) ); CPPUNIT_ASSERT( CheckStr(s, (cond ? "foo" : s.c_str())) );
#endif #endif
} }
bool CheckStrChar(const wxString& expected, char *s)
{ return CheckStr(expected, s); }
bool CheckStrWChar(const wxString& expected, wchar_t *s)
{ return CheckStr(expected, s); }
bool CheckStrConstChar(const wxString& expected, const char *s)
{ return CheckStr(expected, s); }
bool CheckStrConstWChar(const wxString& expected, const wchar_t *s)
{ return CheckStr(expected, s); }
void StringTestCase::CStrDataImplicitConversion()
{
wxString s("foo");
// FIXME-UTF8: when wxCStrData can handle both conversions, this should
// be changed to always test all versions, both MB and WC
#if wxUSE_UNICODE
CPPUNIT_ASSERT( CheckStrConstWChar(s, s.c_str()) );
CPPUNIT_ASSERT( CheckStrConstWChar(s, s) );
#else
CPPUNIT_ASSERT( CheckStrConstChar(s, s.c_str()) );
CPPUNIT_ASSERT( CheckStrConstChar(s, s) );
#endif
}
void StringTestCase::ExplicitConversion()
{
wxString s("foo");
CPPUNIT_ASSERT( CheckStr(s, s.mb_str()) );
CPPUNIT_ASSERT( CheckStrConstChar(s, s.mb_str()) );
CPPUNIT_ASSERT( CheckStrChar(s, s.char_str()) );
CPPUNIT_ASSERT( CheckStr(s, s.wc_str()) );
CPPUNIT_ASSERT( CheckStrConstWChar(s, s.wc_str()) );
CPPUNIT_ASSERT( CheckStrWChar(s, s.wchar_str()) );
}