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