]> git.saurik.com Git - wxWidgets.git/blob - wxPython/src/streams.i
correction for memory leak
[wxWidgets.git] / wxPython / src / streams.i
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: streams.i
3 // Purpose: SWIG definitions of the wxFileSystem family of classes
4 //
5 // Author: Joerg Baumann
6 //
7 // Created: 25-Sept-2000
8 // RCS-ID: $Id$
9 // Copyright: (c) 2000 by Joerg Baumann
10 // Licence: wxWindows license
11 /////////////////////////////////////////////////////////////////////////////
12
13 %module streams
14
15 %{
16 #include "helpers.h"
17 #include <wx/stream.h>
18 #include <wx/list.h>
19 %}
20
21 //----------------------------------------------------------------------
22
23 %include typemaps.i
24 %include my_typemaps.i
25
26 // Import some definitions of other classes, etc.
27 %import _defs.i
28
29 %pragma(python) code = "import wx"
30 %pragma(python) code = "import string"
31
32 //----------------------------------------------------------------------
33 // typemaps for wxInputStream
34 %typemap(python,in) wxInputStream *stream {
35 if (PyInstance_Check($source)) {
36 wxPyInputStream* ptr;
37 if (SWIG_GetPtrObj($source, (void **) &ptr,"_wxPyInputStream_p")) {
38 PyErr_SetString(PyExc_TypeError,"Expected _wxInputStream_p.");
39 return NULL;
40 }
41 $target = ptr->wxi;
42 } else {
43 PyErr_SetString(PyExc_TypeError,"Expected _wxInputStream_p.");
44 return NULL;
45 }
46 }
47
48
49 // typemaps for wxInputStream
50 %typemap(python,out) wxInputStream* {
51 wxPyInputStream * _ptr = NULL;
52
53 if ($source) {
54 _ptr = new wxPyInputStream($source);
55 }
56 $target = wxPyConstructObject(_ptr, "wxInputStream", TRUE);
57 }
58
59 //----------------------------------------------------------------------
60
61 %{ // C++
62 // definitions of wxStringPtrList and wxPyInputStream
63 #include <wx/listimpl.cpp>
64 WX_DEFINE_LIST(wxStringPtrList);
65
66
67 void wxPyInputStream::close() {
68 /* do nothing */
69 }
70
71 void wxPyInputStream::flush() {
72 /*do nothing*/
73 }
74
75 bool wxPyInputStream::eof() {
76 if (wxi)
77 return wxi->Eof();
78 else
79 return TRUE;
80 }
81
82 wxPyInputStream::~wxPyInputStream() {
83 /*do nothing*/
84 }
85
86 wxString* wxPyInputStream::read(int size) {
87 wxString* s = NULL;
88 const int BUFSIZE = 1024;
89
90 // check if we have a real wxInputStream to work with
91 if (!wxi) {
92 PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below");
93 return NULL;
94 }
95
96 if (size < 0) {
97 // init buffers
98 char * buf = new char[BUFSIZE];
99 if (!buf) {
100 PyErr_NoMemory();
101 return NULL;
102 }
103
104 s = new wxString();
105 if (!s) {
106 delete buf;
107 PyErr_NoMemory();
108 return NULL;
109 }
110
111 // read until EOF
112 wxPy_BEGIN_ALLOW_THREADS;
113 while (! wxi->Eof()) {
114 wxi->Read(buf, BUFSIZE);
115 //*s += wxString(buf, wxi->LastRead());
116 s->Append(buf, wxi->LastRead());
117 }
118 delete buf;
119 wxPy_END_ALLOW_THREADS;
120
121 // error check
122 if (wxi->LastError() == wxSTREAM_READ_ERROR) {
123 delete s;
124 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
125 return NULL;
126 }
127
128 } else { // Read only size number of characters
129 s = new wxString;
130 if (!s) {
131 PyErr_NoMemory();
132 return NULL;
133 }
134
135 // read size bytes
136 wxPy_BEGIN_ALLOW_THREADS;
137 wxi->Read(s->GetWriteBuf(size+1), size);
138 s->UngetWriteBuf(wxi->LastRead());
139 wxPy_END_ALLOW_THREADS;
140
141 // error check
142 if (wxi->LastError() == wxSTREAM_READ_ERROR) {
143 delete s;
144 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
145 return NULL;
146 }
147 }
148 return s;
149 }
150
151
152 wxString* wxPyInputStream::readline (int size) {
153 // check if we have a real wxInputStream to work with
154 if (!wxi) {
155 PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below");
156 return NULL;
157 }
158
159 // init buffer
160 int i;
161 char ch;
162 wxString* s = new wxString;
163 if (!s) {
164 PyErr_NoMemory();
165 return NULL;
166 }
167
168 // read until \n or byte limit reached
169 wxPy_BEGIN_ALLOW_THREADS;
170 for (i=ch=0; (ch != '\n') && (!wxi->Eof()) && ((size < 0) || (i < size)); i++) {
171 *s += ch = wxi->GetC();
172 }
173 wxPy_END_ALLOW_THREADS;
174
175 // errorcheck
176 if (wxi->LastError() == wxSTREAM_READ_ERROR) {
177 delete s;
178 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
179 return NULL;
180 }
181 return s;
182 }
183
184
185 wxStringPtrList* wxPyInputStream::readlines (int sizehint) {
186 // check if we have a real wxInputStream to work with
187 if (!wxi) {
188 PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below");
189 return NULL;
190 }
191
192 // init list
193 wxStringPtrList* l = new wxStringPtrList();
194 if (!l) {
195 PyErr_NoMemory();
196 return NULL;
197 }
198
199 // read sizehint bytes or until EOF
200 wxPy_BEGIN_ALLOW_THREADS;
201 int i;
202 for (i=0; (!wxi->Eof()) && ((sizehint < 0) || (i < sizehint));) {
203 wxString* s = readline();
204 if (s == NULL) {
205 l->DeleteContents(TRUE);
206 l->Clear();
207 return NULL;
208 }
209 l->Append(s);
210 i = i + s->Length();
211 }
212 wxPy_END_ALLOW_THREADS;
213
214 // error check
215 if (wxi->LastError() == wxSTREAM_READ_ERROR) {
216 l->DeleteContents(TRUE);
217 l->Clear();
218 PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
219 return NULL;
220 }
221 return l;
222 }
223
224
225 void wxPyInputStream::seek(int offset, int whence) {
226 if (wxi)
227 wxi->SeekI(offset, wxSeekMode(whence));
228 }
229
230 int wxPyInputStream::tell(){
231 if (wxi)
232 return wxi->TellI();
233 }
234
235
236
237 // wxInputStream which operates on a Python file-like object
238 class wxPyCBInputStream : public wxInputStream {
239 protected:
240 PyObject* read;
241 PyObject* seek;
242 PyObject* tell;
243 PyObject* py;
244
245 virtual size_t OnSysRead(void *buffer, size_t bufsize) {
246 if (bufsize == 0)
247 return 0;
248
249 wxPyTState* state = wxPyBeginBlockThreads();
250 PyObject* arglist = Py_BuildValue("(i)", bufsize);
251 PyObject* result = PyEval_CallObject(read, arglist);
252 Py_DECREF(arglist);
253
254 size_t o = 0;
255 if ((result != NULL) && PyString_Check(result)) {
256 o = PyString_Size(result);
257 if (o == 0)
258 m_lasterror = wxSTREAM_EOF;
259 if (o > bufsize)
260 o = bufsize;
261 strncpy((char*)buffer, PyString_AsString(result), o);
262 Py_DECREF(result);
263
264 }
265 else
266 m_lasterror = wxSTREAM_READ_ERROR;
267 wxPyEndBlockThreads(state);
268 m_lastcount = o;
269 return o;
270 }
271
272 virtual size_t OnSysWrite(const void *buffer, size_t bufsize){
273 m_lasterror = wxSTREAM_WRITE_ERROR;
274 return 0;
275 }
276
277 virtual off_t OnSysSeek(off_t off, wxSeekMode mode){
278 wxPyTState* state = wxPyBeginBlockThreads();
279 PyObject*arglist = Py_BuildValue("(ii)", off, mode);
280 PyObject*result = PyEval_CallObject(seek, arglist);
281 Py_DECREF(arglist);
282 Py_XDECREF(result);
283 wxPyEndBlockThreads(state);
284 return OnSysTell();
285 }
286
287 virtual off_t OnSysTell() const{
288 wxPyTState* state = wxPyBeginBlockThreads();
289 PyObject* arglist = Py_BuildValue("()");
290 PyObject* result = PyEval_CallObject(tell, arglist);
291 Py_DECREF(arglist);
292 off_t o = 0;
293 if (result != NULL) {
294 o = PyInt_AsLong(result);
295 Py_DECREF(result);
296 };
297 wxPyEndBlockThreads(state);
298 return o;
299 }
300
301 wxPyCBInputStream(PyObject *p, PyObject *r, PyObject *s, PyObject *t)
302 : py(p), read(r), seek(s), tell(t)
303 {}
304
305 public:
306 ~wxPyCBInputStream() {
307 wxPyTState* state = wxPyBeginBlockThreads();
308 Py_XDECREF(py);
309 Py_XDECREF(read);
310 Py_XDECREF(seek);
311 Py_XDECREF(tell);
312 wxPyEndBlockThreads(state);
313 }
314
315 virtual size_t GetSize() {
316 if (seek && tell) {
317 off_t temp = OnSysTell();
318 off_t ret = OnSysSeek(0, wxFromEnd);
319 OnSysSeek(temp, wxFromStart);
320 return ret;
321 }
322 else
323 return 0;
324 }
325
326 static wxPyCBInputStream* create(PyObject *py) {
327 PyObject* read;
328 PyObject* seek;
329 PyObject* tell;
330
331 if (!PyInstance_Check(py) && !PyFile_Check(py)) {
332 PyErr_SetString(PyExc_TypeError, "Not a file-like object");
333 Py_XDECREF(py);
334 return NULL;
335 }
336 read = getMethod(py, "read");
337 seek = getMethod(py, "seek");
338 tell = getMethod(py, "tell");
339
340 if (!read) {
341 PyErr_SetString(PyExc_TypeError, "Not a file-like object");
342 Py_XDECREF(py);
343 Py_XDECREF(read);
344 Py_XDECREF(seek);
345 Py_XDECREF(tell);
346 return NULL;
347 }
348 return new wxPyCBInputStream(py, read, seek, tell);
349 }
350
351 static PyObject* getMethod(PyObject* py, char* name) {
352 if (!PyObject_HasAttrString(py, name))
353 return NULL;
354 PyObject* o = PyObject_GetAttrString(py, name);
355 if (!PyMethod_Check(o) && !PyCFunction_Check(o)) {
356 Py_DECREF(o);
357 return NULL;
358 }
359 return o;
360 }
361
362 protected:
363
364 };
365
366 %} // End of the C++
367 //----------------------------------------------------------------------
368
369
370 // block threads for wxPyInputStream **** WHY?
371 %except(python) {
372 $function
373 }
374
375
376 // wxStringPtrList* to python list of strings typemap
377 %typemap(python, out) wxStringPtrList* {
378 if ($source) {
379 $target = PyList_New($source->GetCount());
380 wxStringPtrList::Node *node = $source->GetFirst();
381 for (int i=0; node; i++) {
382 wxString *s = node->GetData();
383 PyList_SetItem($target, i, PyString_FromStringAndSize(s->c_str(), s->Len()));
384 node = node->GetNext();
385 delete s;
386 }
387 delete $source;
388 }
389 else
390 $target=0;
391 }
392
393
394 // transport exceptions via %target=0
395 %typemap(python, out) wxPyInputStream* {
396 char _ptemp[128];
397 if ($source) {
398 SWIG_MakePtr(_ptemp, (char *) $source,"_wxPyInputStream_p");
399 $target = Py_BuildValue("s",_ptemp);
400 }
401 else
402 $target=0;
403 }
404
405
406 // transport exceptions via %target=0
407 %typemap(python, out) wxString* {
408 if ($source) {
409 $target = PyString_FromStringAndSize($source->c_str(), $source->Len());
410 delete $source;
411 }
412 else
413 $target=0;
414 }
415
416
417
418 %name(wxInputStream) class wxPyInputStream {
419 public:
420 %addmethods {
421 wxPyInputStream(PyObject* p) {
422 wxInputStream* wxi = wxPyCBInputStream::create(p);
423 if (wxi)
424 return new wxPyInputStream(wxi);
425 else
426 return NULL;
427 }
428 }
429 void close();
430 void flush();
431 bool eof();
432 wxString* read(int size=-1);
433 wxString* readline(int size=-1);
434 wxStringPtrList* readlines(int sizehint=-1);
435 void seek(int offset, int whence=0);
436 int tell();
437 /*
438 bool isatty();
439 int fileno();
440 void truncate(int size=-1);
441 void write(wxString data);
442 void writelines(wxStringPtrList);
443 */
444 }
445
446
447
448 // TODO: make a more fully implemented file interface...
449 class wxOutputStream {
450 public:
451 /*
452 void close();
453 void flush();
454 wxString* read(int size=-1);
455 wxString* readline(int size=-1);
456 wxStringPtrList* readlines(int sizehint=-1);
457 void seek(int offset, int whence=0);
458 int tell();
459 bool isatty();
460 int fileno();
461 void truncate(int size=-1);
462 void write(wxString data);
463 void writelines(wxStringPtrList);
464 */
465
466 %addmethods {
467 void write(const wxString& str) {
468 self->Write(str.c_str(), str.Length());
469 }
470 }
471 };
472
473
474 // restore except and typemaps
475 %typemap(python,out) wxStringPtrList*;
476 %typemap(python,out) wxPyInputStream*;
477 %typemap(python, out) wxString* {
478 $target = PyString_FromStringAndSize($source->c_str(), $source->Len());
479 }
480 %except(python) {
481 wxPy_BEGIN_ALLOW_THREADS;
482 $function
483 wxPy_END_ALLOW_THREADS;
484 }
485
486
487 //----------------------------------------------------------------------
488
489 %init %{
490 wxPyPtrTypeMap_Add("wxInputStream", "wxPyInputStream");
491 %}
492
493 //----------------------------------------------------------------------