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