]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/buffer.h
Bitmap button updates
[wxWidgets.git] / include / wx / buffer.h
index f5fc0f9208a8ee45a8f6d0b95e7123d0a3a2a698..3b770e32af24d8e9f5e8d109c74146b8c74f999d 100644 (file)
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////
-// Name:        buffer.h
+// Name:        wx/buffer.h
 // Purpose:     auto buffer classes: buffers which automatically free memory
 // Author:      Vadim Zeitlin
 // Modified by:
@@ -14,8 +14,9 @@
 #ifndef _WX_BUFFER_H
 #define _WX_BUFFER_H
 
+#include "wx/wxchar.h"
+
 #include <string.h> // strdup
-#include <wchar.h>  // wchar_t
 
 // ----------------------------------------------------------------------------
 // Special classes for (wide) character strings: they use malloc/free instead
@@ -26,90 +27,200 @@ class wxCharBuffer
 {
 public:
     wxCharBuffer(const char *str)
+        : m_str(str ? strdup(str) : NULL)
     {
-        wxASSERT_MSG( str, _T("NULL string in wxCharBuffer") );
-
-        m_str = str ? strdup(str) : (char *)NULL;
     }
+
     wxCharBuffer(size_t len)
+        : m_str((char *)malloc((len + 1)*sizeof(char)))
     {
-        m_str = (char *)malloc(len+1);
-       m_str[len] = '\0';
+        m_str[len] = '\0';
     }
+
     // no need to check for NULL, free() does it
-   ~wxCharBuffer() { free(m_str); }
+    ~wxCharBuffer() { free(m_str); }
 
-   wxCharBuffer(const wxCharBuffer& src)
-   {
-     m_str = src.m_str;
-     // no reference count yet...
-     (wxCharBuffer)src.m_str = (char *)NULL;
-   }
-   wxCharBuffer& operator=(const wxCharBuffer& src)
-   {
-     m_str = src.m_str;
-     // no reference count yet...
-     (wxCharBuffer)src.m_str = (char *)NULL;
-     return *this;
-   }
+    wxCharBuffer(const wxCharBuffer& src)
+        : m_str(src.m_str)
+    {
+        // no reference count yet...
+        ((wxCharBuffer*)&src)->m_str = (char *)NULL;
+    }
+    wxCharBuffer& operator=(const wxCharBuffer& src)
+    {
+        m_str = src.m_str;
+        // no reference count yet...
+        ((wxCharBuffer*)&src)->m_str = (char *)NULL;
+        return *this;
+    }
 
-   operator const char *() const { return m_str; }
+    const char *data() const { return m_str; }
+    operator const char *() const { return m_str; }
+    char operator[](size_t n) const { return m_str[n]; }
 
 private:
-   char *m_str;
+    char *m_str;
 };
 
+#if wxUSE_WCHAR_T
+
 class wxWCharBuffer
 {
 public:
     wxWCharBuffer(const wchar_t *wcs)
+        : m_wcs((wchar_t *)NULL)
     {
-        wxASSERT_MSG( wcs, _T("NULL string in wxWCharBuffer") );
-
-        m_wcs = wcs ? (wchar_t *)malloc((wcslen(wcs)+1)*sizeof(wchar_t))
-                   : (wchar_t *)NULL;
-       if (m_wcs) wcscpy(m_wcs, wcs);
+        if (wcs) {
+          size_t siz = (wxWcslen(wcs) + 1)*sizeof(wchar_t);
+          m_wcs = (wchar_t *)malloc(siz);
+          memcpy(m_wcs, wcs, siz);
+        }
     }
     wxWCharBuffer(size_t len)
+        : m_wcs((wchar_t *)malloc((len + 1)*sizeof(wchar_t)))
     {
-        m_wcs = (wchar_t *)malloc((len+1)*sizeof(wchar_t));
-       m_wcs[len] = L'\0';
+        m_wcs[len] = L'\0';
     }
 
     // no need to check for NULL, free() does it
-   ~wxWCharBuffer() { free(m_wcs); }
+    ~wxWCharBuffer() { free(m_wcs); }
 
-   wxWCharBuffer(const wxWCharBuffer& src)
-   {
-     m_wcs = src.m_wcs;
-     // no reference count yet...
-     (wxWCharBuffer)src.m_wcs = (wchar_t *)NULL;
-   }
-   wxWCharBuffer& operator=(const wxWCharBuffer& src)
-   {
-     m_wcs = src.m_wcs;
-     // no reference count yet...
-     (wxWCharBuffer)src.m_wcs = (wchar_t *)NULL;
-     return *this;
-   }
+    wxWCharBuffer(const wxWCharBuffer& src)
+        : m_wcs(src.m_wcs)
+    {
+       // no reference count yet...
+       ((wxWCharBuffer*)&src)->m_wcs = (wchar_t *)NULL;
+    }
+    wxWCharBuffer& operator=(const wxWCharBuffer& src)
+    {
+        m_wcs = src.m_wcs;
+        // no reference count yet...
+        ((wxWCharBuffer*)&src)->m_wcs = (wchar_t *)NULL;
+        return *this;
+    }
 
-   operator const wchar_t *() const { return m_wcs; }
+    const wchar_t *data() const { return m_wcs; }
+    operator const wchar_t *() const { return m_wcs; }
+    wchar_t operator[](size_t n) const { return m_wcs[n]; }
 
 private:
-   wchar_t *m_wcs;
+    wchar_t *m_wcs;
 };
 
