]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/string.h
more compilation fixes for VC6 (#9492)
[wxWidgets.git] / include / wx / string.h
index c5283522d57be2d9b25e3fee888ec3bd9e7f9618..aaa1581d9d3ab97fb644ce2832f90ec763a0330e 100644 (file)
@@ -65,6 +65,11 @@ class WXDLLIMPEXP_FWD_BASE wxString;
     #define WXWIN_COMPATIBILITY_STRING_PTR_AS_ITER 1
 #endif
 
+namespace wxPrivate
+{
+    template <typename T> struct wxStringAsBufHelper;
+}
+
 // ---------------------------------------------------------------------------
 // macros
 // ---------------------------------------------------------------------------
@@ -953,8 +958,11 @@ public:
   wxString(const wxWCharBuffer& buf)
     { assign(buf.data()); } // FIXME-UTF8: fix for embedded NUL and buffer length
 
+    // NB: this version uses m_impl.c_str() to force making a copy of the
+    //     string, so that "wxString(str.c_str())" idiom for passing strings
+    //     between threads works
   wxString(const wxCStrData& cstr)
-      : m_impl(cstr.AsString().m_impl) { }
+      : m_impl(cstr.AsString().m_impl.c_str()) { }
 
     // as we provide both ctors with this signature for both char and unsigned
     // char string, we need to provide one for wxCStrData to resolve ambiguity
@@ -1014,6 +1022,13 @@ public:
   #endif
 #endif // wxUSE_STL
 
+  wxString Clone() const
+  {
+      // make a deep copy of the string, i.e. the returned string will have
+      // ref count = 1 with refcounted implementation
+      return wxString::FromImpl(wxStringImpl(m_impl.c_str(), m_impl.length()));
+  }
+
   // first valid index position
   const_iterator begin() const { return const_iterator(this, m_impl.begin()); }
   iterator begin() { return iterator(this, m_impl.begin()); }
@@ -1201,6 +1216,30 @@ public:
         { return mb_str(conv); }
     wxWritableWCharBuffer wchar_str() const { return wc_str(); }
 
+    // conversion to the buffer of the given type T (= char or wchar_t) and
+    // also optionally return the buffer length
+    //
+    // this is mostly/only useful for the template functions
+    //
+    // FIXME-VC6: the second argument only exists for VC6 which doesn't support
+    //            explicit template function selection, do not use it unless
+    //            you must support VC6!
+    template <typename T>
+    wxCharTypeBuffer<T> tchar_str(size_t *len = NULL,
+                                  T * WXUNUSED(dummy) = NULL) const
+    {
+#if wxUSE_UNICODE
+        // we need a helper dispatcher depending on type
+        return wxPrivate::wxStringAsBufHelper<T>::Get(*this, len);
+#else // ANSI
+        // T can only be char in ANSI build
+        if ( len )
+            *len = length();
+
+        return wxCharTypeBuffer<T>::CreateNonOwned(wx_str());
+#endif // Unicode build kind
+    }
+
     // 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.)
@@ -1249,6 +1288,10 @@ public:
     }
     const char* utf8_str() const { return wx_str(); }
     const char* ToUTF8() const { return wx_str(); }
+
+    // this function exists in UTF-8 build only and returns the length of the
+    // internal UTF-8 representation
+    size_t utf8_length() const { return m_impl.length(); }
 #elif wxUSE_UNICODE_WCHAR
     static wxString FromUTF8(const char *utf8)
       { return wxString(utf8, wxMBConvUTF8()); }
@@ -2705,6 +2748,67 @@ inline wxString operator+(wchar_t ch, const wxString& string)
 
 #define wxGetEmptyString() wxString()
 
+// ----------------------------------------------------------------------------
+// helper functions which couldn't be defined inline
+// ----------------------------------------------------------------------------
+
+namespace wxPrivate
+{
+
+#if wxUSE_UNICODE_WCHAR
+
+template <>
+struct wxStringAsBufHelper<char>
+{
+    static wxCharBuffer Get(const wxString& s, size_t *len)
+    {
+        wxCharBuffer buf(s.mb_str());
+        if ( len )
+            *len = buf ? strlen(buf) : 0;
+        return buf;
+    }
+};
+
+template <>
+struct wxStringAsBufHelper<wchar_t>
+{
+    static wxWCharBuffer Get(const wxString& s, size_t *len)
+    {
+        if ( len )
+            *len = s.length();
+        return wxWCharBuffer::CreateNonOwned(s.wx_str());
+    }
+};
+
+#elif wxUSE_UNICODE_UTF8
+
+template <>
+struct wxStringAsBufHelper<char>
+{
+    static wxCharBuffer Get(const wxString& s, size_t *len)
+    {
+        if ( len )
+            *len = s.utf8_length();
+        return wxCharBuffer::CreateNonOwned(s.wx_str());
+    }
+};
+
+template <>
+struct wxStringAsBufHelper<wchar_t>
+{
+    static wxWCharBuffer Get(const wxString& s, size_t *len)
+    {
+        wxWCharBuffer wbuf(s.wc_str());
+        if ( len )
+            *len = wxWcslen(wbuf);
+        return wbuf;
+    }
+};
+
+#endif // Unicode build kind
+
+} // namespace wxPrivate
+
 // ----------------------------------------------------------------------------
 // wxStringBuffer: a tiny class allowing to get a writable pointer into string
 // ----------------------------------------------------------------------------
