Back to index

python3.2  3.2.2
Defines | Functions | Variables
memoryobject.c File Reference
#include "Python.h"

Go to the source code of this file.

Defines

#define IS_RELEASED(memobj)   (((PyMemoryViewObject *) memobj)->view.buf == NULL)
#define CHECK_RELEASED(memobj)
#define CHECK_RELEASED_INT(memobj)

Functions

static Py_ssize_t get_shape0 (Py_buffer *buf)
static void dup_buffer (Py_buffer *dest, Py_buffer *src)
static int memory_getbuf (PyMemoryViewObject *self, Py_buffer *view, int flags)
static void memory_releasebuf (PyMemoryViewObject *self, Py_buffer *view)
 PyDoc_STRVAR (memory_doc,"memoryview(object)\n\ \n\ Create a new memoryview object which references the given object.")
PyObjectPyMemoryView_FromBuffer (Py_buffer *info)
PyObjectPyMemoryView_FromObject (PyObject *base)
static PyObjectmemory_new (PyTypeObject *subtype, PyObject *args, PyObject *kwds)
static void _strided_copy_nd (char *dest, char *src, int nd, Py_ssize_t *shape, Py_ssize_t *strides, Py_ssize_t itemsize, char fort)
static int _indirect_copy_nd (char *dest, Py_buffer *view, char fort)
PyObjectPyMemoryView_GetContiguous (PyObject *obj, int buffertype, char fort)
static PyObjectmemory_format_get (PyMemoryViewObject *self)
static PyObjectmemory_itemsize_get (PyMemoryViewObject *self)
static PyObject_IntTupleFromSsizet (int len, Py_ssize_t *vals)
static PyObjectmemory_shape_get (PyMemoryViewObject *self)
static PyObjectmemory_strides_get (PyMemoryViewObject *self)
static PyObjectmemory_suboffsets_get (PyMemoryViewObject *self)
static PyObjectmemory_readonly_get (PyMemoryViewObject *self)
static PyObjectmemory_ndim_get (PyMemoryViewObject *self)
static PyObjectmemory_tobytes (PyMemoryViewObject *mem, PyObject *noargs)
static PyObjectmemory_tolist (PyMemoryViewObject *mem, PyObject *noargs)
static void do_release (PyMemoryViewObject *self)
static PyObjectmemory_enter (PyObject *self, PyObject *args)
static PyObjectmemory_exit (PyObject *self, PyObject *args)
static void memory_dealloc (PyMemoryViewObject *self)
static PyObjectmemory_repr (PyMemoryViewObject *self)
static Py_ssize_t memory_length (PyMemoryViewObject *self)
static PyObjectmemory_item (PyMemoryViewObject *self, Py_ssize_t result)
static PyObjectmemory_subscript (PyMemoryViewObject *self, PyObject *key)
static int memory_ass_sub (PyMemoryViewObject *self, PyObject *key, PyObject *value)
static PyObjectmemory_richcompare (PyObject *v, PyObject *w, int op)
static int memory_traverse (PyMemoryViewObject *self, visitproc visit, void *arg)
static int memory_clear (PyMemoryViewObject *self)

Variables

static PyGetSetDef memory_getsetlist []
static PyMethodDef memory_methods []
static PyMappingMethods memory_as_mapping
static PySequenceMethods memory_as_sequence
static PyBufferProcs memory_as_buffer
PyTypeObject PyMemoryView_Type

Define Documentation

#define CHECK_RELEASED (   memobj)
Value:
if (IS_RELEASED(memobj)) { \
        PyErr_SetString(PyExc_ValueError, \
                        "operation forbidden on released memoryview object"); \
        return NULL; \
    }

Definition at line 9 of file memoryobject.c.

#define CHECK_RELEASED_INT (   memobj)
Value:
if (IS_RELEASED(memobj)) { \
        PyErr_SetString(PyExc_ValueError, \
                        "operation forbidden on released memoryview object"); \
        return -1; \
    }

Definition at line 16 of file memoryobject.c.

#define IS_RELEASED (   memobj)    (((PyMemoryViewObject *) memobj)->view.buf == NULL)

Definition at line 6 of file memoryobject.c.


Function Documentation

static int _indirect_copy_nd ( char *  dest,
Py_buffer view,
char  fort 
) [static]

Definition at line 193 of file memoryobject.c.

