home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / include / wx / buffer.h < prev    next >
C/C++ Source or Header  |  2002-12-04  |  11KB  |  281 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name:        wx/buffer.h
  3. // Purpose:     auto buffer classes: buffers which automatically free memory
  4. // Author:      Vadim Zeitlin
  5. // Modified by:
  6. // Created:     12.04.99
  7. // RCS-ID:      $Id: buffer.h,v 1.23.2.4 2002/11/30 22:22:25 VZ Exp $
  8. // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
  9. // Licence:     wxWindows license
  10. ///////////////////////////////////////////////////////////////////////////////
  11.  
  12. // these classes are for private use only for now, they're not documented
  13.  
  14. #ifndef _WX_BUFFER_H
  15. #define _WX_BUFFER_H
  16.  
  17. #include "wx/wxchar.h"
  18.  
  19. #include <string.h> // strdup
  20.  
  21. // ----------------------------------------------------------------------------
  22. // Special classes for (wide) character strings: they use malloc/free instead
  23. // of new/delete
  24. // ----------------------------------------------------------------------------
  25.  
  26. #define DEFINE_BUFFER(classname, chartype, strdupfunc)                      \
  27. class classname                                                             \
  28. {                                                                           \
  29. public:                                                                     \
  30.     classname(const chartype *str)                                          \
  31.         : m_str(str ? strdupfunc(str) : NULL)                               \
  32.     {                                                                       \
  33.     }                                                                       \
  34.                                                                             \
  35.     classname(size_t len)                                                   \
  36.         : m_str((chartype *)malloc((len + 1)*sizeof(chartype)))             \
  37.     {                                                                       \
  38.         m_str[len] = (chartype)0;                                           \
  39.     }                                                                       \
  40.                                                                             \
  41.     /* no need to check for NULL, free() does it */                         \
  42.     ~classname() { free(m_str); }                                           \
  43.                                                                             \
  44.     /*                                                                      \
  45.         WARNING:                                                            \
  46.                                                                             \
  47.         the copy ctor and assignment operators change the passed in object  \
  48.         even although it is declared as "const", so:                        \
  49.                                                                             \
  50.         a) it shouldn't be really const                                     \
  51.         b) you shouldn't use it afterwards (or know that it was reset)      \
  52.                                                                             \
  53.         This is very ugly but is unfortunately needed to make the normal use\
  54.         of classname buffer objects possible and is very similar to what    \
  55.         std::auto_ptr<> does (as if it were an excuse...)                   \
  56.     */                                                                      \
  57.                                                                             \
  58.     /*                                                                      \
  59.        because of the remark above, release() is declared const even if it  \
  60.        isn't really const                                                   \
  61.      */                                                                     \
  62.     chartype *release() const                                               \
  63.     {                                                                       \
  64.         chartype *p = m_str;                                                \
  65.         ((classname *)this)->m_str = NULL;                                  \
  66.         return p;                                                           \
  67.     }                                                                       \
  68.                                                                             \
  69.     classname(const classname& src)                                         \
  70.         : m_str(src.release())                                              \
  71.     {                                                                       \
  72.     }                                                                       \
  73.                                                                             \
  74.     classname& operator=(const chartype *str)                               \
  75.     {                                                                       \
  76.         free(m_str);                                                        \
  77.         m_str = str ? strdupfunc(str) : NULL;                               \
  78.         return *this;                                                       \
  79.     }                                                                       \
  80.                                                                             \
  81.     classname& operator=(const classname& src)                              \
  82.     {                                                                       \
  83.         free(m_str);                                                        \
  84.         m_str = src.release();                                              \
  85.                                                                             \
  86.         return *this;                                                       \
  87.     }                                                                       \
  88.                                                                             \
  89.     chartype *data() { return m_str; }                                      \
  90.     const chartype *data() const { return m_str; }                          \
  91.     operator const chartype *() const { return m_str; }                     \
  92.     chartype operator[](size_t n) const { return m_str[n]; }                \
  93.                                                                             \
  94. private:                                                                    \
  95.     chartype *m_str;                                                        \
  96. }
  97.  
  98. DEFINE_BUFFER(wxCharBuffer, char, strdup);
  99.  
  100. #if wxUSE_WCHAR_T
  101.  
  102. inline wchar_t *wxWcsdupReplacement(const wchar_t *wcs)
  103. {
  104.     const size_t siz = (wxWcslen(wcs) + 1)*sizeof(wchar_t);
  105.     wchar_t *wcsCopy = (wchar_t *)malloc(siz);
  106.     memcpy(wcsCopy, wcs, siz);
  107.     return wcsCopy;
  108. }
  109.  
  110. DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxWcsdupReplacement);
  111.  
  112. #endif // wxUSE_WCHAR_T
  113.  
  114. #undef DEFINE_BUFFER
  115.  
  116. #if wxUSE_UNICODE
  117.     #define wxMB2WXbuf wxWCharBuffer
  118.     #define wxWX2MBbuf wxCharBuffer
  119.     #define wxWC2WXbuf wxChar*
  120.     #define wxWX2WCbuf wxChar*
  121. #else // ANSI
  122.     #define wxMB2WXbuf wxChar*
  123.     #define wxWX2MBbuf wxChar*
  124.     #define wxWC2WXbuf wxCharBuffer
  125.     #define wxWX2WCbuf wxWCharBuffer
  126. #endif // Unicode/ANSI
  127.  
  128. // ----------------------------------------------------------------------------
  129. // A class for holding growable data buffers (not necessarily strings)
  130. // ----------------------------------------------------------------------------
  131.  
  132. // This class manages the actual data buffer pointer and is ref-counted.
  133. class wxMemoryBufferData
  134. {
  135. public:
  136.     // the initial size and also the size added by ResizeIfNeeded()
  137.     enum { BLOCK_SIZE = 1024 };
  138.  
  139.     friend class wxMemoryBuffer;
  140.  
  141.     // everyting is private as it can only be used by wxMemoryBuffer
  142. private:
  143.     wxMemoryBufferData(size_t size = wxMemoryBufferData::BLOCK_SIZE)
  144.         : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
  145.     {
  146.     }
  147.     ~wxMemoryBufferData() { free(m_data); }
  148.  
  149.  
  150.     void ResizeIfNeeded(size_t newSize)
  151.     {
  152.         if (newSize > m_size)
  153.         {
  154.             void *dataOld = m_data;
  155.             m_data = realloc(m_data, newSize + wxMemoryBufferData::BLOCK_SIZE);
  156.             if ( !m_data )
  157.             {
  158.                 free(dataOld);
  159.             }
  160.  
  161.             m_size = newSize + wxMemoryBufferData::BLOCK_SIZE;
  162.         }
  163.     }
  164.  
  165.     void IncRef() { m_ref += 1; }
  166.     void DecRef()
  167.     {
  168.         m_ref -= 1;
  169.         if (m_ref == 0)  // are there no more references?
  170.             delete this;
  171.     }
  172.  
  173.  
  174.     // the buffer containing the data
  175.     void  *m_data;
  176.  
  177.     // the size of the buffer
  178.     size_t m_size;
  179.  
  180.     // the amount of data currently in the buffer
  181.     size_t m_len;
  182.  
  183.     // the reference count
  184.     size_t m_ref;
  185. };
  186.  
  187.  
  188. class wxMemoryBuffer
  189. {
  190. public:
  191.     // ctor and dtor
  192.     wxMemoryBuffer(size_t size = wxMemoryBufferData::BLOCK_SIZE)
  193.     {
  194.         m_bufdata = new wxMemoryBufferData(size);
  195.         m_bufdata->IncRef();
  196.     }
  197.  
  198.     ~wxMemoryBuffer() { m_bufdata->DecRef(); }
  199.  
  200.  
  201.     // copy and assignment
  202.     wxMemoryBuffer(const wxMemoryBuffer& src)
  203.         : m_bufdata(src.m_bufdata)
  204.     {
  205.         m_bufdata->IncRef();
  206.     }
  207.  
  208.     wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
  209.     {
  210.         m_bufdata->DecRef();
  211.         m_bufdata = src.m_bufdata;
  212.         m_bufdata->IncRef();
  213.         return *this;
  214.     }
  215.  
  216.  
  217.     // Accessors
  218.     void  *GetData() const    { return m_bufdata->m_data; }
  219.     size_t GetBufSize() const { return m_bufdata->m_size; }
  220.     size_t GetDataLen() const { return m_bufdata->m_len; }
  221.  
  222.     void   SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
  223.     void   SetDataLen(size_t len)
  224.     {
  225.         wxASSERT(len <= m_bufdata->m_size);
  226.         m_bufdata->m_len = len;
  227.     }
  228.  
  229.     // Ensure the buffer is big enough and return a pointer to it
  230.     void *GetWriteBuf(size_t sizeNeeded)
  231.     {
  232.         m_bufdata->ResizeIfNeeded(sizeNeeded);
  233.         return m_bufdata->m_data;
  234.     }
  235.  
  236.     // Update the length after the write
  237.     void  UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
  238.  
  239.     // Like the above, but appends to the buffer
  240.     void *GetAppendBuf(size_t sizeNeeded)
  241.     {
  242.         m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
  243.         return (char*)m_bufdata->m_data + m_bufdata->m_len;
  244.     }
  245.  
  246.     // Update the length after the append
  247.     void  UngetAppendBuf(size_t sizeUsed)
  248.     {
  249.         SetDataLen(m_bufdata->m_len + sizeUsed);
  250.     }
  251.  
  252.     // Other ways to append to the buffer
  253.     void  AppendByte(char data)
  254.     {
  255.         wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
  256.  
  257.         m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
  258.         *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
  259.         m_bufdata->m_len += 1;
  260.     }
  261.  
  262.     void  AppendData(void* data, size_t len)
  263.     {
  264.         memcpy(GetAppendBuf(len), data, len);
  265.         UngetAppendBuf(len);
  266.     }
  267.  
  268.     operator const char *() const { return (const char*)GetData(); }
  269.  
  270. private:
  271.     wxMemoryBufferData*  m_bufdata;
  272. };
  273.  
  274. // ----------------------------------------------------------------------------
  275. // template class for any kind of data
  276. // ----------------------------------------------------------------------------
  277.  
  278. // TODO
  279.  
  280. #endif // _WX_BUFFER_H
  281.