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