{
    Py_ssize_t *indices;
    int k;
    Py_ssize_t elements;
    char *ptr;
    void (*func)(int, Py_ssize_t *, const Py_ssize_t *);

    if (view->ndim > PY_SSIZE_T_MAX / sizeof(Py_ssize_t)) {
        PyErr_NoMemory();
        return -1;
    }

    indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view->ndim);
    if (indices == NULL) {
        PyErr_NoMemory();
        return -1;
    }
    for (k=0; k<view->ndim;k++) {
        indices[k] = 0;
    }

    elements = 1;
    for (k=0; k<view->ndim; k++) {
        elements *= view->shape[k];
    }
    if (fort == 'F') {
        func = _Py_add_one_to_index_F;
    }
    else {
        func = _Py_add_one_to_index_C;
    }
    while (elements--) {
        func(view->ndim, indices, view->shape);
        ptr = PyBuffer_GetPointer(view, indices);
        memcpy(dest, ptr, view->itemsize);
        dest += view->itemsize;
    }

    PyMem_Free(indices);
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* _IntTupleFromSsizet ( int  len,
Py_ssize_t vals 
) [static]

Definition at line 346 of file memoryobject.c.

{
    int i;
    PyObject *o;
    PyObject *intTuple;

    if (vals == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    intTuple = PyTuple_New(len);
    if (!intTuple)
        return NULL;
    for (i=0; i<len; i++) {
        o = PyLong_FromSsize_t(vals[i]);
        if (!o) {
            Py_DECREF(intTuple);
            return NULL;
        }
        PyTuple_SET_ITEM(intTuple, i, o);
    }
    return intTuple;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void _strided_copy_nd ( char *  dest,
char *  src,
int  nd,
Py_ssize_t shape,
Py_ssize_t strides,
Py_ssize_t  itemsize,
char  fort 
) [static]

Definition at line 135 of file memoryobject.c.

{
    int k;
    Py_ssize_t outstride;

    if (nd==0) {
        memcpy(dest, src, itemsize);
    }
    else if (nd == 1) {
        for (k = 0; k<shape[0]; k++) {
            memcpy(dest, src, itemsize);
            dest += itemsize;
            src += strides[0];
        }
    }
    else {
        if (fort == 'F') {
            /* Copy first dimension first,
               second dimension second, etc...
               Set up the recursive loop backwards so that final
               dimension is actually copied last.
            */
            outstride = itemsize;
            for (k=1; k<nd-1;k++) {
                outstride *= shape[k];
            }
            for (k=0; k<shape[nd-1]; k++) {
                _strided_copy_nd(dest, src, nd-1, shape,
                                 strides, itemsize, fort);
                dest += outstride;
                src += strides[nd-1];
            }
        }

        else {
            /* Copy last dimension first,
               second-to-last dimension second, etc.
               Set up the recursion so that the
               first dimension is copied last
            */
            outstride = itemsize;
            for (k=1; k < nd; k++) {
                outstride *= shape[k];
            }
            for (k=0; k<shape[0]; k++) {
                _strided_copy_nd(dest, src, nd-1, shape+1,
                                 strides+1, itemsize,
                                 fort);
                dest += outstride;
                src += strides[0];
            }
        }
    }
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_release ( PyMemoryViewObject self) [static]

Definition at line 464 of file memoryobject.c.

{
    if (self->view.obj != NULL) {
        PyBuffer_Release(&(self->view));
    }
    self->view.obj = NULL;
    self->view.buf = NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void dup_buffer ( Py_buffer dest,
Py_buffer src 
) [static]

Definition at line 37 of file memoryobject.c.

{
    *dest = *src;
    if (src->ndim == 1 && src->shape != NULL) {
        dest->shape = &(dest->smalltable[0]);
        dest->shape[0] = get_shape0(src);
    }
    if (src->ndim == 1 && src->strides != NULL) {
        dest->strides = &(dest->smalltable[1]);
        dest->strides[0] = src->strides[0];
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Py_ssize_t get_shape0 ( Py_buffer buf) [static]

Definition at line 24 of file memoryobject.c.

{
    if (buf->shape != NULL)
        return buf->shape[0];
    if (buf->ndim == 0)
        return 1;
    PyErr_SetString(PyExc_TypeError,
        "exported buffer does not have any shape information associated "
        "to it");
    return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int memory_ass_sub ( PyMemoryViewObject self,
PyObject key,
PyObject value 
) [static]

Definition at line 644 of file memoryobject.c.

{
    Py_ssize_t start, len, bytelen;
    Py_buffer srcview;
    Py_buffer *view = &(self->view);
    char *srcbuf, *destbuf;

    CHECK_RELEASED_INT(self);
    if (view->readonly) {
        PyErr_SetString(PyExc_TypeError,
            "cannot modify read-only memory");
        return -1;
    }
    if (value == NULL) {
        PyErr_SetString(PyExc_TypeError,
                        "cannot delete memory");
        return -1;
    }
    if (view->ndim != 1) {
        PyErr_SetNone(PyExc_NotImplementedError);
        return -1;
    }
    if (PyIndex_Check(key)) {
        start = PyNumber_AsSsize_t(key, NULL);
        if (start == -1 && PyErr_Occurred())
            return -1;
        if (start < 0) {
            start += get_shape0(view);
        }
        if ((start < 0) || (start >= get_shape0(view))) {
            PyErr_SetString(PyExc_IndexError,
                            "index out of bounds");
            return -1;
        }
        len = 1;
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t stop, step;

        if (PySlice_GetIndicesEx(key, get_shape0(view),
                         &start, &stop, &step, &len) < 0) {
            return -1;
        }
        if (step != 1) {
            PyErr_SetNone(PyExc_NotImplementedError);
            return -1;
        }
    }
    else {
        PyErr_Format(PyExc_TypeError,
            "cannot index memory using \"%.200s\"", 
            key->ob_type->tp_name);
        return -1;
    }
    if (PyObject_GetBuffer(value, &srcview, PyBUF_CONTIG_RO) == -1) {
        return -1;
    }
    /* XXX should we allow assignment of different item sizes
       as long as the byte length is the same?
       (e.g. assign 2 shorts to a 4-byte slice) */
    if (srcview.itemsize != view->itemsize) {
        PyErr_Format(PyExc_TypeError,
            "mismatching item sizes for \"%.200s\" and \"%.200s\"", 
            view->obj->ob_type->tp_name, srcview.obj->ob_type->tp_name);
        goto _error;
    }
    bytelen = len * view->itemsize;
    if (bytelen != srcview.len) {
        PyErr_SetString(PyExc_ValueError,
            "cannot modify size of memoryview object");
        goto _error;
    }
    /* Do the actual copy */
    destbuf = (char *) view->buf + start * view->itemsize;
    srcbuf = (char *) srcview.buf;
    if (destbuf + bytelen < srcbuf || srcbuf + bytelen < destbuf)
        /* No overlapping */
        memcpy(destbuf, srcbuf, bytelen);
    else
        memmove(destbuf, srcbuf, bytelen);

    PyBuffer_Release(&srcview);
    return 0;

_error:
    PyBuffer_Release(&srcview);
    return -1;
}

Here is the call graph for this function:

static int memory_clear ( PyMemoryViewObject self) [static]

Definition at line 790 of file memoryobject.c.

{
    PyBuffer_Release(&self->view);
    return 0;
}

Here is the call graph for this function:

static void memory_dealloc ( PyMemoryViewObject self) [static]

Definition at line 499 of file memoryobject.c.

Here is the call graph for this function:

static PyObject* memory_enter ( PyObject self,
PyObject args 
) [static]

Definition at line 474 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    Py_INCREF(self);
    return self;
}
static PyObject* memory_exit ( PyObject self,
PyObject args 
) [static]

Definition at line 482 of file memoryobject.c.

Here is the call graph for this function:

static PyObject* memory_format_get ( PyMemoryViewObject self) [static]

Definition at line 332 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return PyUnicode_FromString(self->view.format);
}

Here is the call graph for this function:

static int memory_getbuf ( PyMemoryViewObject self,
Py_buffer view,
int  flags 
) [static]

Definition at line 51 of file memoryobject.c.

{
    int res = 0;
    CHECK_RELEASED_INT(self);
    if (self->view.obj != NULL)
        res = PyObject_GetBuffer(self->view.obj, view, flags);
    if (view)
        dup_buffer(view, &self->view);
    return res;
}

Here is the call graph for this function:

static PyObject* memory_item ( PyMemoryViewObject self,
Py_ssize_t  result 
) [static]

Definition at line 527 of file memoryobject.c.

{
    Py_buffer *view = &(self->view);

    CHECK_RELEASED(self);
    if (view->ndim == 0) {
        PyErr_SetString(PyExc_IndexError,
                        "invalid indexing of 0-dim memory");
        return NULL;
    }
    if (view->ndim == 1) {
        /* Return a bytes object */
        char *ptr;
        ptr = (char *)view->buf;
        if (result < 0) {
            result += get_shape0(view);
        }
        if ((result < 0) || (result >= get_shape0(view))) {
            PyErr_SetString(PyExc_IndexError,
                                "index out of bounds");
            return NULL;
        }
        if (view->strides == NULL)
            ptr += view->itemsize * result;
        else
            ptr += view->strides[0] * result;
        if (view->suboffsets != NULL &&
            view->suboffsets[0] >= 0) {
            ptr = *((char **)ptr) + view->suboffsets[0];
        }
        return PyBytes_FromStringAndSize(ptr, view->itemsize);
    } else {
        /* Return a new memory-view object */
        Py_buffer newview;
        memset(&newview, 0, sizeof(newview));
        /* XXX:  This needs to be fixed so it actually returns a sub-view */
        return PyMemoryView_FromBuffer(&newview);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* memory_itemsize_get ( PyMemoryViewObject self) [static]

Definition at line 339 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return PyLong_FromSsize_t(self->view.itemsize);
}
static Py_ssize_t memory_length ( PyMemoryViewObject self) [static]

Definition at line 517 of file memoryobject.c.

{
    CHECK_RELEASED_INT(self);
    return get_shape0(&self->view);
}

Here is the call graph for this function:

static PyObject* memory_ndim_get ( PyMemoryViewObject self) [static]

Definition at line 399 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return PyLong_FromLong(self->view.ndim);
}

Here is the call graph for this function:

static PyObject* memory_new ( PyTypeObject subtype,
PyObject args,
PyObject kwds 
) [static]

Definition at line 120 of file memoryobject.c.

{
    PyObject *obj;
    static char *kwlist[] = {"object", 0};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:memoryview", kwlist,
                                     &obj)) {
        return NULL;
    }

    return PyMemoryView_FromObject(obj);
}

Here is the call graph for this function:

static PyObject* memory_readonly_get ( PyMemoryViewObject self) [static]

Definition at line 392 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return PyBool_FromLong(self->view.readonly);
}

Here is the call graph for this function:

static void memory_releasebuf ( PyMemoryViewObject self,
Py_buffer view 
) [static]

Definition at line 63 of file memoryobject.c.

{
    PyBuffer_Release(view);
}

Here is the call graph for this function:

static PyObject* memory_repr ( PyMemoryViewObject self) [static]

Definition at line 507 of file memoryobject.c.

{
    if (IS_RELEASED(self))
        return PyUnicode_FromFormat("<released memory at %p>", self);
    else
        return PyUnicode_FromFormat("<memory at %p>", self);
}
static PyObject* memory_richcompare ( PyObject v,
PyObject w,
int  op 
) [static]

Definition at line 734 of file memoryobject.c.

{
    Py_buffer vv, ww;
    int equal = 0;
    PyObject *res;

    vv.obj = NULL;
    ww.obj = NULL;
    if (op != Py_EQ && op != Py_NE)
        goto _notimpl;
    if ((PyMemoryView_Check(v) && IS_RELEASED(v)) ||
        (PyMemoryView_Check(w) && IS_RELEASED(w))) {
        equal = (v == w);
        goto _end;
    }
    if (PyObject_GetBuffer(v, &vv, PyBUF_CONTIG_RO) == -1) {
        PyErr_Clear();
        goto _notimpl;
    }
    if (PyObject_GetBuffer(w, &ww, PyBUF_CONTIG_RO) == -1) {
        PyErr_Clear();
        goto _notimpl;
    }

    if (vv.itemsize != ww.itemsize || vv.len != ww.len)
        goto _end;

    equal = !memcmp(vv.buf, ww.buf, vv.len);

_end:
    PyBuffer_Release(&vv);
    PyBuffer_Release(&ww);
    if ((equal && op == Py_EQ) || (!equal && op == Py_NE))
        res = Py_True;
    else
        res = Py_False;
    Py_INCREF(res);
    return res;

_notimpl:
    PyBuffer_Release(&vv);
    PyBuffer_Release(&ww);
    Py_INCREF(Py_NotImplemented);
    return Py_NotImplemented;
}

Here is the call graph for this function:

static PyObject* memory_shape_get ( PyMemoryViewObject self) [static]

Definition at line 371 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return _IntTupleFromSsizet(self->view.ndim, self->view.shape);
}

Here is the call graph for this function:

static PyObject* memory_strides_get ( PyMemoryViewObject self) [static]

Definition at line 378 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return _IntTupleFromSsizet(self->view.ndim, self->view.strides);
}

