123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- 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()
|