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