@@ -2772,8 +2876,30 @@ public:
 
     wxStringTypeBufferBase(wxString& str, size_t lenWanted = 1024)
         : m_str(str), m_buf(lenWanted)
-        { }
-
+    {
+        // for compatibility with old wxStringBuffer which provided direct
+        // access to wxString internal buffer, initialize ourselves with the
+        // string initial contents
+
+        // FIXME-VC6: remove the ugly (CharType *)NULL and use normal
+        //            tchar_str<CharType>
+        size_t len;
+        const wxCharTypeBuffer<CharType> buf(str.tchar_str(&len, (CharType *)NULL));
+        if ( buf )
+        {
+            if ( len > lenWanted )
+            {
+                // in this case there is not enough space for terminating NUL,
+                // ensure that we still put it there
+                m_buf.data()[lenWanted] = 0;
+                len = lenWanted - 1;
+            }
+
+            wxTmemcpy(m_buf.data(), buf, len + 1);
+        }
+        //else: conversion failed, this can happen when trying to get Unicode
+        //      string contents into a char string
+    }
 
     operator CharType*() { return m_buf.data(); }
 
@@ -2784,22 +2910,25 @@ protected:
 
 template<typename T>
 class WXDLLIMPEXP_BASE wxStringTypeBufferLengthBase
+    : public wxStringTypeBufferBase<T>
 {
 public:
-    typedef T CharType;
-
     wxStringTypeBufferLengthBase(wxString& str, size_t lenWanted = 1024)
-        : m_str(str), m_buf(lenWanted), m_len(0), m_lenSet(false)
+        : wxStringTypeBufferBase<T>(str, lenWanted),
+          m_len(0),
+          m_lenSet(false)
         { }
 
-    operator CharType*() { return m_buf.data(); }
+    ~wxStringTypeBufferLengthBase()
+    {
+        wxASSERT_MSG( this->m_lenSet, "forgot to call SetLength()" );
+    }
+
     void SetLength(size_t length) { m_len = length; m_lenSet = true; }
 
 protected:
-    wxString& m_str;
-    wxCharTypeBuffer<CharType> m_buf;
-    size_t        m_len;
-    bool          m_lenSet;
+    size_t m_len;
+    bool m_lenSet;
 };
 
 template<typename T>
@@ -2807,7 +2936,9 @@ class wxStringTypeBuffer : public wxStringTypeBufferBase<T>
 {
 public:
     wxStringTypeBuffer(wxString& str, size_t lenWanted = 1024)
-        : wxStringTypeBufferBase<T>(str, lenWanted) {}
+        : wxStringTypeBufferBase<T>(str, lenWanted)
+        { }
+
     ~wxStringTypeBuffer()
     {
         this->m_str.assign(this->m_buf.data());
@@ -2821,11 +2952,11 @@ class wxStringTypeBufferLength : public wxStringTypeBufferLengthBase<T>
 {
 public:
     wxStringTypeBufferLength(wxString& str, size_t lenWanted = 1024)
-        : wxStringTypeBufferLengthBase<T>(str, lenWanted) {}
+        : wxStringTypeBufferLengthBase<T>(str, lenWanted)
+        { }
 
     ~wxStringTypeBufferLength()
     {
-        wxASSERT(this->m_lenSet);
         this->m_str.assign(this->m_buf.data(), this->m_len);
     }
 
@@ -2859,12 +2990,12 @@ public:
 
     ~wxStringInternalBufferLength()
     {
-        wxASSERT(m_lenSet);
         m_str.m_impl.assign(m_buf.data(), m_len);
     }
 
     DECLARE_NO_COPY_CLASS(wxStringInternalBufferLength)
 };
+
 #endif // wxUSE_STL_BASED_WXSTRING