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
|
import ctypes
from ctypes import (byref, POINTER, pythonapi,
c_int, c_char, c_char_p, c_void_p, py_object, c_ssize_t)
from .info import PY2
c_ssize_p = POINTER(c_ssize_t)
PyObject_GetBuffer = pythonapi.PyObject_GetBuffer
PyBuffer_Release = pythonapi.PyBuffer_Release
PyBUF_SIMPLE = 0
PyBUF_WRITABLE = 1
class Py_buffer(ctypes.Structure):
_fields_ = [
("buf", c_void_p),
("obj", py_object),
("len", c_ssize_t),
("itemsize", c_ssize_t),
("readonly", c_int),
("ndim", c_int),
("format", c_char_p),
("shape", c_ssize_p),
("strides", c_ssize_p),
("suboffsets", c_ssize_p),
("internal", c_void_p)
]
if PY2:
_fields_.insert(-1, ("smalltable", c_ssize_t * 2))
@classmethod
def get_from(cls, obj, flags=PyBUF_SIMPLE):
buf = cls()
PyObject_GetBuffer(py_object(obj), byref(buf), flags)
return buf
def release(self):
PyBuffer_Release(byref(self))
def get_buffer(obj, writable=False):
buf = Py_buffer.get_from(obj, PyBUF_WRITABLE if writable else PyBUF_SIMPLE)
try:
buffer_type = c_char * buf.len
return buffer_type.from_address(buf.buf)
finally:
buf.release()
|