]> git.saurik.com Git - wxWidgets.git/blame - include/wx/buffer.h
Patch from FN that fixes bug in RefreshItem on an item that has no
[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
681e4412 48 static const wxCharTypeBuffer CreateNonOwned(const CharType *str)
486a5941
VS
49 {
50 wxCharTypeBuffer buf;
681e4412 51 buf.m_str = wx_const_cast(CharType*, str);
486a5941
VS
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
681e4412
VS
160 wxCharBuffer(const wxCharTypeBufferBase& buf)
161 : wxCharTypeBufferBase(buf) {}
162
ccd4deab
VZ
163 wxCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
164 wxCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
165
ccd4deab 166 wxCharBuffer(const wxCStrData& cstr);
d18c8d3d
VS
167};
168
169#if wxUSE_WCHAR_T
170class WXDLLIMPEXP_BASE wxWCharBuffer : public wxCharTypeBuffer<wchar_t>
171{
172public:
ccd4deab
VZ
173 typedef wxCharTypeBuffer<wchar_t> wxCharTypeBufferBase;
174
681e4412
VS
175 wxWCharBuffer(const wxCharTypeBufferBase& buf)
176 : wxCharTypeBufferBase(buf) {}
177
ccd4deab
VZ
178 wxWCharBuffer(const CharType *str = NULL) : wxCharTypeBufferBase(str) {}
179 wxWCharBuffer(size_t len) : wxCharTypeBufferBase(len) {}
180
ccd4deab 181 wxWCharBuffer(const wxCStrData& cstr);
d18c8d3d
VS
182};
183#endif // wxUSE_WCHAR_T
2b5f62a0 184
ef0f1387
VS
185// wxCharTypeBuffer<T> implicitly convertible to T*
186template <typename T>
665e6a87 187class wxWritableCharTypeBuffer : public wxCharTypeBuffer<T>
ef0f1387
VS
188{
189public:
190 typedef typename wxCharTypeBuffer<T>::CharType CharType;
191
192 wxWritableCharTypeBuffer(const wxCharTypeBuffer<T>& src)
193 : wxCharTypeBuffer<T>(src) {}
194 // FIXME-UTF8: this won't be needed after converting mb_str()/wc_str() to
195 // always return a buffer
196 wxWritableCharTypeBuffer(const CharType *str = NULL)
197 : wxCharTypeBuffer<T>(str) {}
198
199 operator CharType*() { return this->data(); }
200};
201
202typedef wxWritableCharTypeBuffer<char> wxWritableCharBuffer;
203typedef wxWritableCharTypeBuffer<wchar_t> wxWritableWCharBuffer;
204
205
f93d01be 206#if wxUSE_UNICODE
ccd4deab 207 #define wxWxCharBuffer wxWCharBuffer
2f4f6de7 208
e90c1d2a
VZ
209 #define wxMB2WXbuf wxWCharBuffer
210 #define wxWX2MBbuf wxCharBuffer
81727065
VS
211 #if wxUSE_UNICODE_WCHAR
212 #define wxWC2WXbuf wxChar*
213 #define wxWX2WCbuf wxChar*
214 #elif wxUSE_UNICODE_UTF8
215 #define wxWC2WXbuf wxWCharBuffer
216 #define wxWX2WCbuf wxWCharBuffer
217 #endif
e90c1d2a 218#else // ANSI
ccd4deab 219 #define wxWxCharBuffer wxCharBuffer
2f4f6de7 220
e90c1d2a
VZ
221 #define wxMB2WXbuf wxChar*
222 #define wxWX2MBbuf wxChar*
223 #define wxWC2WXbuf wxCharBuffer
224 #define wxWX2WCbuf wxWCharBuffer
225#endif // Unicode/ANSI
f93d01be 226
b9fdb397
RD
227// ----------------------------------------------------------------------------
228// A class for holding growable data buffers (not necessarily strings)
229// ----------------------------------------------------------------------------
230
2b5f62a0
VZ
231// This class manages the actual data buffer pointer and is ref-counted.
232class wxMemoryBufferData
b9fdb397
RD
233{
234public:
2b5f62a0 235 // the initial size and also the size added by ResizeIfNeeded()
ae0ca755 236 enum { DefBufSize = 1024 };
2b5f62a0
VZ
237
238 friend class wxMemoryBuffer;
239
240 // everyting is private as it can only be used by wxMemoryBuffer
241private:
ae0ca755 242 wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
2b5f62a0 243 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
b9fdb397 244 {
b9fdb397 245 }
2b5f62a0 246 ~wxMemoryBufferData() { free(m_data); }
b9fdb397 247
b9fdb397 248
2b5f62a0 249 void ResizeIfNeeded(size_t newSize)
b9fdb397 250 {
2b5f62a0
VZ
251 if (newSize > m_size)
252 {
253 void *dataOld = m_data;
ae0ca755 254 m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
2b5f62a0
VZ
255 if ( !m_data )
256 {
257 free(dataOld);
258 }
259
ae0ca755 260 m_size = newSize + wxMemoryBufferData::DefBufSize;
2b5f62a0 261 }
b9fdb397
RD
262 }
263
2b5f62a0
VZ
264 void IncRef() { m_ref += 1; }
265 void DecRef()
b9fdb397 266 {
2b5f62a0
VZ
267 m_ref -= 1;
268 if (m_ref == 0) // are there no more references?
269 delete this;
b9fdb397 270 }
b9fdb397 271
2b5f62a0
VZ
272
273 // the buffer containing the data
274 void *m_data;
275
276 // the size of the buffer
277 size_t m_size;
278
279 // the amount of data currently in the buffer
280 size_t m_len;
281
282 // the reference count
283 size_t m_ref;
22f3361e
VZ
284
285 DECLARE_NO_COPY_CLASS(wxMemoryBufferData)
2b5f62a0
VZ
286};
287
288
289class wxMemoryBuffer
290{
291public:
292 // ctor and dtor
ae0ca755 293 wxMemoryBuffer(size_t size = wxMemoryBufferData::DefBufSize)
b9fdb397 294 {
2b5f62a0
VZ
295 m_bufdata = new wxMemoryBufferData(size);
296 m_bufdata->IncRef();
b9fdb397 297 }
b9fdb397 298
2b5f62a0
VZ
299 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
300
301
302 // copy and assignment
303 wxMemoryBuffer(const wxMemoryBuffer& src)
304 : m_bufdata(src.m_bufdata)
305 {
306 m_bufdata->IncRef();
b9fdb397 307 }
2b5f62a0
VZ
308
309 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
b9fdb397 310 {
2b5f62a0
VZ
311 m_bufdata->DecRef();
312 m_bufdata = src.m_bufdata;
313 m_bufdata->IncRef();
314 return *this;
b9fdb397
RD
315 }
316
b9fdb397 317
2b5f62a0
VZ
318 // Accessors
319 void *GetData() const { return m_bufdata->m_data; }
320 size_t GetBufSize() const { return m_bufdata->m_size; }
321 size_t GetDataLen() const { return m_bufdata->m_len; }
ef1cae87 322
2b5f62a0
VZ
323 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
324 void SetDataLen(size_t len)
ef1cae87 325 {
2b5f62a0
VZ
326 wxASSERT(len <= m_bufdata->m_size);
327 m_bufdata->m_len = len;
ef1cae87
RD
328 }
329
2b5f62a0
VZ
330 // Ensure the buffer is big enough and return a pointer to it
331 void *GetWriteBuf(size_t sizeNeeded)
ef1cae87 332 {
2b5f62a0
VZ
333 m_bufdata->ResizeIfNeeded(sizeNeeded);
334 return m_bufdata->m_data;
335 }
c12ef8a2 336
2b5f62a0
VZ
337 // Update the length after the write
338 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
ef1cae87 339
2b5f62a0
VZ
340 // Like the above, but appends to the buffer
341 void *GetAppendBuf(size_t sizeNeeded)
342 {
343 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
344 return (char*)m_bufdata->m_data + m_bufdata->m_len;
345 }
ef1cae87 346
2b5f62a0
VZ
347 // Update the length after the append
348 void UngetAppendBuf(size_t sizeUsed)
349 {
350 SetDataLen(m_bufdata->m_len + sizeUsed);
351 }
ef1cae87 352
2b5f62a0
VZ
353 // Other ways to append to the buffer
354 void AppendByte(char data)
b9fdb397 355 {
2b5f62a0
VZ
356 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
357
358 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
359 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
360 m_bufdata->m_len += 1;
361 }
362
68bc51a9 363 void AppendData(const void *data, size_t len)
2b5f62a0
VZ
364 {
365 memcpy(GetAppendBuf(len), data, len);
366 UngetAppendBuf(len);
b9fdb397
RD
367 }
368
2b5f62a0
VZ
369 operator const char *() const { return (const char*)GetData(); }
370
b9fdb397 371private:
2b5f62a0 372 wxMemoryBufferData* m_bufdata;
b9fdb397
RD
373};
374
14971e5b
VZ
375// ----------------------------------------------------------------------------
376// template class for any kind of data
377// ----------------------------------------------------------------------------
378
379// TODO
380
381#endif // _WX_BUFFER_H