]> git.saurik.com Git - wxWidgets.git/blame - include/wx/buffer.h
Applied patch which allows you to detach a stream
[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
14971e5b
VZ
19// ----------------------------------------------------------------------------
20// Special classes for (wide) character strings: they use malloc/free instead
21// of new/delete
22// ----------------------------------------------------------------------------
23
2b5f62a0 24#define DEFINE_BUFFER(classname, chartype, strdupfunc) \
b08a2401 25class WXDLLIMPEXP_BASE classname \
2b5f62a0
VZ
26{ \
27public: \
fedde9b9 28 classname(const chartype *str = NULL) \
2b5f62a0
VZ
29 : m_str(str ? strdupfunc(str) : NULL) \
30 { \
31 } \
32 \
fedde9b9 33 classname(size_t len) \
2b5f62a0
VZ
34 : m_str((chartype *)malloc((len + 1)*sizeof(chartype))) \
35 { \
36 m_str[len] = (chartype)0; \
37 } \
38 \
39 /* no need to check for NULL, free() does it */ \
40 ~classname() { free(m_str); } \
41 \
42 /* \
43 WARNING: \
44 \
45 the copy ctor and assignment operators change the passed in object \
46 even although it is declared as "const", so: \
47 \
48 a) it shouldn't be really const \
49 b) you shouldn't use it afterwards (or know that it was reset) \
50 \
51 This is very ugly but is unfortunately needed to make the normal use\
52 of classname buffer objects possible and is very similar to what \
53 std::auto_ptr<> does (as if it were an excuse...) \
54 */ \
55 \
56 /* \
57 because of the remark above, release() is declared const even if it \
58 isn't really const \
59 */ \
60 chartype *release() const \
61 { \
62 chartype *p = m_str; \
63 ((classname *)this)->m_str = NULL; \
64 return p; \
65 } \
66 \
11fead7c
VZ
67 void reset() \
68 { \
69 free(m_str); \
70 m_str = NULL; \
71 } \
72 \
2b5f62a0
VZ
73 classname(const classname& src) \
74 : m_str(src.release()) \
75 { \
76 } \
77 \
78 classname& operator=(const chartype *str) \
79 { \
80 free(m_str); \
81 m_str = str ? strdupfunc(str) : NULL; \
82 return *this; \
83 } \
84 \
85 classname& operator=(const classname& src) \
86 { \
87 free(m_str); \
88 m_str = src.release(); \
89 \
90 return *this; \
91 } \
92 \
6901ac37
VZ
93 bool extend(size_t len) \
94 { \
95 chartype * \
96 str = (chartype *)realloc(m_str, (len + 1)*sizeof(chartype)); \
97 if ( !str ) \
98 return false; \
99 \
100 m_str = str; \
101 \
102 return true; \
103 } \
104 \
2b5f62a0
VZ
105 chartype *data() { return m_str; } \
106 const chartype *data() const { return m_str; } \
107 operator const chartype *() const { return m_str; } \
108 chartype operator[](size_t n) const { return m_str[n]; } \
109 \
110private: \
111 chartype *m_str; \
112}
113
07243717 114DEFINE_BUFFER(wxCharBuffer, char, wxStrdupA);
14971e5b 115
7a3e402c 116#if wxUSE_WCHAR_T
c12ef8a2 117
07243717 118DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxStrdupW);
c12ef8a2
VZ
119
120#endif // wxUSE_WCHAR_T
14971e5b 121
2b5f62a0
VZ
122#undef DEFINE_BUFFER
123
f93d01be 124#if wxUSE_UNICODE
2f4f6de7
VZ
125 typedef wxWCharBuffer wxWxCharBuffer;
126
e90c1d2a
VZ
127 #define wxMB2WXbuf wxWCharBuffer
128 #define wxWX2MBbuf wxCharBuffer
129 #define wxWC2WXbuf wxChar*
130 #define wxWX2WCbuf wxChar*
131#else // ANSI
2f4f6de7
VZ
132 typedef wxCharBuffer wxWxCharBuffer;
133
e90c1d2a
VZ
134 #define wxMB2WXbuf wxChar*
135 #define wxWX2MBbuf wxChar*
136 #define wxWC2WXbuf wxCharBuffer
137 #define wxWX2WCbuf wxWCharBuffer
138#endif // Unicode/ANSI
f93d01be 139
b9fdb397
RD
140// ----------------------------------------------------------------------------
141// A class for holding growable data buffers (not necessarily strings)
142// ----------------------------------------------------------------------------
143
2b5f62a0
VZ
144// This class manages the actual data buffer pointer and is ref-counted.
145class wxMemoryBufferData
b9fdb397
RD
146{
147public:
2b5f62a0 148 // the initial size and also the size added by ResizeIfNeeded()
ae0ca755 149 enum { DefBufSize = 1024 };
2b5f62a0
VZ
150
151 friend class wxMemoryBuffer;
152
153 // everyting is private as it can only be used by wxMemoryBuffer
154private:
ae0ca755 155 wxMemoryBufferData(size_t size = wxMemoryBufferData::DefBufSize)
2b5f62a0 156 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
b9fdb397 157 {
b9fdb397 158 }
2b5f62a0 159 ~wxMemoryBufferData() { free(m_data); }
b9fdb397 160
b9fdb397 161
2b5f62a0 162 void ResizeIfNeeded(size_t newSize)
b9fdb397 163 {
2b5f62a0
VZ
164 if (newSize > m_size)
165 {
166 void *dataOld = m_data;
ae0ca755 167 m_data = realloc(m_data, newSize + wxMemoryBufferData::DefBufSize);
2b5f62a0
VZ
168 if ( !m_data )
169 {
170 free(dataOld);
171 }
172
ae0ca755 173 m_size = newSize + wxMemoryBufferData::DefBufSize;
2b5f62a0 174 }
b9fdb397
RD
175 }
176
2b5f62a0
VZ
177 void IncRef() { m_ref += 1; }
178 void DecRef()
b9fdb397 179 {
2b5f62a0
VZ
180 m_ref -= 1;
181 if (m_ref == 0) // are there no more references?
182 delete this;
b9fdb397 183 }
b9fdb397 184
2b5f62a0
VZ
185
186 // the buffer containing the data
187 void *m_data;
188
189 // the size of the buffer
190 size_t m_size;
191
192 // the amount of data currently in the buffer
193 size_t m_len;
194
195 // the reference count
196 size_t m_ref;
22f3361e
VZ
197
198 DECLARE_NO_COPY_CLASS(wxMemoryBufferData)
2b5f62a0
VZ
199};
200
201
202class wxMemoryBuffer
203{
204public:
205 // ctor and dtor
ae0ca755 206 wxMemoryBuffer(size_t size = wxMemoryBufferData::DefBufSize)
b9fdb397 207 {
2b5f62a0
VZ
208 m_bufdata = new wxMemoryBufferData(size);
209 m_bufdata->IncRef();
b9fdb397 210 }
b9fdb397 211
2b5f62a0
VZ
212 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
213
214
215 // copy and assignment
216 wxMemoryBuffer(const wxMemoryBuffer& src)
217 : m_bufdata(src.m_bufdata)
218 {
219 m_bufdata->IncRef();
b9fdb397 220 }
2b5f62a0
VZ
221
222 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
b9fdb397 223 {
2b5f62a0
VZ
224 m_bufdata->DecRef();
225 m_bufdata = src.m_bufdata;
226 m_bufdata->IncRef();
227 return *this;
b9fdb397
RD
228 }
229
b9fdb397 230
2b5f62a0
VZ
231 // Accessors
232 void *GetData() const { return m_bufdata->m_data; }
233 size_t GetBufSize() const { return m_bufdata->m_size; }
234 size_t GetDataLen() const { return m_bufdata->m_len; }
ef1cae87 235
2b5f62a0
VZ
236 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
237 void SetDataLen(size_t len)
ef1cae87 238 {
2b5f62a0
VZ
239 wxASSERT(len <= m_bufdata->m_size);
240 m_bufdata->m_len = len;
ef1cae87
RD
241 }
242
2b5f62a0
VZ
243 // Ensure the buffer is big enough and return a pointer to it
244 void *GetWriteBuf(size_t sizeNeeded)
ef1cae87 245 {
2b5f62a0
VZ
246 m_bufdata->ResizeIfNeeded(sizeNeeded);
247 return m_bufdata->m_data;
248 }
c12ef8a2 249
2b5f62a0
VZ
250 // Update the length after the write
251 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
ef1cae87 252
2b5f62a0
VZ
253 // Like the above, but appends to the buffer
254 void *GetAppendBuf(size_t sizeNeeded)
255 {
256 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
257 return (char*)m_bufdata->m_data + m_bufdata->m_len;
258 }
ef1cae87 259
2b5f62a0
VZ
260 // Update the length after the append
261 void UngetAppendBuf(size_t sizeUsed)
262 {
263 SetDataLen(m_bufdata->m_len + sizeUsed);
264 }
ef1cae87 265
2b5f62a0
VZ
266 // Other ways to append to the buffer
267 void AppendByte(char data)
b9fdb397 268 {
2b5f62a0
VZ
269 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
270
271 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
272 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
273 m_bufdata->m_len += 1;
274 }
275
68bc51a9 276 void AppendData(const void *data, size_t len)
2b5f62a0
VZ
277 {
278 memcpy(GetAppendBuf(len), data, len);
279 UngetAppendBuf(len);
b9fdb397
RD
280 }
281
2b5f62a0
VZ
282 operator const char *() const { return (const char*)GetData(); }
283
b9fdb397 284private:
2b5f62a0 285 wxMemoryBufferData* m_bufdata;
b9fdb397
RD
286};
287
14971e5b
VZ
288// ----------------------------------------------------------------------------
289// template class for any kind of data
290// ----------------------------------------------------------------------------
291
292// TODO
293
294#endif // _WX_BUFFER_H