]> 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.
 
+- 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:
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).
 
+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},
-\helpref{fn\_str}{wxstringfnstr}
+\helpref{fn\_str}{wxstringfnstr}, \helpref{c\_str}{wxstringcstr},
+\helpref{wchar\_str}{wxstringwcharstr}
 
 
 \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{fn\_str}{wxstringfnstr}
+\helpref{fn\_str}{wxstringfnstr}, \helpref{char\_str}{wxstringcharstr}
 
 
 \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{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}
index c9232820fec15c0d34d3554088350b2e51e2a7c2..a0c2786ef43e086b49f5ffba958005218bcee72a 100644 (file)
@@ -146,6 +146,27 @@ public:
 };
 #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
 
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(); }
 
+    // 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.)
@@ -972,7 +978,7 @@ public:
     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 ) ); }
index b486a32142db7a93854984814e513f4ec6c1a02c..7198b0cb7cd005384bcc4dcb877014a7ad958e9e 100644 (file)
@@ -53,7 +53,9 @@ private:
 #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();
@@ -77,8 +79,10 @@ private:
 #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)
 };
@@ -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)
@@ -668,7 +672,7 @@ template<typename T> bool CheckStr(const wxString& expected, T 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):
@@ -691,3 +695,40 @@ void StringTestCase::DoCStrData(bool cond)
     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()) );
+}