]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/buffer.h
fixed memory leak in wxXmlResource introduced when fixing wxVector<> usage (patch...
[wxWidgets.git] / include / wx / buffer.h
index 7daf8a8e7143ff2e9a23a1718f871ec01d08b3a0..d06fbf6fc15b57a76d726521cd9f4295621bd111 100644 (file)
 #ifndef _WX_BUFFER_H
 #define _WX_BUFFER_H
 
 #ifndef _WX_BUFFER_H
 #define _WX_BUFFER_H
 
-#include "wx/wxchar.h"
+#include "wx/chartype.h"
+#include "wx/wxcrtbase.h"
 
 #include <stdlib.h>             // malloc() and free()
 
 
 #include <stdlib.h>             // malloc() and free()
 
-inline char *wxStrDup(const char *s) { return wxStrdupA(s); }
-#if wxUSE_WCHAR_T
-    inline wchar_t *wxStrDup(const wchar_t *ws) { return wxStrdupW(ws); }
-#endif
+class WXDLLIMPEXP_FWD_BASE wxCStrData;
 
 // ----------------------------------------------------------------------------
 // Special classes for (wide) character strings: they use malloc/free instead
 
 // ----------------------------------------------------------------------------
 // Special classes for (wide) character strings: they use malloc/free instead
@@ -27,24 +25,38 @@ inline char *wxStrDup(const char *s) { return wxStrdupA(s); }
 // ----------------------------------------------------------------------------
 
 template <typename T>
 // ----------------------------------------------------------------------------
 
 template <typename T>
-class wxCharTypeBuffer
+class WXDLLIMPEXP_BASE wxCharTypeBuffer
 {
 public:
     typedef T CharType;
 
     wxCharTypeBuffer(const CharType *str = NULL)
 {
 public:
     typedef T CharType;
 
     wxCharTypeBuffer(const CharType *str = NULL)
-        : m_str(str ? wxStrDup(str) : NULL)
+        : m_str(str ? wxStrdup(str) : NULL),
+          m_owned(true)
     {
     }
 
     wxCharTypeBuffer(size_t len)
     {
     }
 
     wxCharTypeBuffer(size_t len)
-        : m_str((CharType *)malloc((len + 1)*sizeof(CharType)))
+        : m_str((CharType *)malloc((len + 1)*sizeof(CharType))),
+          m_owned(true)
     {
         m_str[len] = (CharType)0;
     }
 
     {
         m_str[len] = (CharType)0;
     }
 
+    static const wxCharTypeBuffer CreateNonOwned(const CharType *str)
+    {
+        wxCharTypeBuffer buf;
+        buf.m_str = wx_const_cast(CharType*, str);
+        buf.m_owned = false;
+        return buf;
+    }
+
     /* no need to check for NULL, free() does it */
     /* no need to check for NULL, free() does it */
-    ~wxCharTypeBuffer() { free(m_str); }
+    ~wxCharTypeBuffer()
+    {
+        if ( m_owned)
+            free(m_str);
+    }
 
     /*
         WARNING:
 
     /*
         WARNING:
@@ -55,7 +67,7 @@ public:
         a) it shouldn't be really const
         b) you shouldn't use it afterwards (or know that it was reset)
 
         a) it shouldn't be really const
         b) you shouldn't use it afterwards (or know that it was reset)
 
-        This is very ugly but is unfortunately needed to make the normal use\
+        This is very ugly but is unfortunately needed to make the normal use
         of wxCharTypeBuffer buffer objects possible and is very similar to what
         std::auto_ptr<> does (as if it were an excuse...)
     */
         of wxCharTypeBuffer buffer objects possible and is very similar to what
         std::auto_ptr<> does (as if it were an excuse...)
     */
@@ -66,39 +78,46 @@ public:
      */
     CharType *release() const
     {
      */
     CharType *release() const
     {
-        CharType *p = m_str;
-        ((wxCharTypeBuffer *)this)->m_str = NULL;
-        return p;
+        wxASSERT_MSG( m_owned, _T("can't release non-owned buffer") );
+        return DoRelease();
     }
 
     void reset()
     {
     }
 
     void reset()
     {
-        free(m_str);
+        if ( m_owned )
+            free(m_str);
         m_str = NULL;
     }
 
     wxCharTypeBuffer(const wxCharTypeBuffer& src)
         m_str = NULL;
     }
 
     wxCharTypeBuffer(const wxCharTypeBuffer& src)
-        : m_str(src.release())
     {
     {
+        CopyFrom(src);
     }
 
     wxCharTypeBuffer& operator=(const CharType *str)
     {
     }
 
     wxCharTypeBuffer& operator=(const CharType *str)
     {
-        free(m_str);
-        m_str = str ? wxStrDup(str) : NULL;
+        if ( m_owned )
+            free(m_str);
+        m_str = str ? wxStrdup(str) : NULL;
+        m_owned = true;
         return *this;
     }
 
     wxCharTypeBuffer& operator=(const wxCharTypeBuffer& src)
     {
         return *this;
     }
 
     wxCharTypeBuffer& operator=(const wxCharTypeBuffer& src)
     {
-        free(m_str);
-        m_str = src.release();
-
+        if (&src != this)
+        {
+            if ( m_owned )
+                free(m_str);
+            CopyFrom(src);
+        }
         return *this;
     }
 
     bool extend(size_t len)
     {
         return *this;
     }
 
     bool extend(size_t len)
     {
+        wxASSERT_MSG( m_owned, _T("cannot extend non-owned buffer") );
+
         CharType *
             str = (CharType *)realloc(m_str, (len + 1)*sizeof(CharType));
         if ( !str )
         CharType *
             str = (CharType *)realloc(m_str, (len + 1)*sizeof(CharType));
         if ( !str )
@@ -114,35 +133,57 @@ public:
     operator const CharType *() const { return m_str; }
     CharType operator[](size_t n) const { return m_str[n]; }
 
     operator const CharType *() const { return m_str; }
     CharType operator[](size_t n) const { return m_str[n]; }
 
+
+private:
+    CharType *DoRelease() const
+    {
+        CharType *p = m_str;
+        ((wxCharTypeBuffer *)this)->m_str = NULL;
+        return p;
+    }
+
+    void CopyFrom(const wxCharTypeBuffer& src)
+    {
+        m_owned = src.m_owned;
+        m_str = src.DoRelease();
+    }
+
 private:
     CharType *m_str;
 private:
     CharType *m_str;
+    bool m_owned;
 };
 
 };
 
+WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<char> )
+
 class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
 {
 public:
     typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
 
 class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
 {
 public:
     typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
 
+    wxCharBuffer(const wxCharTypeBufferBase& buf)
+        : wxCharTypeBufferBase(buf) {}
+
     wxCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
     wxCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
 
     wxCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
     wxCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
 
-#if !wxUSE_UNICODE
     wxCharBuffer(const wxCStrData& cstr);
     wxCharBuffer(const wxCStrData& cstr);
-#endif
 };
 
 #if wxUSE_WCHAR_T
 };
 
 #if wxUSE_WCHAR_T
+WXDLLIMPEXP_TEMPLATE_INSTANCE_BASE( wxCharTypeBuffer<wchar_t> )
+
 class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
 {
 public:
     typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
 
 class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
 {
 public:
     typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
 
+    wxWCharBuffer(const wxCharTypeBufferBase& buf)
+        : wxCharTypeBufferBase(buf) {}
+
     wxWCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
     wxWCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
 
     wxWCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
     wxWCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
 
-#if wxUSE_UNICODE
     wxWCharBuffer(const wxCStrData& cstr);
     wxWCharBuffer(const wxCStrData& cstr);
-#endif
 };
 #endif // wxUSE_WCHAR_T
 
 };
 #endif // wxUSE_WCHAR_T
 
@@ -172,8 +213,13 @@ typedef wxWritableCharTypeBuffer<wchar_t> wxWritableWCharBuffer;
 
     #define wxMB2WXbuf wxWCharBuffer
     #define wxWX2MBbuf wxCharBuffer
 
     #define wxMB2WXbuf wxWCharBuffer
     #define wxWX2MBbuf wxCharBuffer
-    #define wxWC2WXbuf wxChar*
-    #define wxWX2WCbuf wxChar*
+    #if wxUSE_UNICODE_WCHAR
+        #define wxWC2WXbuf wxChar*
+        #define wxWX2WCbuf wxChar*
+    #elif wxUSE_UNICODE_UTF8
+        #define wxWC2WXbuf wxWCharBuffer
+        #define wxWX2WCbuf wxWCharBuffer
+    #endif
 #else // ANSI
     #define wxWxCharBuffer wxCharBuffer
 
 #else // ANSI
     #define wxWxCharBuffer wxCharBuffer
 
@@ -183,6 +229,13 @@ typedef wxWritableCharTypeBuffer<wchar_t> wxWritableWCharBuffer;
     #define wxWX2WCbuf wxWCharBuffer
 #endif // Unicode/ANSI
 
     #define wxWX2WCbuf wxWCharBuffer
 #endif // Unicode/ANSI
 
+// type of the value returned by wxString::utf8_str()
+#if wxUSE_UNICODE_UTF8
+    #define wxUTF8Buf char *
+#else
+    #define wxUTF8Buf wxCharBuffer
+#endif
+
 // ----------------------------------------------------------------------------
 // A class for holding growable data buffers (not necessarily strings)
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // A class for holding growable data buffers (not necessarily strings)
 // ----------------------------------------------------------------------------
@@ -245,7 +298,7 @@ private:
 };
 
 
 };
 
 
-class wxMemoryBuffer
+class WXDLLIMPEXP_BASE wxMemoryBuffer
 {
 public:
     // ctor and dtor
 {
 public:
     // ctor and dtor
@@ -267,9 +320,12 @@ public:
 
     wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
     {
 
     wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
     {
-        m_bufdata->DecRef();
-        m_bufdata = src.m_bufdata;
-        m_bufdata->IncRef();
+        if (&src != this)
+        {
+            m_bufdata->DecRef();
+            m_bufdata = src.m_bufdata;
+            m_bufdata->IncRef();
+        }
         return *this;
     }
 
         return *this;
     }