]> git.saurik.com Git - wxWidgets.git/blame - include/wx/buffer.h
added macros to avoid code repetition when defining comparison operators; use them...
[wxWidgets.git] / include / wx / buffer.h
CommitLineData
14971e5b 1///////////////////////////////////////////////////////////////////////////////
c12ef8a2 2// Name: wx/buffer.h
14971e5b
VZ
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$
8// Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
65571936 9// Licence: wxWindows licence
14971e5b
VZ
10///////////////////////////////////////////////////////////////////////////////
11
14971e5b
VZ
12#ifndef _WX_BUFFER_H
13#define _WX_BUFFER_H
14
853d7d3d 15#include "wx/wxchar.h"
e90c1d2a 16
e2473d4c
VZ
17#include <stdlib.h> // malloc() and free()
18
14971e5b
VZ
19// ----------------------------------------------------------------------------
20// Special classes for (wide) character strings: they use malloc/free instead
21// of new/delete
22// ----------------------------------------------------------------------------
23
2b5f62a0 24#define DEFINE_BUFFER(classname, chartype, strdupfunc) \
b08a2401 25class WXDLLIMPEXP_BASE classname \
2b5f62a0
VZ
26{ \
27public: \
fedde9b9 28 classname(const chartype *str = NULL) \
2b5f62a0
VZ
29 : m_str(str ? strdupfunc(str) : NULL) \
30 { \
31 } \
32 \
414b7b40
VZ
33 classname(const wxCStrData& cstr); \
34 \
fedde9b9 35 classname(size_t len) \
2b5f62a0
VZ
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 \
11fead7c
VZ
69 void reset() \
70 { \
71 free(m_str); \
72 m_str = NULL; \
73 } \
74 \
2b5f62a0
VZ
75 classname(const classname& src) \
76 : m_str(src.release()) \
77 { \
78 } \
79 \
80 classname& operator=(const chartype *str) \
81 { \
82 free(m_str); \
83 m_str = str ? strdupfunc(str) : NULL; \
84 return *this; \
85 } \
86 \
87 classname& operator=(const classname& src) \
88 { \
89 free(m_str); \
90 m_str = src.release(); \
91 \
92 return *this; \
93 } \
94 \
6901ac37
VZ
95 bool extend(size_t len) \
96 { \
97 chartype * \
98 str = (chartype *)realloc(m_str, (len + 1)*sizeof(chartype)); \
99 if ( !str ) \
100 return false; \
101 \
102 m_str = str; \
103 \
104 return true; \
105 } \
106 \
2b5f62a0
VZ
107 chartype *data() { return m_str; } \
108 const chartype *data() const { return m_str; } \
109 operator const chartype *() const { return m_str; } \
110 chartype operator[](size_t n) const { return m_str[n]; } \
111 \
112private: \
113 chartype *m_str; \
114}
115
07243717 116DEFINE_BUFFER(wxCharBuffer, char, wxStrdupA);
14971e5b 117
7a3e402c 118#if wxUSE_WCHAR_T
c12ef8a2 119
07243717 120DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxStrdupW);
c12ef8a2
VZ
121
122#endif // wxUSE_WCHAR_T
14971e5b 123
2b5f62a0
VZ
124#undef DEFINE_BUFFER
125
f93d01be 126#if wxUSE_UNICODE
2f4f6de7
VZ
127 typedef wxWCharBuffer wxWxCharBuffer;
128
e90c1d2a
VZ
129 #define wxMB2WXbuf wxWCharBuffer
130 #define wxWX2MBbuf wxCharBuffer
131 #define wxWC2WXbuf wxChar*
132 #define wxWX2WCbuf wxChar*
133#else // ANSI
2f4f6de7
VZ
134 typedef wxCharBuffer wxWxCharBuffer;
135
e90c1d2a
VZ
136 #define wxMB2WXbuf wxChar*
137 #define wxWX2MBbuf wxChar*
138 #define wxWC2WXbuf wxCharBuffer
139 #define wxWX2WCbuf wxWCharBuffer
140#endif // Unicode/ANSI
f93d01be 141
b9fdb397
RD
142// ----------------------------------------------------------------------------
143// A class for holding growable data buffers (not necessarily strings)
144// ----------------------------------------------------------------------------
145
2b5f62a0
VZ
146// This class manages the actual data buffer pointer and is ref-counted.
147class wxMemoryBufferData
b9fdb397
RD
148{
149public:
2b5f62a0 150 // the initial size and also the size added by ResizeIfNeeded()
ae0ca755 151 enum { DefBufSize = 1024 };
2b5f62a0
VZ
152
153 friend class wxMemoryBuffer;
154
155 // everyting is private as it can only be used by wxMemoryBuffer
156private:
ae0ca755 157 wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
2b5f62a0 158 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
b9fdb397 159 {
b9fdb397 160 }
2b5f62a0 161 ~wxMemoryBufferData() { free(m_data); }
b9fdb397 162
b9fdb397 163
2b5f62a0 164 void ResizeIfNeeded(size_t newSize)
b9fdb397 165 {
2b5f62a0
VZ
166 if (newSize > m_size)
167 {
168 void *dataOld = m_data;
ae0ca755 169 m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
2b5f62a0
VZ
170 if ( !m_data )
171 {
172 free(dataOld);
173 }
174
ae0ca755 175 m_size = newSize + wxMemoryBufferData::DefBufSize;
2b5f62a0 176 }
b9fdb397
RD
177 }
178
2b5f62a0
VZ
179 void IncRef() { m_ref += 1; }
180 void DecRef()
b9fdb397 181 {
2b5f62a0
VZ
182 m_ref -= 1;
183 if (m_ref == 0) // are there no more references?
184 delete this;
b9fdb397 185 }
b9fdb397 186
2b5f62a0
VZ
187
188 // the buffer containing the data
189 void *m_data;
190
191 // the size of the buffer
192 size_t m_size;
193
194 // the amount of data currently in the buffer
195 size_t m_len;
196
197 // the reference count
198 size_t m_ref;
22f3361e
VZ
199
200 DECLARE_NO_COPY_CLASS(wxMemoryBufferData)
2b5f62a0
VZ
201};
202
203
204class wxMemoryBuffer
205{
206public:
207 // ctor and dtor
ae0ca755 208 wxMemoryBuffer(size_t size = wxMemoryBufferData::DefBufSize)
b9fdb397 209 {
2b5f62a0
VZ
210 m_bufdata = new wxMemoryBufferData(size);
211 m_bufdata->IncRef();
b9fdb397 212 }
b9fdb397 213
2b5f62a0
VZ
214 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
215
216
217 // copy and assignment
218 wxMemoryBuffer(const wxMemoryBuffer& src)
219 : m_bufdata(src.m_bufdata)
220 {
221 m_bufdata->IncRef();
b9fdb397 222 }
2b5f62a0
VZ
223
224 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
b9fdb397 225 {
2b5f62a0
VZ
226 m_bufdata->DecRef();
227 m_bufdata = src.m_bufdata;
228 m_bufdata->IncRef();
229 return *this;
b9fdb397
RD
230 }
231
b9fdb397 232
2b5f62a0
VZ
233 // Accessors
234 void *GetData() const { return m_bufdata->m_data; }
235 size_t GetBufSize() const { return m_bufdata->m_size; }
236 size_t GetDataLen() const { return m_bufdata->m_len; }
ef1cae87 237
2b5f62a0
VZ
238 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
239 void SetDataLen(size_t len)
ef1cae87 240 {
2b5f62a0
VZ
241 wxASSERT(len <= m_bufdata->m_size);
242 m_bufdata->m_len = len;
ef1cae87
RD
243 }
244
2b5f62a0
VZ
245 // Ensure the buffer is big enough and return a pointer to it
246 void *GetWriteBuf(size_t sizeNeeded)
ef1cae87 247 {
2b5f62a0
VZ
248 m_bufdata->ResizeIfNeeded(sizeNeeded);
249 return m_bufdata->m_data;
250 }
c12ef8a2 251
2b5f62a0
VZ
252 // Update the length after the write
253 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
ef1cae87 254
2b5f62a0
VZ
255 // Like the above, but appends to the buffer
256 void *GetAppendBuf(size_t sizeNeeded)
257 {
258 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
259 return (char*)m_bufdata->m_data + m_bufdata->m_len;
260 }
ef1cae87 261
2b5f62a0
VZ
262 // Update the length after the append
263 void UngetAppendBuf(size_t sizeUsed)
264 {
265 SetDataLen(m_bufdata->m_len + sizeUsed);
266 }
ef1cae87 267
2b5f62a0
VZ
268 // Other ways to append to the buffer
269 void AppendByte(char data)
b9fdb397 270 {
2b5f62a0
VZ
271 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
272
273 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
274 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
275 m_bufdata->m_len += 1;
276 }
277
68bc51a9 278 void AppendData(const void *data, size_t len)
2b5f62a0
VZ
279 {
280 memcpy(GetAppendBuf(len), data, len);
281 UngetAppendBuf(len);
b9fdb397
RD
282 }
283
2b5f62a0
VZ
284 operator const char *() const { return (const char*)GetData(); }
285
b9fdb397 286private:
2b5f62a0 287 wxMemoryBufferData* m_bufdata;
b9fdb397
RD
288};
289
14971e5b
VZ
290// ----------------------------------------------------------------------------
291// template class for any kind of data
292// ----------------------------------------------------------------------------
293
294// TODO
295
296#endif // _WX_BUFFER_H