diff options
author | Inada Naoki <songofacandy@gmail.com> | 2021-07-29 10:46:47 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 10:46:47 (GMT) |
commit | ce5e1a6809b714eb0383219190a076d9f883e008 (patch) | |
tree | a28ab28d295952746ff8bfe71b26e56b1d4acc95 /Objects | |
parent | d542742128b634264d5b6796297613975211b43b (diff) | |
download | cpython-ce5e1a6809b714eb0383219190a076d9f883e008.zip cpython-ce5e1a6809b714eb0383219190a076d9f883e008.tar.gz cpython-ce5e1a6809b714eb0383219190a076d9f883e008.tar.bz2 |
bpo-41103: Resurrect the old buffer protocol. (GH-27437)
Revert "bpo-41103: Remove old buffer protocol support (#21117)"
This reverts commit 6f8a6ee59cb7f99f68df8ee9c3e8c8cf19af3eed.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index 842c367..8ad1910 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -293,6 +293,85 @@ PyObject_CheckBuffer(PyObject *obj) } +/* We release the buffer right after use of this function which could + cause issues later on. Don't use these functions in new code. + */ +int +PyObject_CheckReadBuffer(PyObject *obj) +{ + PyBufferProcs *pb = Py_TYPE(obj)->tp_as_buffer; + Py_buffer view; + + if (pb == NULL || + pb->bf_getbuffer == NULL) + return 0; + if ((*pb->bf_getbuffer)(obj, &view, PyBUF_SIMPLE) == -1) { + PyErr_Clear(); + return 0; + } + PyBuffer_Release(&view); + return 1; +} + +static int +as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) +{ + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + if (PyObject_GetBuffer(obj, &view, PyBUF_SIMPLE) != 0) + return -1; + + *buffer = view.buf; + *buffer_len = view.len; + PyBuffer_Release(&view); + return 0; +} + +int +PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, (const void **)buffer, buffer_len); +} + +int PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, buffer, buffer_len); +} + +int PyObject_AsWriteBuffer(PyObject *obj, + void **buffer, + Py_ssize_t *buffer_len) +{ + PyBufferProcs *pb; + Py_buffer view; + + if (obj == NULL || buffer == NULL || buffer_len == NULL) { + null_error(); + return -1; + } + pb = Py_TYPE(obj)->tp_as_buffer; + if (pb == NULL || + pb->bf_getbuffer == NULL || + ((*pb->bf_getbuffer)(obj, &view, PyBUF_WRITABLE) != 0)) { + PyErr_SetString(PyExc_TypeError, + "expected a writable bytes-like object"); + return -1; + } + + *buffer = view.buf; + *buffer_len = view.len; + PyBuffer_Release(&view); + return 0; +} + /* Buffer C-API for Python 3.0 */ int |