]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/src/helpers.cpp
Removed unneeded assert
[wxWidgets.git] / wxPython / src / helpers.cpp
index 0943cabc006302e47d3ab25c8cdaf1d71fb32b84..bf1d3402f31995eb63c6605e65c36ac01facbd82 100644 (file)
@@ -15,6 +15,7 @@
 #undef DEBUG
 #include <Python.h>
 #include "helpers.h"
+#include "pyistream.h"
 
 #ifdef __WXMSW__
 #include <wx/msw/private.h>
@@ -223,11 +224,13 @@ PyObject* __wxStart(PyObject* /* self */, PyObject* args)
 
 void __wxCleanup() {
     wxEntryCleanup();
+#ifdef WXP_WITH_THREAD
     delete wxPyTMutex;
     wxPyTMutex = NULL;
     wxPyTStates->Empty();
     delete wxPyTStates;
     wxPyTStates = NULL;
+#endif
 }
 
 
@@ -254,8 +257,8 @@ PyObject* __wxSetDictionary(PyObject* /* self */, PyObject* args)
 #ifdef __WXMOTIF__
 #define wxPlatform "__WXMOTIF__"
 #endif
-#ifdef __WXQT__
-#define wxPlatform "__WXQT__"
+#ifdef __WXX11__
+#define wxPlatform "__WXX11__"
 #endif
 #ifdef __WXGTK__
 #define wxPlatform "__WXGTK__"
@@ -448,9 +451,12 @@ unsigned long wxPyGetCurrentThreadId() {
     return wxThread::GetCurrentId();
 }
 
