X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/46e6ad89d596d0987f00440c77e42c36f7d347f7..1c6b925f0cf913ce3100c2ae3bcaed26a3f34bc1:/buffer.c?ds=sidebyside diff --git a/buffer.c b/buffer.c index 8dc885a..bd5e334 100644 --- a/buffer.c +++ b/buffer.c @@ -1,13 +1,11 @@ /* -*-c-*- * - * $Id$ - * * Reading and writing buffers of stuff * * (c) 2005 Straylight/Edgeware */ -/*----- Licensing notice --------------------------------------------------* +/*----- Licensing notice --------------------------------------------------* * * This file is part of the Python interface to Catacomb. * @@ -15,12 +13,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * Catacomb/Python is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with Catacomb/Python; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. @@ -35,12 +33,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 --------------------------------------------------------*/ @@ -53,28 +53,35 @@ static PyObject *buferr; static PyObject *rbuf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { char *p, *q; - int n; + Py_ssize_t n; buf_pyobj *me = 0; static char *kwlist[] = { "data", 0 }; 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) +static Py_ssize_t rbuf_pysegcount(PyObject *me, Py_ssize_t *nn) { if (nn) *nn = BSZ(BUF_B(me)); return (1); } -static int rbuf_pyreadbuf(PyObject *me, int seg, void **q) - { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BSZ(BUF_B(me))); } +static Py_ssize_t rbuf_pyreadbuf(PyObject *me, Py_ssize_t seg, void **q) + { assert(seg == 0); *q = BCUR(BUF_B(me)); return (BLEFT(BUF_B(me))); } static PyObject *rbmeth_skip(PyObject *me, PyObject *arg) { @@ -105,7 +112,8 @@ end: uint##n x; \ if (!PyArg_ParseTuple(arg, ":getu" #w)) goto end; \ if (buf_getu##w(BUF_B(me), &x)) BUFERR(); \ - return (getu32(x)); \ + if (MASK##W <= ULONG_MAX) return (getulong(x)); \ + else { kludge64 y; ASSIGN64(y, x); return (getk64(y)); } \ end: \ return (0); \ } @@ -124,6 +132,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; @@ -160,7 +185,7 @@ static PyObject *rbmeth_getecpt(PyObject *me, PyObject *arg, PyObject *kw) end: return (0); } - + static PyObject *rbmeth_getecptraw(PyObject *me, PyObject *arg) { PyTypeObject *cobj = ecpt_pytype; @@ -205,12 +230,26 @@ 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 (!x) NIERR("__del__"); + 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") @@ -244,7 +286,7 @@ static PyBufferProcs rbuf_pybuffer = { static PyTypeObject rbuf_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ReadBuffer", /* @tp_name@ */ + "ReadBuffer", /* @tp_name@ */ sizeof(buf_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -274,7 +316,7 @@ static PyTypeObject rbuf_pytype_skel = { 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ rbuf_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ rbuf_pygetset, /* @tp_getset@ */ @@ -299,7 +341,7 @@ static void ensure(PyObject *me, size_t n) if (BLEFT(b) < n) { size_t nn = BSZ(b); octet *p; - size_t want = BLEFT(b) + n; + size_t want = BLEN(b) + n; while (nn < want) nn <<= 1; p = xrealloc(BBASE(b), nn, BSZ(b)); BCUR(b) = p + BLEN(b); @@ -320,15 +362,16 @@ 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); } -static int wbuf_pysegcount(PyObject *me, int *nn) +static Py_ssize_t wbuf_pysegcount(PyObject *me, Py_ssize_t *nn) { if (nn) *nn = BLEN(BUF_B(me)); return (1); } -static int wbuf_pyreadbuf(PyObject *me, int seg, void **q) +static Py_ssize_t wbuf_pyreadbuf(PyObject *me, Py_ssize_t seg, void **q) { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BLEN(BUF_B(me))); } static PyObject *wbmeth_zero(PyObject *me, PyObject *arg) @@ -345,10 +388,10 @@ static PyObject *wbmeth_zero(PyObject *me, PyObject *arg) static PyObject *wbmeth_put(PyObject *me, PyObject *arg) { void *p; - int n; + Py_ssize_t n; if (!PyArg_ParseTuple(arg, "s#:put", &p, &n)) return (0); ensure(me, n); - buf_put(BUF_B(me), p, n); assert(BOK(BUF_B(m))); + buf_put(BUF_B(me), p, n); assert(BOK(BUF_B(me))); RETURN_ME; } @@ -363,16 +406,20 @@ static PyObject *wbmeth_put(PyObject *me, PyObject *arg) } DOUINTCONV(WBMETH_PUTU_) +#define MASKz 0 #define SZ_z 1 #define WBMETH_PUTBLK_(n, W, w) \ static PyObject *wbmeth_putblk##w(PyObject *me, PyObject *arg) \ { \ char *p; \ - int sz; \ - if (!PyArg_ParseTuple(arg, "s#:putblk" #w, &p, &sz)) return (0); \ + Py_ssize_t sz; \ + if (!PyArg_ParseTuple(arg, "s#:putblk" #w, &p, &sz)) goto end; \ + if (MASK##W && sz > MASK##W) VALERR("too large"); \ ensure(me, sz + SZ_##n); \ buf_putmem##w(BUF_B(me), p, sz); assert(BOK(BUF_B(me))); \ RETURN_ME; \ + end: \ + return (0); \ } BUF_DOSUFFIXES(WBMETH_PUTBLK_) @@ -449,7 +496,7 @@ static PyGetSetDef wbuf_pygetset[] = { static PyMethodDef wbuf_pymethods[] = { #define METHNAME(func) wbmeth_##func - METH (zero, "WBUF.skip(N)") + METH (zero, "WBUF.zero(N)") METH (put, "WBUF.put(BYTES)") #define WBMETH_DECL_PUTU_(n, W, w) \ METH(putu##w, "WBUF.putu" #w "(INT)") @@ -459,7 +506,7 @@ static PyMethodDef wbuf_pymethods[] = { BUF_DOSUFFIXES(WBMETH_DECL_PUTBLK_) METH (putmp, "WBUF.putmp(X)") METH (putgf, "WBUF.putgf(X)") - KWMETH(putecpt, "WBUF.putecpt(P)") + METH (putecpt, "WBUF.putecpt(P)") METH (putecptraw, "WBUF.putecptraw(P)") METH (putge, "WBUF.putge(X)") METH (putgeraw, "WBUF.putgeraw(X)") @@ -476,7 +523,7 @@ static PyBufferProcs wbuf_pybuffer = { static PyTypeObject wbuf_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.WriteBuffer", /* @tp_name@ */ + "WriteBuffer", /* @tp_name@ */ sizeof(buf_pyobj), /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -506,7 +553,7 @@ static PyTypeObject wbuf_pytype_skel = { 0, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ - 0, /* @tp_iternexr@ */ + 0, /* @tp_iternext@ */ wbuf_pymethods, /* @tp_methods@ */ 0, /* @tp_members@ */ wbuf_pygetset, /* @tp_getset@ */