int s_aws_input_stream_py_read()

in source/io.c [745:795]


int s_aws_input_stream_py_read(struct aws_input_stream *stream, struct aws_byte_buf *dest) {
    struct aws_input_stream_py_impl *impl = stream->impl;

    int aws_result = AWS_OP_SUCCESS;
    PyObject *memory_view = NULL;
    PyObject *method_result = NULL;

    /*************** GIL ACQUIRE ***************/
    PyGILState_STATE state;
    if (aws_py_gilstate_ensure(&state)) {
        return AWS_OP_ERR; /* Python has shut down. Nothing matters anymore, but don't crash */
    }

    memory_view = aws_py_memory_view_from_byte_buffer(dest);
    if (!memory_view) {
        aws_result = aws_py_raise_error();
        goto done;
    }

    method_result = PyObject_CallMethod(impl->self_proxy, "_read_into_memoryview", "(O)", memory_view);
    if (!method_result) {
        aws_result = aws_py_raise_error();
        goto done;
    }

    /* Return the number of bytes read. If the object is in non-blocking mode
     * and no bytes are available, None is returned */
    Py_ssize_t bytes_read = 0;
    if (method_result != Py_None) {
        bytes_read = PyLong_AsSsize_t(method_result);
        if (bytes_read == -1 && PyErr_Occurred()) {
            aws_result = aws_py_raise_error();
            goto done;
        }
        AWS_FATAL_ASSERT(bytes_read >= 0);

        if (bytes_read == 0) {
            impl->is_end_of_stream = true;
        } else {
            dest->len += bytes_read;
        }
    }

done:
    Py_XDECREF(memory_view);
    Py_XDECREF(method_result);
    PyGILState_Release(state);
    /*************** GIL RELEASE ***************/

    return aws_result;
}