-
+static PyThreadState* gs_shutdownTState;
 static
 PyThreadState* wxPyGetThreadState() {
+    if (wxPyTMutex == NULL) // Python is shutting down...
+        return gs_shutdownTState;
+
     unsigned long ctid = wxPyGetCurrentThreadId();
     PyThreadState* tstate = NULL;
 
@@ -469,6 +475,10 @@ PyThreadState* wxPyGetThreadState() {
 
 static
 void wxPySaveThreadState(PyThreadState* tstate) {
+    if (wxPyTMutex == NULL) { // Python is shutting down, assume a single thread...
+        gs_shutdownTState = tstate;
+        return;
+    }
     unsigned long ctid = wxPyGetCurrentThreadId();
     wxPyTMutex->Lock();
     for(size_t i=0; i < wxPyTStates->GetCount(); i++) {
@@ -528,6 +538,291 @@ void wxPyEndBlockThreads() {
 
 
 //---------------------------------------------------------------------------
+// wxPyInputStream and wxPyCBInputStream methods
+
+#include <wx/listimpl.cpp>
+WX_DEFINE_LIST(wxStringPtrList);
+
+
+void wxPyInputStream::close() {
+    /* do nothing */
+}
+
+void wxPyInputStream::flush() {
+    /* do nothing */
+}
+
+bool wxPyInputStream::eof() {
+    if (m_wxis)
+        return m_wxis->Eof();
+    else
+        return TRUE;
+}
+
+wxPyInputStream::~wxPyInputStream() {
+    /* do nothing */
+}
+
+wxString* wxPyInputStream::read(int size) {
+    wxString* s = NULL;
+    const int BUFSIZE = 1024;
+
+    // check if we have a real wxInputStream to work with
+    if (!m_wxis) {
+        PyErr_SetString(PyExc_IOError, "no valid C-wxInputStream");
+        return NULL;
+    }
+
+    if (size < 0) {
+        // init buffers
+        char * buf = new char[BUFSIZE];
+        if (!buf) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+
+        s = new wxString();
+        if (!s) {
+            delete buf;
+            PyErr_NoMemory();
+            return NULL;
+        }
+
+        // read until EOF
+        while (! m_wxis->Eof()) {
+            m_wxis->Read(buf, BUFSIZE);
+            s->Append(buf, m_wxis->LastRead());
+        }
+        delete buf;
+
+        // error check
+        if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
+            delete s;
+            PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
+            return NULL;
+        }
+
+    } else {  // Read only size number of characters
+        s = new wxString;
+        if (!s) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+
+        // read size bytes
+        m_wxis->Read(s->GetWriteBuf(size+1), size);
+        s->UngetWriteBuf(m_wxis->LastRead());
+
+        // error check
+        if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
+            delete s;
+            PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
+            return NULL;
+        }
+    }
+    return s;
+}
+
+
+wxString* wxPyInputStream::readline (int size) {
+    // check if we have a real wxInputStream to work with
+    if (!m_wxis) {
+        PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream");
+        return NULL;
+    }
+
+    // init buffer
+    int i;
+    char ch;
+    wxString* s = new wxString;
+    if (!s) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    // read until \n or byte limit reached
+    for (i=ch=0; (ch != '\n') && (!m_wxis->Eof()) && ((size < 0) || (i < size)); i++) {
+        *s += ch = m_wxis->GetC();
+    }
+
+    // errorcheck
+    if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
+        delete s;
+        PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
+        return NULL;
+    }
+    return s;
+}
+
+
+wxStringPtrList* wxPyInputStream::readlines (int sizehint) {
+    // check if we have a real wxInputStream to work with
+    if (!m_wxis) {
+        PyErr_SetString(PyExc_IOError,"no valid C-wxInputStream below");
+        return NULL;
+    }
+
+    // init list
+    wxStringPtrList* l = new wxStringPtrList();
+    if (!l) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    // read sizehint bytes or until EOF
+    int i;
+    for (i=0; (!m_wxis->Eof()) && ((sizehint < 0) || (i < sizehint));) {
+        wxString* s = readline();
+        if (s == NULL) {
+            l->DeleteContents(TRUE);
+            l->Clear();
+            return NULL;
+        }
+        l->Append(s);
+        i = i + s->Length();
+    }
+
+    // error check
+    if (m_wxis->LastError() == wxSTREAM_READ_ERROR) {
+        l->DeleteContents(TRUE);
+        l->Clear();
+        PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
+        return NULL;
+    }
+    return l;
+}
+
+
+void wxPyInputStream::seek(int offset, int whence) {
+    if (m_wxis)
+        m_wxis->SeekI(offset, wxSeekMode(whence));
+}
+
+int wxPyInputStream::tell(){
+    if (m_wxis)
+        return m_wxis->TellI();
+    else return 0;
+}
+
+
+
+
+wxPyCBInputStream::wxPyCBInputStream(PyObject *r, PyObject *s, PyObject *t, bool block)
+    : wxInputStream(), m_read(r), m_seek(s), m_tell(t), m_block(block)
+{}
+
+
+wxPyCBInputStream::~wxPyCBInputStream() {
+    if (m_block) wxPyBeginBlockThreads();
+    Py_XDECREF(m_read);
+    Py_XDECREF(m_seek);
+    Py_XDECREF(m_tell);
+    if (m_block) wxPyEndBlockThreads();
+}
+
+
+wxPyCBInputStream* wxPyCBInputStream::create(PyObject *py, bool block) {
+    if (block) wxPyBeginBlockThreads();
+
+    PyObject* read = getMethod(py, "read");
+    PyObject* seek = getMethod(py, "seek");
+    PyObject* tell = getMethod(py, "tell");
+
+    if (!read) {
+        PyErr_SetString(PyExc_TypeError, "Not a file-like object");
+        Py_XDECREF(read);
+        Py_XDECREF(seek);
+        Py_XDECREF(tell);
+        if (block) wxPyEndBlockThreads();
+        return NULL;
+    }
+
+    if (block) wxPyEndBlockThreads();
+    return new wxPyCBInputStream(read, seek, tell, block);
+}
+
+PyObject* wxPyCBInputStream::getMethod(PyObject* py, char* name) {
+    if (!PyObject_HasAttrString(py, name))
+        return NULL;
+    PyObject* o = PyObject_GetAttrString(py, name);
+    if (!PyMethod_Check(o) && !PyCFunction_Check(o)) {
+        Py_DECREF(o);
+        return NULL;
+    }
+    return o;
+}
+
+
+size_t wxPyCBInputStream::GetSize() const {
+    wxPyCBInputStream* self = (wxPyCBInputStream*)this; // cast off const
+    if (m_seek && m_tell) {
+        off_t temp = self->OnSysTell();
+        off_t ret = self->OnSysSeek(0, wxFromEnd);
+        self->OnSysSeek(temp, wxFromStart);
+        return ret;
+    }
+    else
+        return 0;
+}
+
+
+size_t wxPyCBInputStream::OnSysRead(void *buffer, size_t bufsize) {
+    if (bufsize == 0)
+        return 0;
+
+    wxPyBeginBlockThreads();
+    PyObject* arglist = Py_BuildValue("(i)", bufsize);
+    PyObject* result = PyEval_CallObject(m_read, arglist);
+    Py_DECREF(arglist);
+
+    size_t o = 0;
+    if ((result != NULL) && PyString_Check(result)) {  // TODO: unicode?
+        o = PyString_Size(result);
+        if (o == 0)
+            m_lasterror = wxSTREAM_EOF;
+        if (o > bufsize)
+            o = bufsize;
+        memcpy((char*)buffer, PyString_AsString(result), o);
+        Py_DECREF(result);
+
+    }
+    else
+        m_lasterror = wxSTREAM_READ_ERROR;
+    wxPyEndBlockThreads();
+    m_lastcount = o;
+    return o;
+}
+
+size_t wxPyCBInputStream::OnSysWrite(const void *buffer, size_t bufsize) {
+    m_lasterror = wxSTREAM_WRITE_ERROR;
+    return 0;
+}
+
+off_t wxPyCBInputStream::OnSysSeek(off_t off, wxSeekMode mode) {
+    wxPyBeginBlockThreads();
+    PyObject* arglist = Py_BuildValue("(ii)", off, mode);
+    PyObject* result = PyEval_CallObject(m_seek, arglist);
+    Py_DECREF(arglist);
+    Py_XDECREF(result);
+    wxPyEndBlockThreads();
+    return OnSysTell();
+}
+
+off_t wxPyCBInputStream::OnSysTell() const {
+    wxPyBeginBlockThreads();
+    PyObject* arglist = Py_BuildValue("()");
+    PyObject* result = PyEval_CallObject(m_tell, arglist);
+    Py_DECREF(arglist);
+    off_t o = 0;
+    if (result != NULL) {
+        o = PyInt_AsLong(result);
+        Py_DECREF(result);
+    };
+    wxPyEndBlockThreads();
+    return o;
+}
+
+//----------------------------------------------------------------------
 
 IMPLEMENT_ABSTRACT_CLASS(wxPyCallback, wxObject);
 
@@ -611,11 +906,11 @@ void wxPyCallbackHelper::setSelf(PyObject* self, PyObject* klass, int incref) {
 // Prior to Python 2.2 PyMethod_GetClass returned the class object
 // in which the method was defined.  Starting with 2.2 it returns
 // "class that asked for the method" which seems totally bogus to me
-// but apprently if fixes some obscure problem waiting to happen in
+// but apprently it fixes some obscure problem waiting to happen in
 // Python.  Since the API was not documented Guido and the gang felt
 // safe in changing it.  Needless to say that totally screwed up the
 // logic below in wxPyCallbackHelper::findCallback, hence this icky
-// code to find the class where the method is actuallt defined...
+// code to find the class where the method is actually defined...
 
 static
 PyObject* PyFindClassWithAttr(PyObject *klass, PyObject *name)
@@ -663,6 +958,7 @@ PyObject* PyFindClassWithAttr(PyObject *klass, PyObject *name)
         }
         return NULL;
     }
+    return NULL;
 }
 #endif
 
@@ -1490,6 +1786,18 @@ PyObject* wxArrayString2PyList_helper(const wxArrayString& arr) {
 }
 
 
+PyObject* wxArrayInt2PyList_helper(const wxArrayInt& arr) {
+
+    PyObject* list = PyList_New(0);
+    for (size_t i=0; i < arr.GetCount(); i++) {
+        PyObject* number = PyInt_FromLong(arr[i]);
+        PyList_Append(list, number);
+        Py_DECREF(number);
+    }
+    return list;
+}
+
+
 //----------------------------------------------------------------------
 //----------------------------------------------------------------------