summaryrefslogtreecommitdiff
path: root/tests/buffers/userbuffer.pyx
blob: df774a07bf24a1891707fca63603d38256e052c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

__doc__ = u"""
>>> b1 = UserBuffer1()
>>> m1 = memoryview(b1)
>>> m1.tolist()
[0, 1, 2, 3, 4]
>>> del m1, b1

>>> b2 = UserBuffer2()
>>> m2 = memoryview(b2)
UserBuffer2: getbuffer
>>> m2.tolist()
[5, 6, 7, 8, 9]
>>> del m2, b2
UserBuffer2: release
"""

cdef extern from *:
    ctypedef struct Py_buffer # redeclared
    enum: PyBUF_SIMPLE
    int PyBuffer_FillInfo(Py_buffer *, object, void *, Py_ssize_t, bint, int) except -1
    int  PyObject_GetBuffer(object, Py_buffer *, int) except -1
    void PyBuffer_Release(Py_buffer *)

cdef char global_buf[5]
global_buf[0:5] = [0, 1, 2, 3, 4]

cdef class UserBuffer1:

    def __getbuffer__(self, Py_buffer* view, int flags):
        PyBuffer_FillInfo(view, None, global_buf, 5, 1, flags)

cdef class UserBuffer2:
    cdef char buf[5]

    def __cinit__(self):
        self.buf[0:5] = [5, 6, 7, 8, 9]

    def __getbuffer__(self, Py_buffer* view, int flags):
        print('UserBuffer2: getbuffer')
        PyBuffer_FillInfo(view, self, self.buf, 5, 0, flags)

    def __releasebuffer__(self, Py_buffer* view):
        print('UserBuffer2: release')


cdef extern from *:
    ctypedef struct PyBuffer"Py_buffer":
        void *buf
        Py_ssize_t len
        bint readonly

cdef class _memoryview:

    """
    Memory
    """

    cdef PyBuffer view

    def __cinit__(self, obj):
        cdef Py_buffer *view = <Py_buffer*>&self.view
        PyObject_GetBuffer(obj, view, PyBUF_SIMPLE)

    def __dealloc__(self):
        cdef Py_buffer *view = <Py_buffer*>&self.view
        PyBuffer_Release(view )
        
    def __getbuffer__(self, Py_buffer *view, int flags):
        PyBuffer_FillInfo(view, self,
                          self.view.buf, self.view.len,
                          self.view.readonly, flags)
    def tolist(self):
        cdef char *b = <char *> self.view.buf
        return [b[i] for i in range(self.view.len)]