]>
git.saurik.com Git - wxWidgets.git/blob - include/wx/buffer.h
1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: auto buffer classes: buffers which automatically free memory
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
12 // these classes are for private use only for now, they're not documented
17 #include "wx/wxchar.h"
19 #include <string.h> // strdup
21 // ----------------------------------------------------------------------------
22 // Special classes for (wide) character strings: they use malloc/free instead
24 // ----------------------------------------------------------------------------
26 #define DEFINE_BUFFER(classname, chartype, strdupfunc) \
30 classname(const chartype *str) \
31 : m_str(str ? strdupfunc(str) : NULL) \
35 classname(size_t len) \
36 : m_str((chartype *)malloc((len + 1)*sizeof(chartype))) \
38 m_str[len] = (chartype)0; \
41 /* no need to check for NULL, free() does it */ \
42 ~classname() { free(m_str); } \
47 the copy ctor and assignment operators change the passed in object \
48 even although it is declared as "const", so: \
50 a) it shouldn't be really const \
51 b) you shouldn't use it afterwards (or know that it was reset) \
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...) \
59 because of the remark above, release() is declared const even if it \
62 chartype *release() const \
64 chartype *p = m_str; \
65 ((classname *)this)->m_str = NULL; \
69 classname(const classname& src) \
70 : m_str(src.release()) \
74 classname& operator=(const chartype *str) \
77 m_str = str ? strdupfunc(str) : NULL; \
81 classname& operator=(const classname& src) \
84 m_str = src.release(); \
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]; } \
99 inline char *strdup(const char *cs
)
104 const size_t siz
= (len
+ 1)*sizeof(char);
105 char *csCopy
= (char *)malloc(siz
);
106 memcpy(csCopy
, cs
, siz
);
111 DEFINE_BUFFER(wxCharBuffer
, char, strdup
);
115 inline wchar_t *wxWcsdupReplacement(const wchar_t *wcs
)
117 const size_t siz
= (wxWcslen(wcs
) + 1)*sizeof(wchar_t);
118 wchar_t *wcsCopy
= (wchar_t *)malloc(siz
);
119 memcpy(wcsCopy
, wcs
, siz
);
123 DEFINE_BUFFER(wxWCharBuffer
, wchar_t, wxWcsdupReplacement
);
125 #endif // wxUSE_WCHAR_T
130 #define wxMB2WXbuf wxWCharBuffer
131 #define wxWX2MBbuf wxCharBuffer
132 #define wxWC2WXbuf wxChar*
133 #define wxWX2WCbuf wxChar*
135 #define wxMB2WXbuf wxChar*
136 #define wxWX2MBbuf wxChar*
137 #define wxWC2WXbuf wxCharBuffer
138 #define wxWX2WCbuf wxWCharBuffer
139 #endif // Unicode/ANSI
141 // ----------------------------------------------------------------------------
142 // A class for holding growable data buffers (not necessarily strings)
143 // ----------------------------------------------------------------------------
145 // This class manages the actual data buffer pointer and is ref-counted.
146 class wxMemoryBufferData
149 // the initial size and also the size added by ResizeIfNeeded()
150 enum { BLOCK_SIZE
= 1024 };
152 friend class wxMemoryBuffer
;
154 // everyting is private as it can only be used by wxMemoryBuffer
156 wxMemoryBufferData(size_t size
= wxMemoryBufferData::BLOCK_SIZE
)
157 : m_data(size
? malloc(size
) : NULL
), m_size(size
), m_len(0), m_ref(0)
160 ~wxMemoryBufferData() { free(m_data
); }
163 void ResizeIfNeeded(size_t newSize
)
165 if (newSize
> m_size
)
167 void *dataOld
= m_data
;
168 m_data
= realloc(m_data
, newSize
+ wxMemoryBufferData::BLOCK_SIZE
);
174 m_size
= newSize
+ wxMemoryBufferData::BLOCK_SIZE
;
178 void IncRef() { m_ref
+= 1; }
182 if (m_ref
== 0) // are there no more references?
187 // the buffer containing the data
190 // the size of the buffer
193 // the amount of data currently in the buffer
196 // the reference count
205 wxMemoryBuffer(size_t size
= wxMemoryBufferData::BLOCK_SIZE
)
207 m_bufdata
= new wxMemoryBufferData(size
);
211 ~wxMemoryBuffer() { m_bufdata
->DecRef(); }
214 // copy and assignment
215 wxMemoryBuffer(const wxMemoryBuffer
& src
)
216 : m_bufdata(src
.m_bufdata
)
221 wxMemoryBuffer
& operator=(const wxMemoryBuffer
& src
)
224 m_bufdata
= src
.m_bufdata
;
231 void *GetData() const { return m_bufdata
->m_data
; }
232 size_t GetBufSize() const { return m_bufdata
->m_size
; }
233 size_t GetDataLen() const { return m_bufdata
->m_len
; }
235 void SetBufSize(size_t size
) { m_bufdata
->ResizeIfNeeded(size
); }
236 void SetDataLen(size_t len
)
238 wxASSERT(len
<= m_bufdata
->m_size
);
239 m_bufdata
->m_len
= len
;
242 // Ensure the buffer is big enough and return a pointer to it
243 void *GetWriteBuf(size_t sizeNeeded
)
245 m_bufdata
->ResizeIfNeeded(sizeNeeded
);
246 return m_bufdata
->m_data
;
249 // Update the length after the write
250 void UngetWriteBuf(size_t sizeUsed
) { SetDataLen(sizeUsed
); }
252 // Like the above, but appends to the buffer
253 void *GetAppendBuf(size_t sizeNeeded
)
255 m_bufdata
->ResizeIfNeeded(m_bufdata
->m_len
+ sizeNeeded
);
256 return (char*)m_bufdata
->m_data
+ m_bufdata
->m_len
;
259 // Update the length after the append
260 void UngetAppendBuf(size_t sizeUsed
)
262 SetDataLen(m_bufdata
->m_len
+ sizeUsed
);
265 // Other ways to append to the buffer
266 void AppendByte(char data
)
268 wxCHECK_RET( m_bufdata
->m_data
, _T("invalid wxMemoryBuffer") );
270 m_bufdata
->ResizeIfNeeded(m_bufdata
->m_len
+ 1);
271 *(((char*)m_bufdata
->m_data
) + m_bufdata
->m_len
) = data
;
272 m_bufdata
->m_len
+= 1;
275 void AppendData(void* data
, size_t len
)
277 memcpy(GetAppendBuf(len
), data
, len
);
281 operator const char *() const { return (const char*)GetData(); }
284 wxMemoryBufferData
* m_bufdata
;
287 // ----------------------------------------------------------------------------
288 // template class for any kind of data
289 // ----------------------------------------------------------------------------
293 #endif // _WX_BUFFER_H