mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
Merged revisions 65654 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r65654 | martin.v.loewis | 2008-08-12 16:49:50 +0200 (Tue, 12 Aug 2008) | 6 lines Issue #3139: Make buffer-interface thread-safe wrt. PyArg_ParseTuple, by denying s# to parse objects that have a releasebuffer procedure, and introducing s*. More module might need to get converted to use s*. ........
This commit is contained in:
parent
688356f59f
commit
423be95dcf
32 changed files with 721 additions and 390 deletions
|
@ -349,16 +349,6 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags)
|
|||
return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags);
|
||||
}
|
||||
|
||||
void
|
||||
PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view)
|
||||
{
|
||||
if (obj->ob_type->tp_as_buffer != NULL &&
|
||||
obj->ob_type->tp_as_buffer->bf_releasebuffer != NULL) {
|
||||
(*(obj->ob_type->tp_as_buffer->bf_releasebuffer))(obj, view);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_IsFortranContiguous(Py_buffer *view)
|
||||
{
|
||||
|
@ -590,15 +580,15 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
|
|||
|
||||
if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1;
|
||||
if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) {
|
||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
||||
PyBuffer_Release(&view_dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (view_dest.len < view_src.len) {
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
"destination is too small to receive data from source");
|
||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
||||
PyObject_ReleaseBuffer(src, &view_src);
|
||||
PyBuffer_Release(&view_dest);
|
||||
PyBuffer_Release(&view_src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -608,8 +598,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
|
|||
PyBuffer_IsContiguous(&view_src, 'F'))) {
|
||||
/* simplest copy is all that is needed */
|
||||
memcpy(view_dest.buf, view_src.buf, view_src.len);
|
||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
||||
PyObject_ReleaseBuffer(src, &view_src);
|
||||
PyBuffer_Release(&view_dest);
|
||||
PyBuffer_Release(&view_src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -619,8 +609,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
|
|||
indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim);
|
||||
if (indices == NULL) {
|
||||
PyErr_NoMemory();
|
||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
||||
PyObject_ReleaseBuffer(src, &view_src);
|
||||
PyBuffer_Release(&view_dest);
|
||||
PyBuffer_Release(&view_src);
|
||||
return -1;
|
||||
}
|
||||
for (k=0; k<view_src.ndim;k++) {
|
||||
|
@ -638,8 +628,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src)
|
|||
memcpy(dptr, sptr, view_src.itemsize);
|
||||
}
|
||||
PyMem_Free(indices);
|
||||
PyObject_ReleaseBuffer(dest, &view_dest);
|
||||
PyObject_ReleaseBuffer(src, &view_src);
|
||||
PyBuffer_Release(&view_dest);
|
||||
PyBuffer_Release(&view_src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -668,7 +658,7 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape,
|
|||
}
|
||||
|
||||
int
|
||||
PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
|
||||
PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len,
|
||||
int readonly, int flags)
|
||||
{
|
||||
if (view == NULL) return 0;
|
||||
|
@ -679,6 +669,7 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
|
|||
return -1;
|
||||
}
|
||||
|
||||
view->obj = obj;
|
||||
view->buf = buf;
|
||||
view->len = len;
|
||||
view->readonly = readonly;
|
||||
|
@ -698,6 +689,17 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PyBuffer_Release(Py_buffer *view)
|
||||
{
|
||||
PyObject *obj = view->obj;
|
||||
if (!obj || !Py_TYPE(obj)->tp_as_buffer || !Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer)
|
||||
/* Unmanaged buffer */
|
||||
return;
|
||||
Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view);
|
||||
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyObject_Format(PyObject *obj, PyObject *format_spec)
|
||||
{
|
||||
|
|
|
@ -69,7 +69,7 @@ bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
|
|||
ptr = "";
|
||||
else
|
||||
ptr = obj->ob_bytes;
|
||||
ret = PyBuffer_FillInfo(view, ptr, Py_SIZE(obj), 0, flags);
|
||||
ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags);
|
||||
if (ret >= 0) {
|
||||
obj->ob_exports++;
|
||||
}
|
||||
|
@ -248,9 +248,9 @@ PyByteArray_Concat(PyObject *a, PyObject *b)
|
|||
|
||||
done:
|
||||
if (va.len != -1)
|
||||
PyObject_ReleaseBuffer(a, &va);
|
||||
PyBuffer_Release(&va);
|
||||
if (vb.len != -1)
|
||||
PyObject_ReleaseBuffer(b, &vb);
|
||||
PyBuffer_Release(&vb);
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
|
|||
mysize = Py_SIZE(self);
|
||||
size = mysize + vo.len;
|
||||
if (size < 0) {
|
||||
PyObject_ReleaseBuffer(other, &vo);
|
||||
PyBuffer_Release(&vo);
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
if (size < self->ob_alloc) {
|
||||
|
@ -286,11 +286,11 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other)
|
|||
self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
|
||||
}
|
||||
else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
|
||||
PyObject_ReleaseBuffer(other, &vo);
|
||||
PyBuffer_Release(&vo);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
|
||||
PyObject_ReleaseBuffer(other, &vo);
|
||||
PyBuffer_Release(&vo);
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
}
|
||||
|
@ -501,7 +501,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
|
|||
|
||||
finish:
|
||||
if (vbytes.len != -1)
|
||||
PyObject_ReleaseBuffer(values, &vbytes);
|
||||
PyBuffer_Release(&vbytes);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -767,10 +767,10 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
|
|||
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
|
||||
if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
|
||||
goto fail;
|
||||
PyObject_ReleaseBuffer(arg, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return 0;
|
||||
fail:
|
||||
PyObject_ReleaseBuffer(arg, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -954,7 +954,7 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
|||
other_size = _getbuffer(other, &other_bytes);
|
||||
if (other_size < 0) {
|
||||
PyErr_Clear();
|
||||
PyObject_ReleaseBuffer(self, &self_bytes);
|
||||
PyBuffer_Release(&self_bytes);
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
@ -989,8 +989,8 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
|||
}
|
||||
|
||||
res = cmp ? Py_True : Py_False;
|
||||
PyObject_ReleaseBuffer(self, &self_bytes);
|
||||
PyObject_ReleaseBuffer(other, &other_bytes);
|
||||
PyBuffer_Release(&self_bytes);
|
||||
PyBuffer_Release(&other_bytes);
|
||||
Py_INCREF(res);
|
||||
return res;
|
||||
}
|
||||
|
@ -998,6 +998,11 @@ bytes_richcompare(PyObject *self, PyObject *other, int op)
|
|||
static void
|
||||
bytes_dealloc(PyByteArrayObject *self)
|
||||
{
|
||||
if (self->ob_exports > 0) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"deallocated bytearray object has exported buffers");
|
||||
PyErr_Print();
|
||||
}
|
||||
if (self->ob_bytes != 0) {
|
||||
PyMem_Free(self->ob_bytes);
|
||||
}
|
||||
|
@ -1065,7 +1070,7 @@ bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir)
|
|||
res = stringlib_rfind_slice(
|
||||
PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
|
||||
subbuf.buf, subbuf.len, start, end);
|
||||
PyObject_ReleaseBuffer(subobj, &subbuf);
|
||||
PyBuffer_Release(&subbuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1120,7 @@ bytes_count(PyByteArrayObject *self, PyObject *args)
|
|||
count_obj = PyLong_FromSsize_t(
|
||||
stringlib_count(str + start, end - start, vsub.buf, vsub.len)
|
||||
);
|
||||
PyObject_ReleaseBuffer(sub_obj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return count_obj;
|
||||
}
|
||||
|
||||
|
@ -1191,7 +1196,7 @@ bytes_contains(PyObject *self, PyObject *arg)
|
|||
return -1;
|
||||
pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self),
|
||||
varg.buf, varg.len, 0);
|
||||
PyObject_ReleaseBuffer(arg, &varg);
|
||||
PyBuffer_Release(&varg);
|
||||
return pos >= 0;
|
||||
}
|
||||
if (ival < 0 || ival >= 256) {
|
||||
|
@ -1241,7 +1246,7 @@ _bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start,
|
|||
rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len);
|
||||
|
||||
done:
|
||||
PyObject_ReleaseBuffer(substr, &vsubstr);
|
||||
PyBuffer_Release(&vsubstr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1421,9 +1426,9 @@ bytes_translate(PyByteArrayObject *self, PyObject *args)
|
|||
PyByteArray_Resize(result, output - output_start);
|
||||
|
||||
done:
|
||||
PyObject_ReleaseBuffer(tableobj, &vtable);
|
||||
PyBuffer_Release(&vtable);
|
||||
if (delobj != NULL)
|
||||
PyObject_ReleaseBuffer(delobj, &vdel);
|
||||
PyBuffer_Release(&vdel);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2042,7 +2047,7 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
|
|||
if (_getbuffer(from, &vfrom) < 0)
|
||||
return NULL;
|
||||
if (_getbuffer(to, &vto) < 0) {
|
||||
PyObject_ReleaseBuffer(from, &vfrom);
|
||||
PyBuffer_Release(&vfrom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2050,8 +2055,8 @@ bytes_replace(PyByteArrayObject *self, PyObject *args)
|
|||
vfrom.buf, vfrom.len,
|
||||
vto.buf, vto.len, count);
|
||||
|
||||
PyObject_ReleaseBuffer(from, &vfrom);
|
||||
PyObject_ReleaseBuffer(to, &vto);
|
||||
PyBuffer_Release(&vfrom);
|
||||
PyBuffer_Release(&vto);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2207,7 +2212,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
|||
|
||||
if (n == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
if (n == 1)
|
||||
|
@ -2215,7 +2220,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
|||
|
||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||
if (list == NULL) {
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2243,12 +2248,12 @@ bytes_split(PyByteArrayObject *self, PyObject *args)
|
|||
#endif
|
||||
SPLIT_ADD(s, i, len);
|
||||
FIX_PREALLOC_SIZE(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return list;
|
||||
|
||||
onError:
|
||||
Py_DECREF(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2439,7 +2444,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
|||
|
||||
if (n == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
else if (n == 1)
|
||||
|
@ -2447,7 +2452,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
|||
|
||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||
if (list == NULL) {
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2468,12 +2473,12 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args)
|
|||
FIX_PREALLOC_SIZE(list);
|
||||
if (PyList_Reverse(list) < 0)
|
||||
goto onError;
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return list;
|
||||
|
||||
onError:
|
||||
Py_DECREF(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2749,7 +2754,7 @@ bytes_strip(PyByteArrayObject *self, PyObject *args)
|
|||
else
|
||||
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
||||
if (arg != Py_None)
|
||||
PyObject_ReleaseBuffer(arg, &varg);
|
||||
PyBuffer_Release(&varg);
|
||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
||||
}
|
||||
|
||||
|
@ -2783,7 +2788,7 @@ bytes_lstrip(PyByteArrayObject *self, PyObject *args)
|
|||
left = lstrip_helper(myptr, mysize, argptr, argsize);
|
||||
right = mysize;
|
||||
if (arg != Py_None)
|
||||
PyObject_ReleaseBuffer(arg, &varg);
|
||||
PyBuffer_Release(&varg);
|
||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
||||
}
|
||||
|
||||
|
@ -2817,7 +2822,7 @@ bytes_rstrip(PyByteArrayObject *self, PyObject *args)
|
|||
left = 0;
|
||||
right = rstrip_helper(myptr, mysize, argptr, argsize);
|
||||
if (arg != Py_None)
|
||||
PyObject_ReleaseBuffer(arg, &varg);
|
||||
PyBuffer_Release(&varg);
|
||||
return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
|
||||
}
|
||||
|
||||
|
|
|
@ -710,9 +710,9 @@ string_concat(PyObject *a, PyObject *b)
|
|||
|
||||
done:
|
||||
if (va.len != -1)
|
||||
PyObject_ReleaseBuffer(a, &va);
|
||||
PyBuffer_Release(&va);
|
||||
if (vb.len != -1)
|
||||
PyObject_ReleaseBuffer(b, &vb);
|
||||
PyBuffer_Release(&vb);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -781,7 +781,7 @@ string_contains(PyObject *self, PyObject *arg)
|
|||
return -1;
|
||||
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
|
||||
varg.buf, varg.len, 0);
|
||||
PyObject_ReleaseBuffer(arg, &varg);
|
||||
PyBuffer_Release(&varg);
|
||||
return pos >= 0;
|
||||
}
|
||||
if (ival < 0 || ival >= 256) {
|
||||
|
@ -964,7 +964,7 @@ string_subscript(PyBytesObject* self, PyObject* item)
|
|||
static int
|
||||
string_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags)
|
||||
{
|
||||
return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_SIZE(self),
|
||||
return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self),
|
||||
1, flags);
|
||||
}
|
||||
|
||||
|
@ -1160,7 +1160,7 @@ string_split(PyBytesObject *self, PyObject *args)
|
|||
|
||||
if (n == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
else if (n == 1)
|
||||
|
@ -1168,7 +1168,7 @@ string_split(PyBytesObject *self, PyObject *args)
|
|||
|
||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||
if (list == NULL) {
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1196,12 +1196,12 @@ string_split(PyBytesObject *self, PyObject *args)
|
|||
#endif
|
||||
SPLIT_ADD(s, i, len);
|
||||
FIX_PREALLOC_SIZE(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return list;
|
||||
|
||||
onError:
|
||||
Py_DECREF(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1376,7 +1376,7 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
|||
|
||||
if (n == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "empty separator");
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
else if (n == 1)
|
||||
|
@ -1384,7 +1384,7 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
|||
|
||||
list = PyList_New(PREALLOC_SIZE(maxsplit));
|
||||
if (list == NULL) {
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1406,12 +1406,12 @@ string_rsplit(PyBytesObject *self, PyObject *args)
|
|||
FIX_PREALLOC_SIZE(list);
|
||||
if (PyList_Reverse(list) < 0)
|
||||
goto onError;
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return list;
|
||||
|
||||
onError:
|
||||
Py_DECREF(list);
|
||||
PyObject_ReleaseBuffer(subobj, &vsub);
|
||||
PyBuffer_Release(&vsub);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1690,7 +1690,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj)
|
|||
j++;
|
||||
}
|
||||
|
||||
PyObject_ReleaseBuffer(sepobj, &vsep);
|
||||
PyBuffer_Release(&vsep);
|
||||
|
||||
if (i == 0 && j == len && PyBytes_CheckExact(self)) {
|
||||
Py_INCREF(self);
|
||||
|
@ -2945,11 +2945,11 @@ string_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval,
|
||||
&view, view.len, 'C') < 0)
|
||||
goto fail;
|
||||
PyObject_ReleaseBuffer(x, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return new;
|
||||
fail:
|
||||
Py_XDECREF(new);
|
||||
PyObject_ReleaseBuffer(x, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,19 +6,21 @@
|
|||
static int
|
||||
memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags)
|
||||
{
|
||||
if (view != NULL)
|
||||
if (view != NULL) {
|
||||
if (self->view.obj)
|
||||
Py_INCREF(self->view.obj);
|
||||
*view = self->view;
|
||||
if (self->base == NULL)
|
||||
}
|
||||
if (self->view.obj == NULL)
|
||||
return 0;
|
||||
return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
|
||||
return self->view.obj->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL,
|
||||
PyBUF_FULL);
|
||||
}
|
||||
|
||||
static void
|
||||
memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view)
|
||||
{
|
||||
if (self->base != NULL)
|
||||
PyObject_ReleaseBuffer(self->base, NULL);
|
||||
PyBuffer_Release(&self->view);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(memory_doc,
|
||||
|
@ -36,6 +38,8 @@ PyMemoryView_FromMemory(Py_buffer *info)
|
|||
if (mview == NULL) return NULL;
|
||||
mview->base = NULL;
|
||||
mview->view = *info;
|
||||
if (info->obj)
|
||||
Py_INCREF(mview->view.obj);
|
||||
return (PyObject *)mview;
|
||||
}
|
||||
|
||||
|
@ -256,7 +260,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
|||
}
|
||||
bytes = PyByteArray_FromStringAndSize(NULL, view->len);
|
||||
if (bytes == NULL) {
|
||||
PyObject_ReleaseBuffer(obj, view);
|
||||
PyBuffer_Release(view);
|
||||
return NULL;
|
||||
}
|
||||
dest = PyByteArray_AS_STRING(bytes);
|
||||
|
@ -271,7 +275,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
|||
else {
|
||||
if (_indirect_copy_nd(dest, view, fort) < 0) {
|
||||
Py_DECREF(bytes);
|
||||
PyObject_ReleaseBuffer(obj, view);
|
||||
PyBuffer_Release(view);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -281,12 +285,12 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort)
|
|||
mem->base = PyTuple_Pack(2, obj, bytes);
|
||||
Py_DECREF(bytes);
|
||||
if (mem->base == NULL) {
|
||||
PyObject_ReleaseBuffer(obj, view);
|
||||
PyBuffer_Release(view);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PyObject_ReleaseBuffer(obj, view);
|
||||
PyBuffer_Release(view);
|
||||
/* steal the reference */
|
||||
mem->base = bytes;
|
||||
}
|
||||
|
@ -407,7 +411,7 @@ static PyMethodDef memory_methods[] = {
|
|||
static void
|
||||
memory_dealloc(PyMemoryViewObject *self)
|
||||
{
|
||||
if (self->base != NULL) {
|
||||
if (self->view.obj != NULL) {
|
||||
if (PyTuple_Check(self->base)) {
|
||||
/* Special case when first element is generic object
|
||||
with buffer interface and the second element is a
|
||||
|
@ -424,11 +428,10 @@ memory_dealloc(PyMemoryViewObject *self)
|
|||
be "locked" and was locked and will be unlocked
|
||||
again after this call.
|
||||
*/
|
||||
PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0),
|
||||
&(self->view));
|
||||
PyBuffer_Release(&(self->view));
|
||||
}
|
||||
else {
|
||||
PyObject_ReleaseBuffer(self->base, &(self->view));
|
||||
PyBuffer_Release(&(self->view));
|
||||
}
|
||||
Py_CLEAR(self->base);
|
||||
}
|
||||
|
@ -453,7 +456,7 @@ memory_str(PyMemoryViewObject *self)
|
|||
|
||||
res = PyByteArray_FromStringAndSize(NULL, view.len);
|
||||
PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C');
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -466,7 +469,7 @@ memory_length(PyMemoryViewObject *self)
|
|||
|
||||
if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0)
|
||||
return -1;
|
||||
PyObject_ReleaseBuffer((PyObject *)self, &view);
|
||||
PyBuffer_Release(&view);
|
||||
return view.len;
|
||||
}
|
||||
|
||||
|
|
|
@ -1198,7 +1198,7 @@ PyObject *PyUnicode_Decode(const char *s,
|
|||
|
||||
/* Decode via the codec registry */
|
||||
buffer = NULL;
|
||||
if (PyBuffer_FillInfo(&info, (void *)s, size, 1, PyBUF_SIMPLE) < 0)
|
||||
if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_SIMPLE) < 0)
|
||||
goto onError;
|
||||
buffer = PyMemoryView_FromMemory(&info);
|
||||
if (buffer == NULL)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue