Example #1
0
File: core.c Project: fried/pyaio
static int _async_callback(void *arg)
{
    Pyaio_cb *aio = (Pyaio_cb *)arg;
    struct aiocb *cb;
    PyObject *callback, *args, *result, *buffer;
    Py_buffer *buffer_view;

    cb = aio->cb;
    callback = aio->callback;
    buffer_view = &(aio->buffer_view);
    buffer = aio->buffer; /* Should have ref count of +2 */

    PyBuffer_Release(buffer_view); /* -1 refcount we are done with it */

    if (aio->read) {
        if (aio_return(cb) > 0) {
            if (aio_return(cb) < cb->aio_nbytes) {
                PyByteArray_Resize(buffer, aio_return(cb));
            }
        }
        else {
            PyByteArray_Resize(buffer, 0);
        }
        args = Py_BuildValue("(Oni)", buffer, aio_return(cb), aio_error(cb));
    }
    else { /* WRITE */
        args = Py_BuildValue("(ni)", aio_return(cb), aio_error(cb));
    }
    result = PyObject_CallObject(callback, args);
    if (result == NULL) {
        printf("Exception in aio callback, dying!\n");
        kill(getpid(), SIGKILL);  // DIE FAST
    }
    Py_XDECREF(buffer); /* -1 refcount. we should be at 0 now */
    Py_XDECREF(result);
    Py_XDECREF(callback);
    Py_XDECREF(args);
    free((struct aiocb *)cb);
    free(aio);
    return 0;
}
Example #2
0
static PyObject *
iobase_readline(PyObject *self, PyObject *args)
{
    /* For backwards compatibility, a (slowish) readline(). */

    Py_ssize_t limit = -1;
    int has_peek = 0;
    PyObject *buffer, *result;
    Py_ssize_t old_size = -1;

    if (!PyArg_ParseTuple(args, "|O&:readline", &_PyIO_ConvertSsize_t, &limit)) {
        return NULL;
    }

    if (PyObject_HasAttrString(self, "peek"))
        has_peek = 1;

    buffer = PyByteArray_FromStringAndSize(NULL, 0);
    if (buffer == NULL)
        return NULL;

    while (limit < 0 || Py_SIZE(buffer) < limit) {
        Py_ssize_t nreadahead = 1;
        PyObject *b;

        if (has_peek) {
            PyObject *readahead = PyObject_CallMethod(self, "peek", "i", 1);
            if (readahead == NULL)
                goto fail;
            if (!PyBytes_Check(readahead)) {
                PyErr_Format(PyExc_IOError,
                             "peek() should have returned a bytes object, "
                             "not '%.200s'", Py_TYPE(readahead)->tp_name);
                Py_DECREF(readahead);
                goto fail;
            }
            if (PyBytes_GET_SIZE(readahead) > 0) {
                Py_ssize_t n = 0;
                const char *buf = PyBytes_AS_STRING(readahead);
                if (limit >= 0) {
                    do {
                        if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
                            break;
                        if (buf[n++] == '\n')
                            break;
                    } while (1);
                }
                else {
                    do {
                        if (n >= PyBytes_GET_SIZE(readahead))
                            break;
                        if (buf[n++] == '\n')
                            break;
                    } while (1);
                }
                nreadahead = n;
            }
            Py_DECREF(readahead);
        }

        b = PyObject_CallMethod(self, "read", "n", nreadahead);
        if (b == NULL)
            goto fail;
        if (!PyBytes_Check(b)) {
            PyErr_Format(PyExc_IOError,
                         "read() should have returned a bytes object, "
                         "not '%.200s'", Py_TYPE(b)->tp_name);
            Py_DECREF(b);
            goto fail;
        }
        if (PyBytes_GET_SIZE(b) == 0) {
            Py_DECREF(b);
            break;
        }

        old_size = PyByteArray_GET_SIZE(buffer);
        PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b));
        memcpy(PyByteArray_AS_STRING(buffer) + old_size,
               PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));

        Py_DECREF(b);

        if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
            break;
    }

    result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
                                       PyByteArray_GET_SIZE(buffer));
    Py_DECREF(buffer);
    return result;
  fail:
    Py_DECREF(buffer);
    return NULL;
}
Example #3
0
static PyObject *
_io__IOBase_readline_impl(PyObject *self, Py_ssize_t limit)
/*[clinic end generated code: output=4479f79b58187840 input=d0c596794e877bff]*/
{
    /* For backwards compatibility, a (slowish) readline(). */

    PyObject *peek, *buffer, *result;
    Py_ssize_t old_size = -1;

    if (_PyObject_LookupAttr(self, _PyIO_str_peek, &peek) < 0) {
        return NULL;
    }

    buffer = PyByteArray_FromStringAndSize(NULL, 0);
    if (buffer == NULL) {
        Py_XDECREF(peek);
        return NULL;
    }

    while (limit < 0 || PyByteArray_GET_SIZE(buffer) < limit) {
        Py_ssize_t nreadahead = 1;
        PyObject *b;

        if (peek != NULL) {
            PyObject *readahead = PyObject_CallFunctionObjArgs(peek, _PyLong_One, NULL);
            if (readahead == NULL) {
                /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
                   when EINTR occurs so we needn't do it ourselves. */
                if (_PyIO_trap_eintr()) {
                    continue;
                }
                goto fail;
            }
            if (!PyBytes_Check(readahead)) {
                PyErr_Format(PyExc_OSError,
                             "peek() should have returned a bytes object, "
                             "not '%.200s'", Py_TYPE(readahead)->tp_name);
                Py_DECREF(readahead);
                goto fail;
            }
            if (PyBytes_GET_SIZE(readahead) > 0) {
                Py_ssize_t n = 0;
                const char *buf = PyBytes_AS_STRING(readahead);
                if (limit >= 0) {
                    do {
                        if (n >= PyBytes_GET_SIZE(readahead) || n >= limit)
                            break;
                        if (buf[n++] == '\n')
                            break;
                    } while (1);
                }
                else {
                    do {
                        if (n >= PyBytes_GET_SIZE(readahead))
                            break;
                        if (buf[n++] == '\n')
                            break;
                    } while (1);
                }
                nreadahead = n;
            }
            Py_DECREF(readahead);
        }

        b = _PyObject_CallMethodId(self, &PyId_read, "n", nreadahead);
        if (b == NULL) {
            /* NOTE: PyErr_SetFromErrno() calls PyErr_CheckSignals()
               when EINTR occurs so we needn't do it ourselves. */
            if (_PyIO_trap_eintr()) {
                continue;
            }
            goto fail;
        }
        if (!PyBytes_Check(b)) {
            PyErr_Format(PyExc_OSError,
                         "read() should have returned a bytes object, "
                         "not '%.200s'", Py_TYPE(b)->tp_name);
            Py_DECREF(b);
            goto fail;
        }
        if (PyBytes_GET_SIZE(b) == 0) {
            Py_DECREF(b);
            break;
        }

        old_size = PyByteArray_GET_SIZE(buffer);
        if (PyByteArray_Resize(buffer, old_size + PyBytes_GET_SIZE(b)) < 0) {
            Py_DECREF(b);
            goto fail;
        }
        memcpy(PyByteArray_AS_STRING(buffer) + old_size,
               PyBytes_AS_STRING(b), PyBytes_GET_SIZE(b));

        Py_DECREF(b);

        if (PyByteArray_AS_STRING(buffer)[PyByteArray_GET_SIZE(buffer) - 1] == '\n')
            break;
    }

    result = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(buffer),
                                       PyByteArray_GET_SIZE(buffer));
    Py_XDECREF(peek);
    Py_DECREF(buffer);
    return result;
  fail:
    Py_XDECREF(peek);
    Py_DECREF(buffer);
    return NULL;
}
Example #4
0
    PyObject* DetachValue()
    {
        // At this point, Trim should have been called by PostRead.

        if (bytesUsed == SQL_NULL_DATA || buffer == 0)
            Py_RETURN_NONE;

        if (usingStack)
        {
            if (dataType == SQL_C_CHAR)
                return PyBytes_FromStringAndSize(buffer, bytesUsed);

            if (dataType == SQL_C_BINARY)
            {
#if PY_VERSION_HEX >= 0x02060000
                return PyByteArray_FromStringAndSize(buffer, bytesUsed);
#else
                return PyBytes_FromStringAndSize(buffer, bytesUsed);
#endif
            }

            if (sizeof(SQLWCHAR) == Py_UNICODE_SIZE)
                return PyUnicode_FromUnicode((const Py_UNICODE*)buffer, bytesUsed / element_size);

            return PyUnicode_FromSQLWCHAR((const SQLWCHAR*)buffer, bytesUsed / element_size);
        }

        if (bufferOwner && PyUnicode_CheckExact(bufferOwner))
        {
            if (PyUnicode_Resize(&bufferOwner, bytesUsed / element_size) == -1)
                return 0;
            PyObject* tmp = bufferOwner;
            bufferOwner = 0;
            buffer      = 0;
            return tmp;
        }

        if (bufferOwner && PyBytes_CheckExact(bufferOwner))
        {
            if (_PyBytes_Resize(&bufferOwner, bytesUsed) == -1)
                return 0;
            PyObject* tmp = bufferOwner;
            bufferOwner = 0;
            buffer      = 0;
            return tmp;
        }

#if PY_VERSION_HEX >= 0x02060000
        if (bufferOwner && PyByteArray_CheckExact(bufferOwner))
        {
            if (PyByteArray_Resize(bufferOwner, bytesUsed) == -1)
                return 0;
            PyObject* tmp = bufferOwner;
            bufferOwner = 0;
            buffer      = 0;
            return tmp;
        }
#endif

        // We have allocated our own SQLWCHAR buffer and must now copy it to a Unicode object.
        I(bufferOwner == 0);
        PyObject* result = PyUnicode_FromSQLWCHAR((const SQLWCHAR*)buffer, bytesUsed / element_size);
        if (result == 0)
            return false;
        pyodbc_free(buffer);
        buffer = 0;
        return result;
    }
