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