pyo3_ffi/
pybuffer.rs

1use crate::object::PyObject;
2use crate::pyport::Py_ssize_t;
3use std::os::raw::{c_char, c_int, c_void};
4use std::ptr;
5
6#[repr(C)]
7#[derive(Copy, Clone)]
8pub struct Py_buffer {
9    pub buf: *mut c_void,
10    /// Owned reference
11    pub obj: *mut crate::PyObject,
12    pub len: Py_ssize_t,
13    pub itemsize: Py_ssize_t,
14    pub readonly: c_int,
15    pub ndim: c_int,
16    pub format: *mut c_char,
17    pub shape: *mut Py_ssize_t,
18    pub strides: *mut Py_ssize_t,
19    pub suboffsets: *mut Py_ssize_t,
20    pub internal: *mut c_void,
21    #[cfg(PyPy)]
22    pub flags: c_int,
23    #[cfg(PyPy)]
24    pub _strides: [Py_ssize_t; PyBUF_MAX_NDIM],
25    #[cfg(PyPy)]
26    pub _shape: [Py_ssize_t; PyBUF_MAX_NDIM],
27}
28
29impl Py_buffer {
30    #[allow(clippy::new_without_default)]
31    pub const fn new() -> Self {
32        Py_buffer {
33            buf: ptr::null_mut(),
34            obj: ptr::null_mut(),
35            len: 0,
36            itemsize: 0,
37            readonly: 0,
38            ndim: 0,
39            format: ptr::null_mut(),
40            shape: ptr::null_mut(),
41            strides: ptr::null_mut(),
42            suboffsets: ptr::null_mut(),
43            internal: ptr::null_mut(),
44            #[cfg(PyPy)]
45            flags: 0,
46            #[cfg(PyPy)]
47            _strides: [0; PyBUF_MAX_NDIM],
48            #[cfg(PyPy)]
49            _shape: [0; PyBUF_MAX_NDIM],
50        }
51    }
52}
53
54pub type getbufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer, c_int) -> c_int;
55pub type releasebufferproc = unsafe extern "C" fn(*mut PyObject, *mut crate::Py_buffer);
56
57/* Return 1 if the getbuffer function is available, otherwise return 0. */
58extern "C" {
59    #[cfg(not(PyPy))]
60    pub fn PyObject_CheckBuffer(obj: *mut PyObject) -> c_int;
61
62    #[cfg_attr(PyPy, link_name = "PyPyObject_GetBuffer")]
63    pub fn PyObject_GetBuffer(obj: *mut PyObject, view: *mut Py_buffer, flags: c_int) -> c_int;
64    #[cfg_attr(PyPy, link_name = "PyPyBuffer_GetPointer")]
65    pub fn PyBuffer_GetPointer(view: *const Py_buffer, indices: *const Py_ssize_t) -> *mut c_void;
66    #[cfg_attr(PyPy, link_name = "PyPyBuffer_SizeFromFormat")]
67    pub fn PyBuffer_SizeFromFormat(format: *const c_char) -> Py_ssize_t;
68    #[cfg_attr(PyPy, link_name = "PyPyBuffer_ToContiguous")]
69    pub fn PyBuffer_ToContiguous(
70        buf: *mut c_void,
71        view: *const Py_buffer,
72        len: Py_ssize_t,
73        order: c_char,
74    ) -> c_int;
75    #[cfg_attr(PyPy, link_name = "PyPyBuffer_FromContiguous")]
76    pub fn PyBuffer_FromContiguous(
77        view: *const Py_buffer,
78        buf: *const c_void,
79        len: Py_ssize_t,
80        order: c_char,
81    ) -> c_int;
82    pub fn PyObject_CopyData(dest: *mut PyObject, src: *mut PyObject) -> c_int;
83    #[cfg_attr(PyPy, link_name = "PyPyBuffer_IsContiguous")]
84    pub fn PyBuffer_IsContiguous(view: *const Py_buffer, fort: c_char) -> c_int;
85    pub fn PyBuffer_FillContiguousStrides(
86        ndims: c_int,
87        shape: *mut Py_ssize_t,
88        strides: *mut Py_ssize_t,
89        itemsize: c_int,
90        fort: c_char,
91    );
92    #[cfg_attr(PyPy, link_name = "PyPyBuffer_FillInfo")]
93    pub fn PyBuffer_FillInfo(
94        view: *mut Py_buffer,
95        o: *mut PyObject,
96        buf: *mut c_void,
97        len: Py_ssize_t,
98        readonly: c_int,
99        flags: c_int,
100    ) -> c_int;
101    #[cfg_attr(PyPy, link_name = "PyPyBuffer_Release")]
102    pub fn PyBuffer_Release(view: *mut Py_buffer);
103}
104
105/// Maximum number of dimensions
106pub const PyBUF_MAX_NDIM: usize = if cfg!(all(PyPy, not(Py_3_11))) {
107    36
108} else {
109    64
110};
111
112/* Flags for getting buffers */
113pub const PyBUF_SIMPLE: c_int = 0;
114pub const PyBUF_WRITABLE: c_int = 0x0001;
115/* we used to include an E, backwards compatible alias */
116pub const PyBUF_WRITEABLE: c_int = PyBUF_WRITABLE;
117pub const PyBUF_FORMAT: c_int = 0x0004;
118pub const PyBUF_ND: c_int = 0x0008;
119pub const PyBUF_STRIDES: c_int = 0x0010 | PyBUF_ND;
120pub const PyBUF_C_CONTIGUOUS: c_int = 0x0020 | PyBUF_STRIDES;
121pub const PyBUF_F_CONTIGUOUS: c_int = 0x0040 | PyBUF_STRIDES;
122pub const PyBUF_ANY_CONTIGUOUS: c_int = 0x0080 | PyBUF_STRIDES;
123pub const PyBUF_INDIRECT: c_int = 0x0100 | PyBUF_STRIDES;
124
125pub const PyBUF_CONTIG: c_int = PyBUF_ND | PyBUF_WRITABLE;
126pub const PyBUF_CONTIG_RO: c_int = PyBUF_ND;
127
128pub const PyBUF_STRIDED: c_int = PyBUF_STRIDES | PyBUF_WRITABLE;
129pub const PyBUF_STRIDED_RO: c_int = PyBUF_STRIDES;
130
131pub const PyBUF_RECORDS: c_int = PyBUF_STRIDES | PyBUF_WRITABLE | PyBUF_FORMAT;
132pub const PyBUF_RECORDS_RO: c_int = PyBUF_STRIDES | PyBUF_FORMAT;
133
134pub const PyBUF_FULL: c_int = PyBUF_INDIRECT | PyBUF_WRITABLE | PyBUF_FORMAT;
135pub const PyBUF_FULL_RO: c_int = PyBUF_INDIRECT | PyBUF_FORMAT;
136
137pub const PyBUF_READ: c_int = 0x100;
138pub const PyBUF_WRITE: c_int = 0x200;