Here is the call graph for this function:

static PyObject* memory_suboffsets_get ( PyMemoryViewObject self) [static]

Definition at line 385 of file memoryobject.c.

{
    CHECK_RELEASED(self);
    return _IntTupleFromSsizet(self->view.ndim, self->view.suboffsets);
}

Here is the call graph for this function:

static PyObject* memory_subscript ( PyMemoryViewObject self,
PyObject key 
) [static]

Definition at line 576 of file memoryobject.c.

{
    Py_buffer *view;
    view = &(self->view);
    
    CHECK_RELEASED(self);
    if (view->ndim == 0) {
        if (key == Py_Ellipsis ||
            (PyTuple_Check(key) && PyTuple_GET_SIZE(key)==0)) {
            Py_INCREF(self);
            return (PyObject *)self;
        }
        else {
            PyErr_SetString(PyExc_IndexError,
                                "invalid indexing of 0-dim memory");
            return NULL;
        }
    }
    if (PyIndex_Check(key)) {
        Py_ssize_t result;
        result = PyNumber_AsSsize_t(key, NULL);
        if (result == -1 && PyErr_Occurred())
                return NULL;
        return memory_item(self, result);
    }
    else if (PySlice_Check(key)) {
        Py_ssize_t start, stop, step, slicelength;

        if (PySlice_GetIndicesEx(key, get_shape0(view),
                                 &start, &stop, &step, &slicelength) < 0) {
            return NULL;
        }
    
        if (step == 1 && view->ndim == 1) {
            Py_buffer newview;
            void *newbuf = (char *) view->buf
                                    + start * view->itemsize;
            int newflags = view->readonly
                    ? PyBUF_CONTIG_RO : PyBUF_CONTIG;
    
            /* XXX There should be an API to create a subbuffer */
            if (view->obj != NULL) {
                if (PyObject_GetBuffer(view->obj, &newview, newflags) == -1)
                    return NULL;
            }
            else {
                newview = *view;
            }
            newview.buf = newbuf;
            newview.len = slicelength * newview.itemsize;
            newview.format = view->format;
            newview.shape = &(newview.smalltable[0]);
            newview.shape[0] = slicelength;
            newview.strides = &(newview.itemsize);
            return PyMemoryView_FromBuffer(&newview);
        }
        PyErr_SetNone(PyExc_NotImplementedError);
        return NULL;
    }
    PyErr_Format(PyExc_TypeError,
        "cannot index memory using \"%.200s\"", 
        key->ob_type->tp_name);
    return NULL;
}

