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