]> git.saurik.com Git - wxWidgets.git/blob - include/wx/buffer.h
Added simplistic makefile/project files for wxWinCE.
[wxWidgets.git] / include / wx / buffer.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/buffer.h
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
17 #include "wx/wxchar.h"
18
19 #include <string.h> // strdup
20
21 // ----------------------------------------------------------------------------
22 // Special classes for (wide) character strings: they use malloc/free instead
23 // of new/delete
24 // ----------------------------------------------------------------------------
25
26 #define DEFINE_BUFFER(classname, chartype, strdupfunc) \
27 class classname \
28 { \
29 public: \
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 \
94 private: \
95 chartype *m_str; \
96 }
97
98 DEFINE_BUFFER(wxCharBuffer, char, strdup);
99
100 #if wxUSE_WCHAR_T
101
102 inline wchar_t *wxWcsdupReplacement(const wchar_t *wcs)
103 {
104 const size_t siz = (wxWcslen(wcs) + 1)*sizeof(wchar_t);
105 wchar_t *wcsCopy = (wchar_t *)malloc(siz);
106 memcpy(wcsCopy, wcs, siz);
107 return wcsCopy;
108 }
109
110 DEFINE_BUFFER(wxWCharBuffer, wchar_t, wxWcsdupReplacement);
111
112 #endif // wxUSE_WCHAR_T
113
114 #undef DEFINE_BUFFER
115
116 #if wxUSE_UNICODE
117 #define wxMB2WXbuf wxWCharBuffer
118 #define wxWX2MBbuf wxCharBuffer
119 #define wxWC2WXbuf wxChar*
120 #define wxWX2WCbuf wxChar*
121 #else // ANSI
122 #define wxMB2WXbuf wxChar*
123 #define wxWX2MBbuf wxChar*
124 #define wxWC2WXbuf wxCharBuffer
125 #define wxWX2WCbuf wxWCharBuffer
126 #endif // Unicode/ANSI
127
128 // ----------------------------------------------------------------------------
129 // A class for holding growable data buffers (not necessarily strings)
130 // ----------------------------------------------------------------------------
131
132 // This class manages the actual data buffer pointer and is ref-counted.
133 class wxMemoryBufferData
134 {
135 public:
136 // the initial size and also the size added by ResizeIfNeeded()
137 enum { BLOCK_SIZE = 1024 };
138
139 friend class wxMemoryBuffer;
140
141 // everyting is private as it can only be used by wxMemoryBuffer
142 private:
143 wxMemoryBufferData(size_t size = wxMemoryBufferData::BLOCK_SIZE)
144 : m_data(size ? malloc(size) : NULL), m_size(size), m_len(0), m_ref(0)
145 {
146 }
147 ~wxMemoryBufferData() { free(m_data); }
148
149
150 void ResizeIfNeeded(size_t newSize)
151 {
152 if (newSize > m_size)
153 {
154 void *dataOld = m_data;
155 m_data = realloc(m_data, newSize + wxMemoryBufferData::BLOCK_SIZE);
156 if ( !m_data )
157 {
158 free(dataOld);
159 }
160
161 m_size = newSize + wxMemoryBufferData::BLOCK_SIZE;
162 }
163 }
164
165 void IncRef() { m_ref += 1; }
166 void DecRef()
167 {
168 m_ref -= 1;
169 if (m_ref == 0) // are there no more references?
170 delete this;
171 }
172
173
174 // the buffer containing the data
175 void *m_data;
176
177 // the size of the buffer
178 size_t m_size;
179
180 // the amount of data currently in the buffer
181 size_t m_len;
182
183 // the reference count
184 size_t m_ref;
185 };
186
187
188 class wxMemoryBuffer
189 {
190 public:
191 // ctor and dtor
192 wxMemoryBuffer(size_t size = wxMemoryBufferData::BLOCK_SIZE)
193 {
194 m_bufdata = new wxMemoryBufferData(size);
195 m_bufdata->IncRef();
196 }
197
198 ~wxMemoryBuffer() { m_bufdata->DecRef(); }
199
200
201 // copy and assignment
202 wxMemoryBuffer(const wxMemoryBuffer& src)
203 : m_bufdata(src.m_bufdata)
204 {
205 m_bufdata->IncRef();
206 }
207
208 wxMemoryBuffer& operator=(const wxMemoryBuffer& src)
209 {
210 m_bufdata->DecRef();
211 m_bufdata = src.m_bufdata;
212 m_bufdata->IncRef();
213 return *this;
214 }
215
216
217 // Accessors
218 void *GetData() const { return m_bufdata->m_data; }
219 size_t GetBufSize() const { return m_bufdata->m_size; }
220 size_t GetDataLen() const { return m_bufdata->m_len; }
221
222 void SetBufSize(size_t size) { m_bufdata->ResizeIfNeeded(size); }
223 void SetDataLen(size_t len)
224 {
225 wxASSERT(len <= m_bufdata->m_size);
226 m_bufdata->m_len = len;
227 }
228
229 // Ensure the buffer is big enough and return a pointer to it
230 void *GetWriteBuf(size_t sizeNeeded)
231 {
232 m_bufdata->ResizeIfNeeded(sizeNeeded);
233 return m_bufdata->m_data;
234 }
235
236 // Update the length after the write
237 void UngetWriteBuf(size_t sizeUsed) { SetDataLen(sizeUsed); }
238
239 // Like the above, but appends to the buffer
240 void *GetAppendBuf(size_t sizeNeeded)
241 {
242 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + sizeNeeded);
243 return (char*)m_bufdata->m_data + m_bufdata->m_len;
244 }
245
246 // Update the length after the append
247 void UngetAppendBuf(size_t sizeUsed)
248 {
249 SetDataLen(m_bufdata->m_len + sizeUsed);
250 }
251
252 // Other ways to append to the buffer
253 void AppendByte(char data)
254 {
255 wxCHECK_RET( m_bufdata->m_data, _T("invalid wxMemoryBuffer") );
256
257 m_bufdata->ResizeIfNeeded(m_bufdata->m_len + 1);
258 *(((char*)m_bufdata->m_data) + m_bufdata->m_len) = data;
259 m_bufdata->m_len += 1;
260 }
261
262 void AppendData(void* data, size_t len)
263 {
264 memcpy(GetAppendBuf(len), data, len);
265 UngetAppendBuf(len);
266 }
267
268 operator const char *() const { return (const char*)GetData(); }
269
270 private:
271 wxMemoryBufferData* m_bufdata;
272 };
273
274 // ----------------------------------------------------------------------------
275 // template class for any kind of data
276 // ----------------------------------------------------------------------------
277
278 // TODO
279
280 #endif // _WX_BUFFER_H