1 ///////////////////////////////////////////////////////////////////////////////
3 // Purpose: auto buffer classes: buffers which automatically free memory
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
15 #include "wx/wxchar.h"
17 #include <stdlib.h> // malloc() and free()
19 inline char *wxStrDup(const char *s
) { return wxStrdupA(s
); }
21 inline wchar_t *wxStrDup(const wchar_t *ws
) { return wxStrdupW(ws
); }
24 // ----------------------------------------------------------------------------
25 // Special classes for (wide) character strings: they use malloc/free instead
27 // ----------------------------------------------------------------------------
30 class wxCharTypeBuffer
35 wxCharTypeBuffer(const CharType
*str
= NULL
)
36 : m_str(str
? wxStrDup(str
) : NULL
)
40 wxCharTypeBuffer(size_t len
)
41 : m_str((CharType
*)malloc((len
+ 1)*sizeof(CharType
)))
43 m_str
[len
] = (CharType
)0;
46 /* no need to check for NULL, free() does it */
47 ~wxCharTypeBuffer() { free(m_str
); }
52 the copy ctor and assignment operators change the passed in object
53 even although it is declared as "const", so:
55 a) it shouldn't be really const
56 b) you shouldn't use it afterwards (or know that it was reset)
58 This is very ugly but is unfortunately needed to make the normal use\
59 of wxCharTypeBuffer buffer objects possible and is very similar to what
60 std::auto_ptr<> does (as if it were an excuse...)
64 because of the remark above, release() is declared const even if it
67 CharType
*release() const
70 ((wxCharTypeBuffer
*)this)->m_str
= NULL
;
80 wxCharTypeBuffer(const wxCharTypeBuffer
& src
)
81 : m_str(src
.release())
85 wxCharTypeBuffer
& operator=(const CharType
*str
)
88 m_str
= str
? wxStrDup(str
) : NULL
;
92 wxCharTypeBuffer
& operator=(const wxCharTypeBuffer
& src
)
95 m_str
= src
.release();
100 bool extend(size_t len
)
103 str
= (CharType
*)realloc(m_str
, (len
+ 1)*sizeof(CharType
));
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
]; }
121 class WXDLLIMPEXP_BASE wxCharBuffer
: public wxCharTypeBuffer
<char>
124 typedef wxCharTypeBuffer
<char> wxCharTypeBufferBase
;
126 wxCharBuffer(const CharType
*str
= NULL
) : wxCharTypeBufferBase(str
) {}
127 wxCharBuffer(size_t len
) : wxCharTypeBufferBase(len
) {}
130 wxCharBuffer(const wxCStrData
& cstr
);
135 class WXDLLIMPEXP_BASE wxWCharBuffer
: public wxCharTypeBuffer
<wchar_t>
138 typedef wxCharTypeBuffer
<wchar_t> wxCharTypeBufferBase
;
140 wxWCharBuffer(const CharType
*str
= NULL
) : wxCharTypeBufferBase(str
) {}
141 wxWCharBuffer(size_t len
) : wxCharTypeBufferBase(len
) {}
144 wxWCharBuffer(const wxCStrData
& cstr
);
147 #endif // wxUSE_WCHAR_T
150 #define wxWxCharBuffer wxWCharBuffer
152 #define wxMB2WXbuf wxWCharBuffer
153 #define wxWX2MBbuf wxCharBuffer
154 #define wxWC2WXbuf wxChar*
155 #define wxWX2WCbuf wxChar*
157 #define wxWxCharBuffer wxCharBuffer
159 #define wxMB2WXbuf wxChar*
160 #define wxWX2MBbuf wxChar*
161 #define wxWC2WXbuf wxCharBuffer
162 #define wxWX2WCbuf wxWCharBuffer
163 #endif // Unicode/ANSI
165 // ----------------------------------------------------------------------------
166 // A class for holding growable data buffers (not necessarily strings)
167 // ----------------------------------------------------------------------------
169 // This class manages the actual data buffer pointer and is ref-counted.
170 class wxMemoryBufferData
173 // the initial size and also the size added by ResizeIfNeeded()
174 enum { DefBufSize
= 1024 };
176 friend class wxMemoryBuffer
;
178 // everyting is private as it can only be used by wxMemoryBuffer
180 wxMemoryBufferData(size_t size
= wxMemoryBufferData::DefBufSize
)
181 : m_data(size
? malloc(size
) : NULL
), m_size(size
), m_len(0), m_ref(0)
184 ~wxMemoryBufferData() { free(m_data
); }
187 void ResizeIfNeeded(size_t newSize
)
189 if (newSize
> m_size
)
191 void *dataOld
= m_data
;
192 m_data
= realloc(m_data
, newSize
+ wxMemoryBufferData::DefBufSize
);
198 m_size
= newSize
+ wxMemoryBufferData::DefBufSize
;
202 void IncRef() { m_ref
+= 1; }
206 if (m_ref
== 0) // are there no more references?
211 // the buffer containing the data
214 // the size of the buffer
217 // the amount of data currently in the buffer
220 // the reference count
223 DECLARE_NO_COPY_CLASS(wxMemoryBufferData
)
231 wxMemoryBuffer(size_t size
= wxMemoryBufferData::DefBufSize
)
233 m_bufdata
= new wxMemoryBufferData(size
);
237 ~wxMemoryBuffer() { m_bufdata
->DecRef(); }
240 // copy and assignment
241 wxMemoryBuffer(const wxMemoryBuffer
& src
)
242 : m_bufdata(src
.m_bufdata
)
247 wxMemoryBuffer
& operator=(const wxMemoryBuffer
& src
)
250 m_bufdata
= src
.m_bufdata
;
257 void *GetData() const { return m_bufdata
->m_data
; }
258 size_t GetBufSize() const { return m_bufdata
->m_size
; }
259 size_t GetDataLen() const { return m_bufdata
->m_len
; }
261 void SetBufSize(size_t size
) { m_bufdata
->ResizeIfNeeded(size
); }
262 void SetDataLen(size_t len
)
264 wxASSERT(len
<= m_bufdata
->m_size
);
265 m_bufdata
->m_len
= len
;
268 // Ensure the buffer is big enough and return a pointer to it
269 void *GetWriteBuf(size_t sizeNeeded
)
271 m_bufdata
->ResizeIfNeeded(sizeNeeded
);
272 return m_bufdata
->m_data
;
275 // Update the length after the write
276 void UngetWriteBuf(size_t sizeUsed
) { SetDataLen(sizeUsed
); }
278 // Like the above, but appends to the buffer
279 void *GetAppendBuf(size_t sizeNeeded
)
281 m_bufdata
->ResizeIfNeeded(m_bufdata
->m_len
+ sizeNeeded
);
282 return (char*)m_bufdata
->m_data
+ m_bufdata
->m_len
;
285 // Update the length after the append
286 void UngetAppendBuf(size_t sizeUsed
)
288 SetDataLen(m_bufdata
->m_len
+ sizeUsed
);
291 // Other ways to append to the buffer
292 void AppendByte(char data
)
294 wxCHECK_RET( m_bufdata
->m_data
, _T("invalid wxMemoryBuffer") );
296 m_bufdata
->ResizeIfNeeded(m_bufdata
->m_len
+ 1);
297 *(((char*)m_bufdata
->m_data
) + m_bufdata
->m_len
) = data
;
298 m_bufdata
->m_len
+= 1;
301 void AppendData(const void *data
, size_t len
)
303 memcpy(GetAppendBuf(len
), data
, len
);
307 operator const char *() const { return (const char*)GetData(); }
310 wxMemoryBufferData
* m_bufdata
;
313 // ----------------------------------------------------------------------------
314 // template class for any kind of data
315 // ----------------------------------------------------------------------------
319 #endif // _WX_BUFFER_H