diff options
Diffstat (limited to 'Objects/bufferobject.c')
-rw-r--r-- | Objects/bufferobject.c | 74 |
1 files changed, 58 insertions, 16 deletions
diff --git a/Objects/bufferobject.c b/Objects/bufferobject.c index 3a0e3d5..ddef868 100644 --- a/Objects/bufferobject.c +++ b/Objects/bufferobject.c @@ -252,23 +252,65 @@ buffer_dealloc(PyBufferObject *self) } static int -buffer_compare(PyBufferObject *self, PyBufferObject *other) +get_bufx(PyObject *obj, void **ptr, Py_ssize_t *size) { - void *p1, *p2; - Py_ssize_t len_self, len_other, min_len; - int cmp; + PyBufferProcs *bp; - if (!get_buf(self, &p1, &len_self, ANY_BUFFER)) - return -1; - if (!get_buf(other, &p2, &len_other, ANY_BUFFER)) - return -1; - min_len = (len_self < len_other) ? len_self : len_other; - if (min_len > 0) { - cmp = memcmp(p1, p2, min_len); - if (cmp != 0) - return cmp < 0 ? -1 : 1; + if (PyBuffer_Check(obj)) { + if (!get_buf((PyBufferObject *)obj, ptr, size, ANY_BUFFER)) { + PyErr_Clear(); + return 0; + } + else + return 1; + } + bp = obj->ob_type->tp_as_buffer; + if (bp == NULL || + bp->bf_getreadbuffer == NULL || + bp->bf_getsegcount == NULL) + return 0; + if ((*bp->bf_getsegcount)(obj, NULL) != 1) + return 0; + *size = (*bp->bf_getreadbuffer)(obj, 0, ptr); + if (*size < 0) { + PyErr_Clear(); + return 0; + } + return 1; +} + +static PyObject * +buffer_richcompare(PyObject *self, PyObject *other, int op) +{ + void *p1, *p2; + Py_ssize_t len1, len2, min_len; + int cmp, ok; + + ok = 1; + if (!get_bufx(self, &p1, &len1)) + ok = 0; + if (!get_bufx(other, &p2, &len2)) + ok = 0; + if (!ok) { + /* If we can't get the buffers, + == and != are still defined + (and the objects are unequal) */ + PyObject *result; + if (op == Py_EQ) + result = Py_False; + else if (op == Py_NE) + result = Py_True; + else + result = Py_NotImplemented; + Py_INCREF(result); + return result; } - return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0; + min_len = (len1 < len2) ? len1 : len2; + cmp = memcmp(p1, p2, min_len); + if (cmp == 0) + cmp = (len1 < len2) ? -1 : + (len1 > len2) ? 1 : 0; + return Py_CmpToRich(op, cmp); } static PyObject * @@ -667,7 +709,7 @@ PyTypeObject PyBuffer_Type = { 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - (cmpfunc)buffer_compare, /* tp_compare */ + 0, /* tp_compare */ (reprfunc)buffer_repr, /* tp_repr */ 0, /* tp_as_number */ &buffer_as_sequence, /* tp_as_sequence */ @@ -682,7 +724,7 @@ PyTypeObject PyBuffer_Type = { buffer_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - 0, /* tp_richcompare */ + buffer_richcompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ |