]> git.saurik.com Git - wxWidgets.git/blame - include/wx/buffer.h
destroy m_impl even if an exception is thrown from the main loop
[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
d18c8d3d
VS
19inline char *wxStrDup(const char *s) { return wxStrdupA(s); }
20#if wxUSE_WCHAR_T
21 inline wchar_t *wxStrDup(const wchar_t *ws) { return wxStrdupW(ws); }
22#endif
23
14971e5b
VZ
24// ----------------------------------------------------------------------------
25// Special classes for (wide) character strings: they use malloc/free instead
26// of new/delete
27// ----------------------------------------------------------------------------
28
d18c8d3d 29template <typename T>
ccd4deab 30class wxCharTypeBuffer
d18c8d3d
VS
31{
32public:
33 typedef T CharType;
34
35 wxCharTypeBuffer(const CharType *str = NULL)
36 : m_str(str ? wxStrDup(str) : NULL)
37 {
38 }
39
d18c8d3d
VS
40 wxCharTypeBuffer(size_t len)
41 : m_str((CharType *)malloc((len + 1)*sizeof(CharType)))
42 {
43 m_str[len] = (CharType)0;
44 }
45
46 /* no need to check for NULL, free() does it */
47 ~wxCharTypeBuffer() { free(m_str); }
48
49 /*
50 WARNING:
51
52 the copy ctor and assignment operators change the passed in object
53 even although it is declared as "const", so:
54
55 a) it shouldn't be really const
56 b) you shouldn't use it afterwards (or know that it was reset)
57
2b5f62a0 58 This is very ugly but is unfortunately needed to make the normal use\
d18c8d3d
VS
59 of wxCharTypeBuffer buffer objects possible and is very similar to what
60 std::auto_ptr<> does (as if it were an excuse...)
61 */
14971e5b 62
d18c8d3d
VS
63 /*
64 because of the remark above, release() is declared const even if it
65 isn't really const
66 */
67 CharType *release() const
68 {
69 CharType *p = m_str;
70 ((wxCharTypeBuffer *)this)->m_str = NULL;
71 return p;
72 }
c12ef8a2 73
d18c8d3d
VS
74 void reset()
75 {
76 free(m_str);
77 m_str = NULL;
78 }
c12ef8a2 79
d18c8d3d
VS
80 wxCharTypeBuffer(const wxCharTypeBuffer& src)
81 : m_str(src.release())
82 {
83 }
14971e5b 84
d18c8d3d
VS
85 wxCharTypeBuffer& operator=(const CharType *str)
86 {
87 free(m_str);
88 m_str = str ? wxStrDup(str) : NULL;
89 return *this;
90 }
91
92 wxCharTypeBuffer& operator=(const wxCharTypeBuffer& src)
93 {
94 free(m_str);
95 m_str = src.release();
96
97 return *this;
98 }
99
100 bool extend(size_t len)
101 {
102 CharType *
103 str = (CharType *)realloc(m_str, (len + 1)*sizeof(CharType));
104 if ( !str )
105 return false;
106
107 m_str = str;
108
109 return true;
110 }
111
112 CharType *data() { return m_str; }
113 const CharType *data() const { return m_str; }
114 operator const CharType *() const { return m_str; }
115 CharType operator[](size_t n) const { return m_str[n]; }
116
d18c8d3d
VS
117private:
118 CharType *m_str;
119};
120
121class WXDLLIMPEXP_BASE wxCharBuffer : public wxCharTypeBuffer<char>
122{
123public:
ccd4deab
VZ
124 typedef wxCharTypeBuffer<char> wxCharTypeBufferBase;
125
126 wxCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
127 wxCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
128
129#if !wxUSE_UNICODE
130 wxCharBuffer(const wxCStrData& cstr);
131#endif
d18c8d3d
VS
132};
133
134#if wxUSE_WCHAR_T
135class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
136{
137public:
ccd4deab
VZ
138 typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
139
140 wxWCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
141 wxWCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
142
143#if wxUSE_UNICODE
144 wxWCharBuffer(const wxCStrData& cstr);
145#endif
d18c8d3d
VS
146};
147#endif // wxUSE_WCHAR_T
2b5f62a0 148
f93d01be 149#if wxUSE_UNICODE
ccd4deab 150 #define wxWxCharBuffer wxWCharBuffer
2f4f6de7 151
e90c1d2a
VZ
152 #define wxMB2WXbuf wxWCharBuffer
153 #define wxWX2MBbuf wxCharBuffer
154 #define wxWC2WXbuf wxChar*
155 #define wxWX2WCbuf wxChar*
156#else // ANSI
ccd4deab 157 #define wxWxCharBuffer wxCharBuffer
2f4f6de7 158
e90c1d2a
VZ
159 #define wxMB2WXbuf wxChar*
160 #define wxWX2MBbuf wxChar*
161 #define wxWC2WXbuf wxCharBuffer
162 #define wxWX2WCbuf wxWCharBuffer
163#endif // Unicode/ANSI
f93d01be 164
b9fdb397
RD
165// ----------------------------------------------------------------------------
166// A class for holding growable data buffers (not necessarily strings)
167// ----------------------------------------------------------------------------
168
2b5f62a0
VZ
169// This class manages the actual data buffer pointer and is ref-counted.
170class wxMemoryBufferData
b9fdb397
RD
171{
172public:
2b5f62a0 173 // the initial size and also the size added by ResizeIfNeeded()
ae0ca755 174 enum { DefBufSize = 1024 };
2b5f62a0
VZ
175
176 friend class wxMemoryBuffer;
177
178 // everyting is private as it can only be used by wxMemoryBuffer
179private:
ae0ca755 180 wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
2b5f62a0 181 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
b9fdb397 182 {
b9fdb397 183 }
2b5f62a0 184 ~wxMemoryBufferData() { free(m_data); }
b9fdb397 185
b9fdb397 186
2b5f62a0 187 void ResizeIfNeeded(size_t newSize)
b9fdb397 188 {
2b5f62a0
VZ
189 if (newSize > m_size)
190 {
191 void *dataOld = m_data;
ae0ca755 192 m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
2b5f62a0
VZ
193 if ( !m_data )
194 {
195 free(dataOld);
196 }
197
ae0ca755 198 m_size = newSize + wxMemoryBufferData::DefBufSize;
2b5f62a0 199 }
b9fdb397
RD
200 }
201
2b5f62a0
VZ
202 void IncRef() { m_ref += 1; }
203 void DecRef()
b9fdb397 204 {
2b5f62a0
VZ
205 m_ref -= 1;
206 if (m_ref == 0) // are there no more references?
207 delete this;
b9fdb397 208 }
b9fdb397 209
2b5f62a0
VZ
210
211 // the buffer containing the data
212 void *m_data;
213
214 // the size of the buffer
215 size_t m_size;
216
217 // the amount of data currently in the buffer
218 size_t m_len;
219
220 // the reference count
221 size_t m_ref;
22f3361e
VZ
222
223 DECLARE_NO_COPY_CLASS(wxMemoryBufferData)
2b5f62a0
VZ
224};
225
226
227class wxMemoryBuffer
228{
229public:
230 // ctor and dtor
ae0ca755 231 wxMemoryBuffer(size_t size = wxMemoryBufferData::DefBufSize)
b9fdb397 232 {
2b5f62a0
VZ
233 m_bufdata = new wxMemoryBufferData(size);
234 m_bufdata->IncRef();
b9fdb397 235 }
b9fdb397 236
2b5f62a0
VZ
237 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
238
239
240 // copy and assignment
241 wxMemoryBuffer(const wxMemoryBuffer& src)
242 : m_bufdata(src.m_bufdata)
243 {
244 m_bufdata->IncRef();
b9fdb397 245 }
2b5f62a0
VZ
246
247 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
b9fdb397 248 {
2b5f62a0
VZ
249 m_bufdata->DecRef();
250 m_bufdata = src.m_bufdata;
251 m_bufdata->IncRef();
252 return *this;
b9fdb397
RD
253 }
254
b9fdb397 255
2b5f62a0
VZ
256 // Accessors
257 void *GetData() const { return m_bufdata->m_data; }
258 size_t GetBufSize() const { return m_bufdata->m_size; }
259 size_t GetDataLen() const { return m_bufdata->m_len; }
ef1cae87 260
2b5f62a0
VZ
261 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
262 void SetDataLen(size_t len)
ef1cae87 263 {
2b5f62a0
VZ
264 wxASSERT(len <= m_bufdata->m_size);
265 m_bufdata->m_len = len;
ef1cae87
RD
266 }
267
2b5f62a0
VZ
268 // Ensure the buffer is big enough and return a pointer to it
269 void *GetWriteBuf(size_t sizeNeeded)
ef1cae87 270 {
2b5f62a0
VZ
271 m_bufdata->ResizeIfNeeded(sizeNeeded);
272 return m_bufdata->m_data;
273 }
c12ef8a2 274
2b5f62a0
VZ
275 // Update the length after the write
276 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
ef1cae87 277
2b5f62a0
VZ
278 // Like the above, but appends to the buffer
279 void *GetAppendBuf(size_t sizeNeeded)
280 {
281 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
282 return (char*)m_bufdata->m_data + m_bufdata->m_len;
283 }
ef1cae87 284
2b5f62a0
VZ
285 // Update the length after the append
286 void UngetAppendBuf(size_t sizeUsed)
287 {
288 SetDataLen(m_bufdata->m_len + sizeUsed);
289 }
ef1cae87 290
2b5f62a0
VZ
291 // Other ways to append to the buffer
292 void AppendByte(char data)
b9fdb397 293 {
2b5f62a0
VZ
294 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
295
296 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
297 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
298 m_bufdata->m_len += 1;
299 }
300
68bc51a9 301 void AppendData(const void *data, size_t len)
2b5f62a0
VZ
302 {
303 memcpy(GetAppendBuf(len), data, len);
304 UngetAppendBuf(len);
b9fdb397
RD
305 }
306
2b5f62a0
VZ
307 operator const char *() const { return (const char*)GetData(); }
308
b9fdb397 309private:
2b5f62a0 310 wxMemoryBufferData* m_bufdata;
b9fdb397
RD
311};
312
14971e5b
VZ
313// ----------------------------------------------------------------------------
314// template class for any kind of data
315// ----------------------------------------------------------------------------
316
317// TODO
318
319#endif // _WX_BUFFER_H