+#endif // wxUSE_WCHAR_T
+
 #if wxUSE_UNICODE
-#define wxMB2WXbuf wxWCharBuffer
-#define wxWX2MBbuf wxCharBuffer
-#define wxWC2WXbuf wxChar*
-#define wxWX2WCbuf wxChar*
-#else
-#define wxMB2WXbuf wxChar*
-#define wxWX2MBbuf wxChar*
-#define wxWC2WXbuf wxCharBuffer
-#define wxWX2WCbuf wxWCharBuffer
-#endif
+    #define wxMB2WXbuf wxWCharBuffer
+    #define wxWX2MBbuf wxCharBuffer
+    #define wxWC2WXbuf wxChar*
+    #define wxWX2WCbuf wxChar*
+#else // ANSI
+    #define wxMB2WXbuf wxChar*
+    #define wxWX2MBbuf wxChar*
+    #define wxWC2WXbuf wxCharBuffer
+    #define wxWX2WCbuf wxWCharBuffer
+#endif // Unicode/ANSI
+
+// ----------------------------------------------------------------------------
+// A class for holding growable data buffers (not necessarily strings)
+// ----------------------------------------------------------------------------
+
+class wxMemoryBuffer
+{
+public:
+    enum { BLOCK_SIZE = 1024 };
+    wxMemoryBuffer(size_t size = wxMemoryBuffer::BLOCK_SIZE)
+        : m_data(malloc(size)), m_size(size), m_len(0)
+    {
+    }
+
+    ~wxMemoryBuffer() { free(m_data); }
+
+    // Accessors
+    void*  GetData() const    { return m_data; }
+    size_t GetBufSize() const { return m_size; }
+    size_t GetDataLen() const { return m_len; }
+
+    void   SetBufSize(size_t size) { ResizeIfNeeded(size); }
+    void   SetDataLen(size_t len)
+    {
+        wxASSERT(len <= m_size);
+        m_len = len;
+    }
+
+    // Ensure the buffer is big enough and return a pointer to it
+    void* GetWriteBuf(size_t sizeNeeded)
+    {
+        ResizeIfNeeded(sizeNeeded);
+        return m_data;
+    }
+    // Update the length after the write
+    void  UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
+
+    // Like the above, but appends to the buffer
+    void* GetAppendBuf(size_t sizeNeeded)
+    {
+        ResizeIfNeeded(m_len + sizeNeeded);
+        return (char*)m_data + m_len;
+    }
+    void  UngetAppendBuf(size_t sizeUsed) { SetDataLen(m_len + sizeUsed); }
+
+    // Other ways to append to the buffer
+    void  AppendByte(char data) {
+        ResizeIfNeeded(m_len + 1);
+        *(((char*)m_data)+m_len) = data;
+        m_len += 1;
+    }
+    void  AppendData(void* data, size_t len)
+    {
+        memcpy(GetAppendBuf(len), data, len);
+        UngetAppendBuf(len);
+    }
+
+    operator const char *() const { return (const char*)m_data; }
+
+
+    // Copy and assignment
+    wxMemoryBuffer(const wxMemoryBuffer& src)
+        : m_data(src.m_data), m_size(src.m_size), m_len(src.m_len)
+    {
+        // no reference count yet...
+        ((wxMemoryBuffer*)&src)->m_data = NULL;
+        ((wxMemoryBuffer*)&src)->m_size = 0;
+        ((wxMemoryBuffer*)&src)->m_len  = 0;
+    }
+
+    wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
+    {
+        m_data = src.m_data;
+        m_size = src.m_size;
+        m_len  = src.m_len;
+
+        // no reference count yet...
+        ((wxMemoryBuffer*)&src)->m_data = NULL;
+        ((wxMemoryBuffer*)&src)->m_size = 0;
+        ((wxMemoryBuffer*)&src)->m_len  = 0;
+
+        return *this;
+   }
+
+
+protected:
+    void ResizeIfNeeded(size_t newSize)
+    {
+        if (newSize > m_size)
+        {
+            m_data = realloc(m_data, newSize + wxMemoryBuffer::BLOCK_SIZE);
+            wxASSERT(m_data != NULL);
+            m_size = newSize + wxMemoryBuffer::BLOCK_SIZE;
+        }
+    }
+
+private:
+    void*       m_data;
+    size_t      m_size;
+    size_t      m_len;
+};
 
 // ----------------------------------------------------------------------------
 // template class for any kind of data