Example #5
0
    bool AllocateMore(SQLLEN cbAdd)
    {
        // cbAdd
        //   The number of bytes (cb --> count of bytes) to add.

        if (cbAdd == 0)
            return true;

        SQLLEN newSize = bufferSize + cbAdd;

        if (usingStack)
        {
            // This is the first call and `buffer` points to stack memory.  Allocate a new object and copy the stack
            // data into it.

            char* stackBuffer = buffer;

            if (dataType == SQL_C_CHAR)
            {
                bufferOwner = PyBytes_FromStringAndSize(0, newSize);
                buffer      = bufferOwner ? PyBytes_AS_STRING(bufferOwner) : 0;
            }
            else if (dataType == SQL_C_BINARY)
            {
#if PY_VERSION_HEX >= 0x02060000
                bufferOwner = PyByteArray_FromStringAndSize(0, newSize);
                buffer      = bufferOwner ? PyByteArray_AS_STRING(bufferOwner) : 0;
#else
                bufferOwner = PyBytes_FromStringAndSize(0, newSize);
                buffer      = bufferOwner ? PyBytes_AS_STRING(bufferOwner) : 0;
#endif
            }
            else if (sizeof(SQLWCHAR) == Py_UNICODE_SIZE)
            {
                // Allocate directly into a Unicode object.
                bufferOwner = PyUnicode_FromUnicode(0, newSize / element_size);
                buffer      = bufferOwner ? (char*)PyUnicode_AsUnicode(bufferOwner) : 0;
            }
            else
            {
                // We're Unicode, but SQLWCHAR and Py_UNICODE don't match, so maintain our own SQLWCHAR buffer.
                bufferOwner = 0;
                buffer      = (char*)pyodbc_malloc((size_t)newSize);
            }

            if (buffer == 0)
                return false;

            usingStack = false;

            memcpy(buffer, stackBuffer, (size_t)bufferSize);
            bufferSize = newSize;
            return true;
        }

        if (bufferOwner && PyUnicode_CheckExact(bufferOwner))
        {
            if (PyUnicode_Resize(&bufferOwner, newSize / element_size) == -1)
                return false;
            buffer = (char*)PyUnicode_AsUnicode(bufferOwner);
        }
#if PY_VERSION_HEX >= 0x02060000
        else if (bufferOwner && PyByteArray_CheckExact(bufferOwner))
        {
            if (PyByteArray_Resize(bufferOwner, newSize) == -1)
                return false;
            buffer = PyByteArray_AS_STRING(bufferOwner);
        }
#else
        else if (bufferOwner && PyBytes_CheckExact(bufferOwner))
        {
            if (_PyBytes_Resize(&bufferOwner, newSize) == -1)
                return false;
            buffer = PyBytes_AS_STRING(bufferOwner);
        }
#endif
        else
        {
            char* tmp = (char*)realloc(buffer, (size_t)newSize);
            if (tmp == 0)
                return false;
            buffer = tmp;
        }

        bufferSize = newSize;

        return true;
    }