]> git.saurik.com Git - wxWidgets.git/commitdiff
added char_str() and wchar_str() methods to wxString for obtaining char*/wchar_t...
authorVáclav Slavík <vslavik@fastmail.fm>
Fri, 30 Mar 2007 20:09:02 +0000 (20:09 +0000)
committerVáclav Slavík <vslavik@fastmail.fm>
Fri, 30 Mar 2007 20:09:02 +0000 (20:09 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45175 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/changes.txt
docs/latex/wx/wxstring.tex
include/wx/buffer.h
include/wx/string.h
tests/strings/strings.cpp

index dc0d82cff79b2bd75ed45f5d7c2b9f37aa65501f..708b7023a5b9feb2bcc61469285e22a7f7c57518 100644 (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
   code that depends on the result being wxChar.
 
   in vast majority of cases because of conversion operators, but it can break
   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
   used in switch statements anymore, because it's a class instance. Code like
   this won't compile:
 - The value returned by wxString::operator[] or wxString::iterator cannot be
   used in switch statements anymore, because it's a class instance. Code like
   this won't compile:
index 5384dd46b18ef53bf0a34ad8a9b94bd7cbf18a85..60bbd04123aa89bd8979037960e0e0b750e637e6 100644 (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,
 {\tt const wchar\_t*} in Unicode build).
 
 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 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}
+
+\helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr},
+\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},
 \wxheading{See also}
 
 \helpref{mb\_str}{wxstringmbstr}, \helpref{wc\_str}{wxstringwcstr},
-\helpref{fn\_str}{wxstringfnstr}
+\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{c\_str}{wxstringcstr}, \helpref{wc\_str}{wxstringwcstr},
 
 \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}
 
 
 \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{c\_str}{wxstringcstr}, \helpref{mb\_str}{wxstringwcstr},
 
 \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.
+
+\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}
index c9232820fec15c0d34d3554088350b2e51e2a7c2..a0c2786ef43e086b49f5ffba958005218bcee72a 100644 (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
     #define wxWxCharBuffer wxWCharBuffer
 
 #if wxUSE_UNICODE
     #define wxWxCharBuffer wxWCharBuffer
 
index e0f58918e884a80309cdd84ee0692b3688a66243..4ff1d975911ab6409af693bc89f43f32af17994a 100644 (file)
@@ -923,6 +923,12 @@ public:
     // wchar_t*, UTF-8-encoded char*, depending on the build):
     const_pointer wx_str() const { return m_impl.c_str(); }
 
     // wchar_t*, UTF-8-encoded char*, depending on the build):
     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
     // converting numbers or strings which are certain not to contain special
     // chars (typically system functions, X atoms, environment variables etc.)
     // 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.)
@@ -972,7 +978,7 @@ public:
     const wxWX2MBbuf mbc_str() const { return mb_str(); }
 
 #if wxUSE_WCHAR_T
     const wxWX2MBbuf mbc_str() const { return mb_str(); }
 
 #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
 #ifdef __WXOSX__
     const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); }
 #endif // wxUSE_WCHAR_T
 #ifdef __WXOSX__
     const wxCharBuffer fn_str() const { return wxConvFile.cWC2WX( wc_str( wxConvLocal ) ); }
index b486a32142db7a93854984814e513f4ec6c1a02c..7198b0cb7cd005384bcc4dcb877014a7ad958e9e 100644 (file)
@@ -53,7 +53,9 @@ private:
 #endif // wxLongLong_t
         CPPUNIT_TEST( ToDouble );
         CPPUNIT_TEST( WriteBuf );
 #endif // wxLongLong_t
         CPPUNIT_TEST( ToDouble );
         CPPUNIT_TEST( WriteBuf );
-        CPPUNIT_TEST( CStrData );
+        CPPUNIT_TEST( CStrDataTernaryOperator );
+        CPPUNIT_TEST( CStrDataImplicitConversion );
+        CPPUNIT_TEST( ExplicitConversion );
     CPPUNIT_TEST_SUITE_END();
 
     void String();
     CPPUNIT_TEST_SUITE_END();
 
     void String();
@@ -77,8 +79,10 @@ private:
 #endif // wxLongLong_t
     void ToDouble();
     void WriteBuf();
 #endif // wxLongLong_t
     void ToDouble();
     void WriteBuf();
-    void CStrData();
-    void DoCStrData(bool cond);
+    void CStrDataTernaryOperator();
+    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);
-    DoCStrData(false);
+    DoCStrDataTernaryOperator(true);
+    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
     // are not very important, we're testing if the code compiles at all):
 {
     // test compilation of wxCStrData when used with operator?: (the asserts
     // 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())) );
 #endif
 }
     CPPUNIT_ASSERT( CheckStr(s, (cond ? "foo" : s.c_str())) );
 #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()) );
+}