From: mdw Date: Tue, 27 Sep 2005 11:27:03 +0000 (+0000) Subject: Buffer sharing and subbuffers. X-Git-Tag: 1.0.1~45 X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/commitdiff_plain/0463996f64aa7cde2c3d033f81d43963f54c2bba Buffer sharing and subbuffers. --- diff --git a/buffer.c b/buffer.c index 8dc885a..ee0dd40 100644 --- a/buffer.c +++ b/buffer.c @@ -35,12 +35,14 @@ typedef struct buf_pyobj { PyObject_HEAD buf b; + PyObject *sub; } buf_pyobj; static PyTypeObject *rbuf_pytype, *wbuf_pytype; #define RBUF_PYCHECK(o) PyObject_TypeCheck((o), rbuf_pytype) #define WBUF_PYCHECK(o) PyObject_TypeCheck((o), wbuf_pytype) #define BUF_B(o) (&((buf_pyobj *)(o))->b) +#define BUF_SUB(o) (((buf_pyobj *)(o))->sub) /*----- Exceptions --------------------------------------------------------*/ @@ -59,16 +61,23 @@ static PyObject *rbuf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &p, &n)) goto end; - me = (buf_pyobj *)ty->tp_alloc(ty, 0); q = xmalloc(n); memcpy(q, p, n); + me = (buf_pyobj *)ty->tp_alloc(ty, 0); + me->sub = 0; buf_init(&me->b, q, n); end: return ((PyObject *)me); } static void buf_pydealloc(PyObject *me) - { xfree(BBASE(BUF_B(me))); FREEOBJ(me); } +{ + if (BUF_SUB(me)) + Py_DECREF(BUF_SUB(me)); + else + xfree(BBASE(BUF_B(me))); + FREEOBJ(me); +} static int rbuf_pysegcount(PyObject *me, int *nn) { if (nn) *nn = BSZ(BUF_B(me)); return (1); } @@ -124,6 +133,23 @@ DOUINTCONV(RBMETH_GETU_) } BUF_DOSUFFIXES(RBMETH_GETBLK_) +#define RBMETH_GETBUF_(n, W, w) \ + static PyObject *rbmeth_getbuf##w(PyObject *me, PyObject *arg) \ + { \ + buf_pyobj *b; \ + buf bb; \ + if (!PyArg_ParseTuple(arg, ":getbuf" #w)) goto end; \ + if (buf_getbuf##w(BUF_B(me), &bb)) BUFERR(); \ + b = PyObject_NEW(buf_pyobj, rbuf_pytype); \ + b->b = bb; \ + b->sub = me; \ + Py_INCREF(me); \ + return ((PyObject *)b); \ + end: \ + return (0); \ + } +BUF_DOSUFFIXES(RBMETH_GETBUF_) + static PyObject *rbmeth_getmp(PyObject *me, PyObject *arg) { mp *x; @@ -205,12 +231,25 @@ static PyObject *rbget_left(PyObject *me, void *hunoz) { return (PyInt_FromLong(BLEFT(BUF_B(me)))); } static PyObject *rbget_endp(PyObject *me, void *hunoz) { return (getbool(!BLEFT(BUF_B(me)))); } +static PyObject *rbget_offset(PyObject *me, void *hunoz) + { return (PyInt_FromLong(BLEN(BUF_B(me)))); } +static int rbset_offset(PyObject *me, PyObject *x, void *hunoz) +{ + size_t n; + if (!convszt(x, &n)) goto end; + if (n > BSZ(BUF_B(me))) VALERR("out of range"); + BCUR(BUF_B(me)) = BBASE(BUF_B(me)) + n; + return (0); +end: + return (-1); +} static PyGetSetDef rbuf_pygetset[] = { #define GETSETNAME(op, name) rb##op##_##name GET (size, "RBUF.size -> SIZE") GET (left, "RBUF.left -> REMAINDER") GET (endp, "RBUF.endp -> BOOL") + GETSET(offset, "RBUF.offset -> OFFSET") #undef GETSETNAME { 0 } }; @@ -225,6 +264,9 @@ static PyMethodDef rbuf_pymethods[] = { #define RBMETH_DECL_GETBLK_(n, W, w) \ METH(getblk##w, "RBUF.getblk" #w "() -> INT") BUF_DOSUFFIXES(RBMETH_DECL_GETBLK_) +#define RBMETH_DECL_GETBUF_(n, W, w) \ + METH(getbuf##w, "RBUF.getbuf" #w "() -> INT") + BUF_DOSUFFIXES(RBMETH_DECL_GETBUF_) METH (getmp, "RBUF.getmp() -> X") METH (getgf, "RBUF.getgf() -> X") KWMETH(getecpt, "RBUF.getecpt(curve = None) -> P") @@ -320,6 +362,7 @@ static PyObject *wbuf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) goto end; me = (buf_pyobj *)ty->tp_alloc(ty, 0); p = xmalloc(n); + me->sub = 0; buf_init(&me->b, p, n); end: return ((PyObject *)me);