Here is the call graph for this function:

static PyObject* memory_tobytes ( PyMemoryViewObject mem,
PyObject noargs 
) [static]

Definition at line 418 of file memoryobject.c.

Here is the call graph for this function:

static PyObject* memory_tolist ( PyMemoryViewObject mem,
PyObject noargs 
) [static]

Definition at line 429 of file memoryobject.c.

{
    Py_buffer *view = &(mem->view);
    Py_ssize_t i;
    PyObject *res, *item;
    char *buf;

    CHECK_RELEASED(mem);
    if (strcmp(view->format, "B") || view->itemsize != 1) {
        PyErr_SetString(PyExc_NotImplementedError, 
                "tolist() only supports byte views");
        return NULL;
    }
    if (view->ndim != 1) {
        PyErr_SetString(PyExc_NotImplementedError, 
                "tolist() only supports one-dimensional objects");
        return NULL;
    }
    res = PyList_New(view->len);
    if (res == NULL)
        return NULL;
    buf = view->buf;
    for (i = 0; i < view->len; i++) {
        item = PyLong_FromUnsignedLong((unsigned char) *buf);
        if (item == NULL) {
            Py_DECREF(res);
            return NULL;
        }
        PyList_SET_ITEM(res, i, item);
        buf++;
    }
    return res;
}

