chiark / gitweb /
catacomb/pwsafe.py: Split out the GDBM-specifics from StorageBackend.
[catacomb-python] / buffer.c
index 8dc885a39c5d130cdcdc0318a792173fdbb848b6..ea38e658fc0993a3cc2a50a29998b3f784c3ecdf 100644 (file)
--- 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.
  *
  * 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.
 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,22 +59,29 @@ 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); }
 
 static int rbuf_pyreadbuf(PyObject *me, int seg, void **q)
-  { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BSZ(BUF_B(me))); }
+  { assert(seg == 0); *q = BCUR(BUF_B(me)); return (BLEFT(BUF_B(me))); }
 
 static PyObject *rbmeth_skip(PyObject *me, PyObject *arg)
 {
@@ -105,7 +112,7 @@ end:
     uint##n x;                                                         \
     if (!PyArg_ParseTuple(arg, ":getu" #w)) goto end;                  \
     if (buf_getu##w(BUF_B(me), &x)) BUFERR();                          \
-    return (getu32(x));                                                        \
+    return (getulong(x));                                              \
   end:                                                                 \
     return (0);                                                                \
   }
@@ -124,6 +131,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 +184,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 +229,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 +263,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")
@@ -274,7 +315,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 +340,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,6 +361,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);
@@ -449,7 +491,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)")
@@ -506,7 +548,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@ */