diff options
Diffstat (limited to 'c/minibuffer.h')
-rw-r--r-- | c/minibuffer.h | 408 |
1 files changed, 0 insertions, 408 deletions
diff --git a/c/minibuffer.h b/c/minibuffer.h deleted file mode 100644 index f3f5ca1..0000000 --- a/c/minibuffer.h +++ /dev/null @@ -1,408 +0,0 @@ - -/* Implementation of a C object with the 'buffer' or 'memoryview' - * interface at C-level (as approriate for the version of Python we're - * compiling for), but only a minimal but *consistent* part of the - * 'buffer' interface at application level. - */ - -typedef struct { - PyObject_HEAD - char *mb_data; - Py_ssize_t mb_size; - PyObject *mb_keepalive; - PyObject *mb_weakreflist; /* weakref support */ -} MiniBufferObj; - -static Py_ssize_t mb_length(MiniBufferObj *self) -{ - return self->mb_size; -} - -static PyObject *mb_item(MiniBufferObj *self, Py_ssize_t idx) -{ - if (idx < 0 || idx >= self->mb_size ) { - PyErr_SetString(PyExc_IndexError, "buffer index out of range"); - return NULL; - } - return PyBytes_FromStringAndSize(self->mb_data + idx, 1); -} - -static PyObject *mb_slice(MiniBufferObj *self, - Py_ssize_t left, Py_ssize_t right) -{ - Py_ssize_t size = self->mb_size; - if (left < 0) left = 0; - if (right > size) right = size; - if (left > right) left = right; - return PyBytes_FromStringAndSize(self->mb_data + left, right - left); -} - -static int mb_ass_item(MiniBufferObj *self, Py_ssize_t idx, PyObject *other) -{ - if (idx < 0 || idx >= self->mb_size) { - PyErr_SetString(PyExc_IndexError, - "buffer assignment index out of range"); - return -1; - } - if (PyBytes_Check(other) && PyBytes_GET_SIZE(other) == 1) { - self->mb_data[idx] = PyBytes_AS_STRING(other)[0]; - return 0; - } - else { - PyErr_Format(PyExc_TypeError, - "must assign a "STR_OR_BYTES - " of length 1, not %.200s", Py_TYPE(other)->tp_name); - return -1; - } -} - -/* forward: from _cffi_backend.c */ -static int _fetch_as_buffer(PyObject *x, Py_buffer *view, int writable_only); - -static int mb_ass_slice(MiniBufferObj *self, - Py_ssize_t left, Py_ssize_t right, PyObject *other) -{ - Py_ssize_t count; - Py_ssize_t size = self->mb_size; - Py_buffer src_view; - - if (_fetch_as_buffer(other, &src_view, 0) < 0) - return -1; - - if (left < 0) left = 0; - if (right > size) right = size; - if (left > right) left = right; - - count = right - left; - if (count != src_view.len) { - PyBuffer_Release(&src_view); - PyErr_SetString(PyExc_ValueError, - "right operand length must match slice length"); - return -1; - } - memcpy(self->mb_data + left, src_view.buf, count); - PyBuffer_Release(&src_view); - return 0; -} - -#if PY_MAJOR_VERSION < 3 -static Py_ssize_t mb_getdata(MiniBufferObj *self, Py_ssize_t idx, void **pp) -{ - *pp = self->mb_data; - return self->mb_size; -} - -static Py_ssize_t mb_getsegcount(MiniBufferObj *self, Py_ssize_t *lenp) -{ - if (lenp) - *lenp = self->mb_size; - return 1; -} - -static PyObject *mb_str(MiniBufferObj *self) -{ - /* Python 2: we want str(buffer) to behave like buffer[:], because - that's what bytes(buffer) does on Python 3 and there is no way - we can prevent this. */ - return PyString_FromStringAndSize(self->mb_data, self->mb_size); -} -#endif - -static int mb_getbuf(MiniBufferObj *self, Py_buffer *view, int flags) -{ - return PyBuffer_FillInfo(view, (PyObject *)self, - self->mb_data, self->mb_size, - /*readonly=*/0, flags); -} - -static PySequenceMethods mb_as_sequence = { - (lenfunc)mb_length, /*sq_length*/ - (binaryfunc)0, /*sq_concat*/ - (ssizeargfunc)0, /*sq_repeat*/ - (ssizeargfunc)mb_item, /*sq_item*/ - (ssizessizeargfunc)mb_slice, /*sq_slice*/ - (ssizeobjargproc)mb_ass_item, /*sq_ass_item*/ - (ssizessizeobjargproc)mb_ass_slice, /*sq_ass_slice*/ -}; - -static PyBufferProcs mb_as_buffer = { -#if PY_MAJOR_VERSION < 3 - (readbufferproc)mb_getdata, - (writebufferproc)mb_getdata, - (segcountproc)mb_getsegcount, - (charbufferproc)mb_getdata, -#endif - (getbufferproc)mb_getbuf, - (releasebufferproc)0, -}; - -static void -mb_dealloc(MiniBufferObj *ob) -{ - PyObject_GC_UnTrack(ob); - if (ob->mb_weakreflist != NULL) - PyObject_ClearWeakRefs((PyObject *)ob); - Py_XDECREF(ob->mb_keepalive); - Py_TYPE(ob)->tp_free((PyObject *)ob); -} - -static int -mb_traverse(MiniBufferObj *ob, visitproc visit, void *arg) -{ - Py_VISIT(ob->mb_keepalive); - return 0; -} - -static int -mb_clear(MiniBufferObj *ob) -{ - Py_CLEAR(ob->mb_keepalive); - return 0; -} - -static PyObject * -mb_richcompare(PyObject *self, PyObject *other, int op) -{ - Py_ssize_t self_size, other_size; - Py_buffer self_bytes, other_bytes; - PyObject *res; - Py_ssize_t minsize; - int cmp, rc; - - /* Bytes can be compared to anything that supports the (binary) - buffer API. Except that a comparison with Unicode is always an - error, even if the comparison is for equality. */ - rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); - if (!rc) - rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); - if (rc < 0) - return NULL; - if (rc) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) { - PyErr_Clear(); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - - } - self_size = self_bytes.len; - - if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) { - PyErr_Clear(); - PyBuffer_Release(&self_bytes); - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - - } - other_size = other_bytes.len; - - if (self_size != other_size && (op == Py_EQ || op == Py_NE)) { - /* Shortcut: if the lengths differ, the objects differ */ - cmp = (op == Py_NE); - } - else { - minsize = self_size; - if (other_size < minsize) - minsize = other_size; - - cmp = memcmp(self_bytes.buf, other_bytes.buf, minsize); - /* In ISO C, memcmp() guarantees to use unsigned bytes! */ - - if (cmp == 0) { - if (self_size < other_size) - cmp = -1; - else if (self_size > other_size) - cmp = 1; - } - - switch (op) { - case Py_LT: cmp = cmp < 0; break; - case Py_LE: cmp = cmp <= 0; break; - case Py_EQ: cmp = cmp == 0; break; - case Py_NE: cmp = cmp != 0; break; - case Py_GT: cmp = cmp > 0; break; - case Py_GE: cmp = cmp >= 0; break; - } - } - - res = cmp ? Py_True : Py_False; - PyBuffer_Release(&self_bytes); - PyBuffer_Release(&other_bytes); - Py_INCREF(res); - return res; -} - -#if PY_MAJOR_VERSION >= 3 -/* pfffffffffffff pages of copy-paste from listobject.c */ - -/* pfffffffffffff#2: the PySlice_GetIndicesEx() *macro* should not - be called, because C extension modules compiled with it differ - on ABI between 3.6.0, 3.6.1 and 3.6.2. */ -#if PY_VERSION_HEX < 0x03070000 && defined(PySlice_GetIndicesEx) && !defined(PYPY_VERSION) -#undef PySlice_GetIndicesEx -#endif - -static PyObject *mb_subscript(MiniBufferObj *self, PyObject *item) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i; - i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return NULL; - if (i < 0) - i += self->mb_size; - return mb_item(self, i); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx(item, self->mb_size, - &start, &stop, &step, &slicelength) < 0) - return NULL; - - if (step == 1) - return mb_slice(self, start, stop); - else { - PyErr_SetString(PyExc_TypeError, - "buffer doesn't support slicing with step != 1"); - return NULL; - } - } - else { - PyErr_Format(PyExc_TypeError, - "buffer indices must be integers, not %.200s", - item->ob_type->tp_name); - return NULL; - } -} -static int -mb_ass_subscript(MiniBufferObj* self, PyObject* item, PyObject* value) -{ - if (PyIndex_Check(item)) { - Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return -1; - if (i < 0) - i += self->mb_size; - return mb_ass_item(self, i, value); - } - else if (PySlice_Check(item)) { - Py_ssize_t start, stop, step, slicelength; - - if (PySlice_GetIndicesEx(item, self->mb_size, - &start, &stop, &step, &slicelength) < 0) { - return -1; - } - - if (step == 1) - return mb_ass_slice(self, start, stop, value); - else { - PyErr_SetString(PyExc_TypeError, - "buffer doesn't support slicing with step != 1"); - return -1; - } - } - else { - PyErr_Format(PyExc_TypeError, - "buffer indices must be integers, not %.200s", - item->ob_type->tp_name); - return -1; - } -} - -static PyMappingMethods mb_as_mapping = { - (lenfunc)mb_length, /*mp_length*/ - (binaryfunc)mb_subscript, /*mp_subscript*/ - (objobjargproc)mb_ass_subscript, /*mp_ass_subscript*/ -}; -#endif - -#if PY_MAJOR_VERSION >= 3 -# define MINIBUF_TPFLAGS 0 -#else -# define MINIBUF_TPFLAGS (Py_TPFLAGS_HAVE_GETCHARBUFFER | Py_TPFLAGS_HAVE_NEWBUFFER) -#endif - -PyDoc_STRVAR(ffi_buffer_doc, -"ffi.buffer(cdata[, byte_size]):\n" -"Return a read-write buffer object that references the raw C data\n" -"pointed to by the given 'cdata'. The 'cdata' must be a pointer or an\n" -"array. Can be passed to functions expecting a buffer, or directly\n" -"manipulated with:\n" -"\n" -" buf[:] get a copy of it in a regular string, or\n" -" buf[idx] as a single character\n" -" buf[:] = ...\n" -" buf[idx] = ... change the content"); - -static PyObject * /* forward, implemented in _cffi_backend.c */ -b_buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds); - - -static PyTypeObject MiniBuffer_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_cffi_backend.buffer", - sizeof(MiniBufferObj), - 0, - (destructor)mb_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - 0, /* tp_repr */ - 0, /* tp_as_number */ - &mb_as_sequence, /* tp_as_sequence */ -#if PY_MAJOR_VERSION < 3 - 0, /* tp_as_mapping */ -#else - &mb_as_mapping, /* tp_as_mapping */ -#endif - 0, /* tp_hash */ - 0, /* tp_call */ -#if PY_MAJOR_VERSION < 3 - (reprfunc)mb_str, /* tp_str */ -#else - 0, /* tp_str */ -#endif - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - &mb_as_buffer, /* tp_as_buffer */ - (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - MINIBUF_TPFLAGS), /* tp_flags */ - ffi_buffer_doc, /* tp_doc */ - (traverseproc)mb_traverse, /* tp_traverse */ - (inquiry)mb_clear, /* tp_clear */ - (richcmpfunc)mb_richcompare, /* tp_richcompare */ - offsetof(MiniBufferObj, mb_weakreflist), /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - b_buffer_new, /* tp_new */ - 0, /* tp_free */ -}; - -static PyObject *minibuffer_new(char *data, Py_ssize_t size, - PyObject *keepalive) -{ - MiniBufferObj *ob = PyObject_GC_New(MiniBufferObj, &MiniBuffer_Type); - if (ob != NULL) { - ob->mb_data = data; - ob->mb_size = size; - ob->mb_keepalive = keepalive; Py_INCREF(keepalive); - ob->mb_weakreflist = NULL; - PyObject_GC_Track(ob); - } - return (PyObject *)ob; -} |