Here is the call graph for this function:

static int memory_traverse ( PyMemoryViewObject self,
visitproc  visit,
void arg 
) [static]

Definition at line 782 of file memoryobject.c.

{
    if (self->view.obj != NULL)
        Py_VISIT(self->view.obj);
    return 0;
}
PyDoc_STRVAR ( memory_doc  ,
"memoryview(object)\n\\n\Create a new memoryview object which references the given object."   
)

Definition at line 74 of file memoryobject.c.

{
    PyMemoryViewObject *mview;

    if (info->buf == NULL) {
        PyErr_SetString(PyExc_ValueError,
            "cannot make memory view from a buffer with a NULL data pointer");
        return NULL;
    }
    mview = (PyMemoryViewObject *)
        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
    if (mview == NULL)
        return NULL;
    dup_buffer(&mview->view, info);
    /* NOTE: mview->view.obj should already have been incref'ed as
       part of PyBuffer_FillInfo(). */
    _PyObject_GC_TRACK(mview);
    return (PyObject *)mview;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 95 of file memoryobject.c.

{
    PyMemoryViewObject *mview;
    Py_buffer view;

    if (!PyObject_CheckBuffer(base)) {
        PyErr_SetString(PyExc_TypeError,
            "cannot make memory view because object does "
            "not have the buffer interface");
        return NULL;
    }

    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
        return NULL;

    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
    if (mview == NULL) {
        PyBuffer_Release(&view);
        return NULL;
    }

    return (PyObject *)mview;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PyObject* PyMemoryView_GetContiguous ( PyObject obj,
int  buffertype,
char  fort 
)

Definition at line 260 of file memoryobject.c.

{
    PyMemoryViewObject *mem;
    PyObject *bytes;
    Py_buffer *view;
    int flags;
    char *dest;

    if (!PyObject_CheckBuffer(obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "object does not support the buffer interface");
        return NULL;
    }

    mem = PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
    if (mem == NULL)
        return NULL;

    view = &mem->view;
    flags = PyBUF_FULL_RO;
    switch(buffertype) {
    case PyBUF_WRITE:
        flags = PyBUF_FULL;
        break;
    }

    if (PyObject_GetBuffer(obj, view, flags) != 0) {
        Py_DECREF(mem);
        return NULL;
    }

    if (PyBuffer_IsContiguous(view, fort)) {
        /* no copy needed */
        _PyObject_GC_TRACK(mem);
        return (PyObject *)mem;
    }
    /* otherwise a copy is needed */
    if (buffertype == PyBUF_WRITE) {
        Py_DECREF(mem);
        PyErr_SetString(PyExc_BufferError,
                        "writable contiguous buffer requested "
                        "for a non-contiguousobject.");
        return NULL;
    }
    bytes = PyBytes_FromStringAndSize(NULL, view->len);
    if (bytes == NULL) {
        Py_DECREF(mem);
        return NULL;
    }
    dest = PyBytes_AS_STRING(bytes);
    /* different copying strategy depending on whether
       or not any pointer de-referencing is needed
    */
    /* strided or in-direct copy */
    if (view->suboffsets==NULL) {
        _strided_copy_nd(dest, view->buf, view->ndim, view->shape,
                         view->strides, view->itemsize, fort);
    }
    else {
        if (_indirect_copy_nd(dest, view, fort) < 0) {
            Py_DECREF(bytes);
            Py_DECREF(mem);
            return NULL;
        }
        PyBuffer_Release(view);  /* XXX ? */
    }
    _PyObject_GC_TRACK(mem);
    return (PyObject *)mem;
}

Here is the call graph for this function:


Variable Documentation

Initial value:

Definition at line 813 of file memoryobject.c.

Initial value:

Definition at line 798 of file memoryobject.c.

Initial value:
 {
        0,                                  
        0,                                  
        0,                                  
        (ssizeargfunc)memory_item,          
}

Definition at line 804 of file memoryobject.c.

Initial value:
{
    {"format",                (getter)memory_format_get,      NULL, NULL},
    {"itemsize",        (getter)memory_itemsize_get,    NULL, NULL},
    {"shape",           (getter)memory_shape_get,       NULL, NULL},
    {"strides",         (getter)memory_strides_get,     NULL, NULL},
    {"suboffsets",      (getter)memory_suboffsets_get,  NULL, NULL},
    {"readonly",        (getter)memory_readonly_get,    NULL, NULL},
    {"ndim",            (getter)memory_ndim_get,        NULL, NULL},
    {NULL, NULL, NULL, NULL},
}

Definition at line 405 of file memoryobject.c.

Initial value:
 {
    {"release", memory_exit, METH_NOARGS},
    {"tobytes", (PyCFunction)memory_tobytes, METH_NOARGS, NULL},
    {"tolist", (PyCFunction)memory_tolist, METH_NOARGS, NULL},
    {"__enter__", memory_enter, METH_NOARGS},
    {"__exit__", memory_exit, METH_VARARGS},
    {NULL,          NULL}           
}

Definition at line 488 of file memoryobject.c.

Definition at line 819 of file memoryobject.c.