]> git.saurik.com Git - wxWidgets.git/blame - include/wx/buffer.h
fix comparison of BYTE variable with -1 after last commit
[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
30386aeb
VZ
229// type of the value returned by wxString::utf8_str()
230#if wxUSE_UNICODE_UTF8
30386aeb 231 #define wxUTF8Buf char *
53c75dc2
VZ
232#else
233 #define wxUTF8Buf wxCharBuffer
30386aeb
VZ
234#endif
235
b9fdb397
RD
236// ----------------------------------------------------------------------------
237// A class for holding growable data buffers (not necessarily strings)
238// ----------------------------------------------------------------------------
239
2b5f62a0
VZ
240// This class manages the actual data buffer pointer and is ref-counted.
241class wxMemoryBufferData
b9fdb397
RD
242{
243public:
2b5f62a0 244 // the initial size and also the size added by ResizeIfNeeded()
ae0ca755 245 enum { DefBufSize = 1024 };
2b5f62a0
VZ
246
247 friend class wxMemoryBuffer;
248
249 // everyting is private as it can only be used by wxMemoryBuffer
250private:
ae0ca755 251 wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
2b5f62a0 252 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
b9fdb397 253 {
b9fdb397 254 }
2b5f62a0 255 ~wxMemoryBufferData() { free(m_data); }
b9fdb397 256
b9fdb397 257
2b5f62a0 258 void ResizeIfNeeded(size_t newSize)
b9fdb397 259 {
2b5f62a0
VZ
260 if (newSize > m_size)
261 {
262 void *dataOld = m_data;
ae0ca755 263 m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
2b5f62a0
VZ
264 if ( !m_data )
265 {
266 free(dataOld);
267 }
268
ae0ca755 269 m_size = newSize + wxMemoryBufferData::DefBufSize;
2b5f62a0 270 }
b9fdb397
RD
271 }
272
2b5f62a0
VZ
273 void IncRef() { m_ref += 1; }
274 void DecRef()
b9fdb397 275 {
2b5f62a0
VZ
276 m_ref -= 1;
277 if (m_ref == 0) // are there no more references?
278 delete this;
b9fdb397 279 }
b9fdb397 280
2b5f62a0
VZ
281
282 // the buffer containing the data
283 void *m_data;
284
285 // the size of the buffer
286 size_t m_size;
287
288 // the amount of data currently in the buffer
289 size_t m_len;
290
291 // the reference count
292 size_t m_ref;
22f3361e
VZ
293
294 DECLARE_NO_COPY_CLASS(wxMemoryBufferData)
2b5f62a0
VZ
295};
296
297
4ec4d861 298class WXDLLIMPEXP_BASE wxMemoryBuffer
2b5f62a0
VZ
299{
300public:
301 // ctor and dtor
ae0ca755 302 wxMemoryBuffer(size_t size = wxMemoryBufferData::DefBufSize)
b9fdb397 303 {
2b5f62a0
VZ
304 m_bufdata = new wxMemoryBufferData(size);
305 m_bufdata->IncRef();
b9fdb397 306 }
b9fdb397 307
2b5f62a0
VZ
308 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
309
310
311 // copy and assignment
312 wxMemoryBuffer(const wxMemoryBuffer& src)
313 : m_bufdata(src.m_bufdata)
314 {
315 m_bufdata->IncRef();
b9fdb397 316 }
2b5f62a0
VZ
317
318 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
b9fdb397 319 {
2b5f62a0
VZ
320 m_bufdata->DecRef();
321 m_bufdata = src.m_bufdata;
322 m_bufdata->IncRef();
323 return *this;
b9fdb397
RD
324 }
325
b9fdb397 326
2b5f62a0
VZ
327 // Accessors
328 void *GetData() const { return m_bufdata->m_data; }
329 size_t GetBufSize() const { return m_bufdata->m_size; }
330 size_t GetDataLen() const { return m_bufdata->m_len; }
ef1cae87 331
2b5f62a0
VZ
332 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
333 void SetDataLen(size_t len)
ef1cae87 334 {
2b5f62a0
VZ
335 wxASSERT(len <= m_bufdata->m_size);
336 m_bufdata->m_len = len;
ef1cae87
RD
337 }
338
2b5f62a0
VZ
339 // Ensure the buffer is big enough and return a pointer to it
340 void *GetWriteBuf(size_t sizeNeeded)
ef1cae87 341 {
2b5f62a0
VZ
342 m_bufdata->ResizeIfNeeded(sizeNeeded);
343 return m_bufdata->m_data;
344 }
c12ef8a2 345
2b5f62a0
VZ
346 // Update the length after the write
347 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
ef1cae87 348
2b5f62a0
VZ
349 // Like the above, but appends to the buffer
350 void *GetAppendBuf(size_t sizeNeeded)
351 {
352 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
353 return (char*)m_bufdata->m_data + m_bufdata->m_len;
354 }
ef1cae87 355
2b5f62a0
VZ
356 // Update the length after the append
357 void UngetAppendBuf(size_t sizeUsed)
358 {
359 SetDataLen(m_bufdata->m_len + sizeUsed);
360 }
ef1cae87 361
2b5f62a0
VZ
362 // Other ways to append to the buffer
363 void AppendByte(char data)
b9fdb397 364 {
2b5f62a0
VZ
365 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
366
367 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
368 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
369 m_bufdata->m_len += 1;
370 }
371
68bc51a9 372 void AppendData(const void *data, size_t len)
2b5f62a0
VZ
373 {
374 memcpy(GetAppendBuf(len), data, len);
375 UngetAppendBuf(len);
b9fdb397
RD
376 }
377
2b5f62a0
VZ
378 operator const char *() const { return (const char*)GetData(); }
379
b9fdb397 380private:
2b5f62a0 381 wxMemoryBufferData* m_bufdata;
b9fdb397
RD
382};
383
14971e5b
VZ
384// ----------------------------------------------------------------------------
385// template class for any kind of data
386// ----------------------------------------------------------------------------
387
388// TODO
389
390#endif // _WX_BUFFER_H