#include "catacomb-python.h"
-/*----- Data structures ---------------------------------------------------*/
-
-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 --------------------------------------------------------*/
-
-static PyObject *buferr;
-
-#define BUFERR() do { PyErr_SetNone(buferr); goto end; } while (0)
-
/*----- Read buffers ------------------------------------------------------*/
+PyTypeObject *rbuf_pytype;
+
static PyObject *rbuf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
{
- char *p, *q;
- int n;
+ struct bin in;
+ void *q;
buf_pyobj *me = 0;
- static char *kwlist[] = { "data", 0 };
+ static const char *const kwlist[] = { "data", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &p, &n))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &in))
goto end;
- q = xmalloc(n);
- memcpy(q, p, n);
+ q = xmalloc(in.sz);
+ memcpy(q, in.p, in.sz);
me = (buf_pyobj *)ty->tp_alloc(ty, 0);
- me->sub = 0;
- buf_init(&me->b, q, n);
+ me->sub = 0; me->lk = 0;
+ buf_init(&me->b, q, in.sz);
end:
return ((PyObject *)me);
}
static void buf_pydealloc(PyObject *me)
{
- if (BUF_SUB(me))
- Py_DECREF(BUF_SUB(me));
- else
- xfree(BBASE(BUF_B(me)));
+ assert(!BUF_LK(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 = BCUR(BUF_B(me)); return (BLEFT(BUF_B(me))); }
+#ifdef PY3
+ static int rbuf_pygetbuf(PyObject *me, Py_buffer *vw, int f)
+ {
+ buf *b = BUF_B(me);
+ return (PyBuffer_FillInfo(vw, me, BCUR(b), BLEFT(b), 1, f));
+ }
+#else
+ static Py_ssize_t rbuf_pysegcount(PyObject *me, Py_ssize_t *nn)
+ { if (nn) *nn = BSZ(BUF_B(me)); return (1); }
+ 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))); }
+#endif
static PyObject *rbmeth_skip(PyObject *me, PyObject *arg)
{
size_t n;
if (!PyArg_ParseTuple(arg, "O&:skip", convszt, &n)) goto end;
- if (!buf_get(BUF_B(me), n)) BUFERR();
+ if (!buf_get(BUF_B(me), n)) BUFERR("buffer exhausted");
RETURN_ME;
end:
return (0);
size_t n;
if (!PyArg_ParseTuple(arg, "O&:get", convszt, &n)) goto end;
- if ((p = buf_get(BUF_B(me), n)) == 0) BUFERR();
+ if ((p = buf_get(BUF_B(me), n)) == 0) BUFERR("buffer exhausted");
return (bytestring_pywrap(p, n));
end:
return (0);
}
#define RBMETH_GETU_(n, W, w) \
- static PyObject *rbmeth_getu##w(PyObject *me, PyObject *arg) \
+ static PyObject *rbmeth_getu##w(PyObject *me) \
{ \
uint##n x; \
- if (!PyArg_ParseTuple(arg, ":getu" #w)) goto end; \
- if (buf_getu##w(BUF_B(me), &x)) BUFERR(); \
- return (getulong(x)); \
+ if (buf_getu##w(BUF_B(me), &x)) BUFERR("buffer exhausted"); \
+ if (MASK##W <= ULONG_MAX) return (getulong(x)); \
+ else { kludge64 y; ASSIGN64(y, x); return (getk64(y)); } \
end: \
return (0); \
}
DOUINTCONV(RBMETH_GETU_)
#define RBMETH_GETBLK_(n, W, w) \
- static PyObject *rbmeth_getblk##w(PyObject *me, PyObject *arg) \
+ static PyObject *rbmeth_getblk##w(PyObject *me) \
{ \
size_t sz; \
char *q; \
- if (!PyArg_ParseTuple(arg, ":getblk" #w)) goto end; \
- if ((q = buf_getmem##w(BUF_B(me), &sz)) == 0) BUFERR(); \
+ if ((q = buf_getmem##w(BUF_B(me), &sz)) == 0) \
+ BUFERR("buffer exhausted"); \
return (bytestring_pywrap(q, sz)); \
end: \
return (0); \
BUF_DOSUFFIXES(RBMETH_GETBLK_)
#define RBMETH_GETBUF_(n, W, w) \
- static PyObject *rbmeth_getbuf##w(PyObject *me, PyObject *arg) \
+ static PyObject *rbmeth_getbuf##w(PyObject *me) \
{ \
buf_pyobj *b; \
buf bb; \
- if (!PyArg_ParseTuple(arg, ":getbuf" #w)) goto end; \
- if (buf_getbuf##w(BUF_B(me), &bb)) BUFERR(); \
+ if (buf_getbuf##w(BUF_B(me), &bb)) BUFERR("buffer exhausted"); \
b = PyObject_NEW(buf_pyobj, rbuf_pytype); \
b->b = bb; \
b->sub = me; \
+ b->lk = 0; \
Py_INCREF(me); \
return ((PyObject *)b); \
end: \
}
BUF_DOSUFFIXES(RBMETH_GETBUF_)
-static PyObject *rbmeth_getmp(PyObject *me, PyObject *arg)
+static PyObject *rbmeth_getmp(PyObject *me)
{
mp *x;
- if (!PyArg_ParseTuple(arg, ":getmp")) goto end;
- if ((x = buf_getmp(BUF_B(me))) == 0) BUFERR();
+ if ((x = buf_getmp(BUF_B(me))) == 0) BUFERR("buffer exhausted");
return (mp_pywrap(x));
end:
return (0);
}
-static PyObject *rbmeth_getgf(PyObject *me, PyObject *arg)
+static PyObject *rbmeth_getgf(PyObject *me)
{
mp *x;
- if (!PyArg_ParseTuple(arg, ":getgf")) goto end;
- if ((x = buf_getmp(BUF_B(me))) == 0) BUFERR();
+ if ((x = buf_getmp(BUF_B(me))) == 0) BUFERR("buffer exhausted");
return (gf_pywrap(x));
end:
return (0);
static PyObject *rbmeth_getecpt(PyObject *me, PyObject *arg, PyObject *kw)
{
PyObject *cobj = Py_None;
- static char *kwlist[] = { "curve", 0 };
+ static const char *const kwlist[] = { "curve", 0 };
ec pt = EC_INIT;
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O:getecpt", kwlist, &cobj))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O:getecpt", KWLIST, &cobj))
goto end;
if (cobj == Py_None) cobj = (PyObject *)ecpt_pytype;
if (!PyType_Check(cobj) ||
!PyType_IsSubtype((PyTypeObject *)cobj, ecpt_pytype))
TYERR("expected elliptic curve type");
- if (buf_getec(BUF_B(me), &pt)) BUFERR();
+ if (buf_getec(BUF_B(me), &pt)) BUFERR("buffer exhausted");
return (ecpt_pywrapout(cobj, &pt));
end:
return (0);
static PyObject *rbmeth_getecptraw(PyObject *me, PyObject *arg)
{
- PyTypeObject *cobj = ecpt_pytype;
+ PyObject *cobj;
ec pt = EC_INIT;
+ PyObject *rc = 0;
if (!PyArg_ParseTuple(arg, "O!:getecptraw", eccurve_pytype, &cobj))
goto end;
- if (ec_getraw(ECCURVE_C(cobj), BUF_B(me), &pt)) BUFERR();
- return (ecpt_pywrapout(cobj, &pt));
+ if (ec_getraw(ECCURVE_C(cobj), BUF_B(me), &pt)) BUFERR("buffer exhausted");
+ rc = ecpt_pywrapout(cobj, &pt);
end:
- return (0);
+ return (rc);
+}
+
+static PyObject *rbmeth_os2ecp(PyObject *me, PyObject *arg, PyObject *kw)
+{
+ PyObject *cobj;
+ ec pt = EC_INIT;
+ unsigned f = EC_XONLY | EC_LSB | EC_SORT | EC_EXPLY;
+ PyObject *rc = 0;
+ static const char *const kwlist[] = { "curve", "flags", 0 };
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O&:os2ecp", KWLIST,
+ eccurve_pytype, &cobj, convuint, &f))
+ goto end;
+ if (ec_os2ecp(ECCURVE_C(cobj), f, BUF_B(me), &pt)) VALERR("bad point");
+ rc = ecpt_pywrapout(cobj, &pt);
+end:
+ return (rc);
}
static PyObject *rbmeth_getge(PyObject *me, PyObject *arg)
ge *x = 0;
if (!PyArg_ParseTuple(arg, "O!:getge", group_pytype, &gobj)) goto end;
x = G_CREATE(GROUP_G(gobj));
- if (G_FROMBUF(GROUP_G(gobj), BUF_B(me), x)) BUFERR();
+ if (G_FROMBUF(GROUP_G(gobj), BUF_B(me), x)) BUFERR("buffer exhausted");
return (ge_pywrap(gobj, x));
end:
if (x) G_DESTROY(GROUP_G(gobj), x);
ge *x = 0;
if (!PyArg_ParseTuple(arg, "O!:getgeraw", group_pytype, &gobj)) goto end;
x = G_CREATE(GROUP_G(gobj));
- if (G_FROMRAW(GROUP_G(gobj), BUF_B(me), x)) BUFERR();
+ if (G_FROMRAW(GROUP_G(gobj), BUF_B(me), x)) BUFERR("buffer exhausted");
return (ge_pywrap(gobj, x));
end:
if (x) G_DESTROY(GROUP_G(gobj), x);
return (-1);
}
-static PyGetSetDef rbuf_pygetset[] = {
+static const 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")
+ GET (size, "RBUF.size -> SIZE")
+ GET (left, "RBUF.left -> REMAINDER")
+ GET (endp, "RBUF.endp -> BOOL")
+ GETSET(offset, "RBUF.offset -> OFFSET")
#undef GETSETNAME
{ 0 }
};
-static PyMethodDef rbuf_pymethods[] = {
+static const PyMethodDef rbuf_pymethods[] = {
#define METHNAME(func) rbmeth_##func
- METH (skip, "RBUF.skip(N)")
- METH (get, "RBUF.get(N) -> BYTES")
+ METH (skip, "RBUF.skip(N)")
+ METH (get, "RBUF.get(N) -> BYTES")
#define RBMETH_DECL_GETU_(n, W, w) \
- METH(getu##w, "RBUF.getu" #w "() -> INT")
+ NAMETH(getu##w, "RBUF.getu" #w "() -> INT")
DOUINTCONV(RBMETH_DECL_GETU_)
#define RBMETH_DECL_GETBLK_(n, W, w) \
- METH(getblk##w, "RBUF.getblk" #w "() -> INT")
+ NAMETH(getblk##w, "RBUF.getblk" #w "() -> BYTES")
BUF_DOSUFFIXES(RBMETH_DECL_GETBLK_)
#define RBMETH_DECL_GETBUF_(n, W, w) \
- METH(getbuf##w, "RBUF.getbuf" #w "() -> INT")
+ NAMETH(getbuf##w, "RBUF.getbuf" #w "() -> RBUF'")
BUF_DOSUFFIXES(RBMETH_DECL_GETBUF_)
- METH (getmp, "RBUF.getmp() -> X")
- METH (getgf, "RBUF.getgf() -> X")
- KWMETH(getecpt, "RBUF.getecpt(curve = None) -> P")
- METH (getecptraw, "RBUF.getecptraw(CURVE) -> P")
- METH (getge, "RBUF.getge(GROUP) -> X")
- METH (getgeraw, "RBUF.getgeraw(GROUP) -> X")
+ NAMETH(getmp, "RBUF.getmp() -> X")
+ NAMETH(getgf, "RBUF.getgf() -> X")
+ KWMETH(getecpt, "RBUF.getecpt([curve = None]) -> P")
+ METH (getecptraw, "RBUF.getecptraw(CURVE) -> P")
+ KWMETH(os2ecp, "RBUF.os2ecp(CURVE, [flags = ...]) -> P")
+ METH (getge, "RBUF.getge(GROUP) -> X")
+ METH (getgeraw, "RBUF.getgeraw(GROUP) -> X")
#undef METHNAME
{ 0 }
};
-static PyBufferProcs rbuf_pybuffer = {
+static const PyBufferProcs rbuf_pybuffer = {
+#ifdef PY3
+ rbuf_pygetbuf, /* @bf_getbuffer@ */
+ 0, /* @bf_releasebuffer@ */
+#else
rbuf_pyreadbuf, /* @bf_getreadbuffer@ */
0, /* @bf_getwritebuffer@ */
rbuf_pysegcount, /* @bf_getsegcount@ */
0 /* @bf_getcharbuffer@ */
+#endif
};
-static PyTypeObject rbuf_pytype_skel = {
- PyObject_HEAD_INIT(0) 0, /* Header */
- "catacomb.ReadBuffer", /* @tp_name@ */
+static const PyTypeObject rbuf_pytype_skel = {
+ PyVarObject_HEAD_INIT(0, 0) /* Header */
+ "ReadBuffer", /* @tp_name@ */
sizeof(buf_pyobj), /* @tp_basicsize@ */
0, /* @tp_itemsize@ */
0, /* @tp_str@ */
0, /* @tp_getattro@ */
0, /* @tp_setattro@ */
- &rbuf_pybuffer, /* @tp_as_buffer@ */
+ PYBUFFER(rbuf), /* @tp_as_buffer@ */
Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
Py_TPFLAGS_BASETYPE,
/* @tp_doc@ */
- "A read buffer.",
+ "ReadBuffer(STR): a read buffer.",
0, /* @tp_traverse@ */
0, /* @tp_clear@ */
0, /* @tp_weaklistoffset@ */
0, /* @tp_iter@ */
0, /* @tp_iternext@ */
- rbuf_pymethods, /* @tp_methods@ */
+ PYMETHODS(rbuf), /* @tp_methods@ */
0, /* @tp_members@ */
- rbuf_pygetset, /* @tp_getset@ */
+ PYGETSET(rbuf), /* @tp_getset@ */
0, /* @tp_base@ */
0, /* @tp_dict@ */
0, /* @tp_descr_get@ */
/*----- Write buffers -----------------------------------------------------*/
-static void ensure(PyObject *me, size_t n)
+PyTypeObject *wbuf_pytype;
+
+int ensurebuf(PyObject *me, size_t n)
{
buf *b = BUF_B(me);
+ size_t nn = BSZ(b);
+ octet *p;
+ size_t want = BLEN(b) + n;
- if (BLEFT(b) < n) {
- size_t nn = BSZ(b);
- octet *p;
- size_t want = BLEN(b) + n;
+ if (BLEFT(b) >= n)
+ return (0);
+ else if (BUF_LK(me))
+ BUFERR("buffer locked");
+ else {
while (nn < want) nn <<= 1;
p = xrealloc(BBASE(b), nn, BSZ(b));
BCUR(b) = p + BLEN(b);
BLIM(b) = p + nn;
BBASE(b) = p;
+ return (0);
}
+end:
+ return (-1);
}
static PyObject *wbuf_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
char *p;
size_t n = 64;
buf_pyobj *me = 0;
- static char *kwlist[] = { "size", 0 };
+ static const char *const kwlist[] = { "size", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:new", kwlist,
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "|O&:new", KWLIST,
convszt, &n))
goto end;
me = (buf_pyobj *)ty->tp_alloc(ty, 0);
p = xmalloc(n);
- me->sub = 0;
+ me->sub = 0; me->lk = 0;
buf_init(&me->b, p, n);
end:
return ((PyObject *)me);
}
-static int wbuf_pysegcount(PyObject *me, int *nn)
- { if (nn) *nn = BLEN(BUF_B(me)); return (1); }
-
-static int wbuf_pyreadbuf(PyObject *me, int seg, void **q)
- { assert(seg == 0); *q = BBASE(BUF_B(me)); return (BLEN(BUF_B(me))); }
+#ifdef PY3
+ static int wbuf_pygetbuf(PyObject *me, Py_buffer *vw, int f)
+ {
+ buf *b = BUF_B(me);
+ if (PyBuffer_FillInfo(vw, me, BBASE(b), BLEN(b), 0, f)) return (-1);
+ BUF_LK(me)++; return (0);
+ }
+ static void wbuf_pyrlsbuf(PyObject *me, Py_buffer *vw)
+ { BUF_LK(me)--; }
+#else
+ static Py_ssize_t wbuf_pysegcount(PyObject *me, Py_ssize_t *nn)
+ { if (nn) *nn = BLEN(BUF_B(me)); return (1); }
+ 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))); }
+#endif
static PyObject *wbmeth_zero(PyObject *me, PyObject *arg)
{
void *p;
size_t n;
if (!PyArg_ParseTuple(arg, "O&:zero", convszt, &n)) return (0);
- ensure(me, n);
+ if (ensurebuf(me, n)) return (0);
p = buf_get(BUF_B(me), n); assert(p && BOK(BUF_B(me)));
memset(p, 0, n);
RETURN_ME;
static PyObject *wbmeth_put(PyObject *me, PyObject *arg)
{
- void *p;
- int 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)));
+ struct bin in;
+ if (!PyArg_ParseTuple(arg, "O&:put", convbin, &in)) return (0);
+ if (ensurebuf(me, in.sz)) return (0);
+ buf_put(BUF_B(me), in.p, in.sz); assert(BOK(BUF_B(me)));
RETURN_ME;
}
{ \
uint##n i; \
if (!PyArg_ParseTuple(arg, "O&:putu" #w, convu##n, &i)) return (0); \
- ensure(me, SZ_##n); \
+ if (ensurebuf(me, SZ_##n)) return (0); \
buf_putu##w(BUF_B(me), i); assert(BOK(BUF_B(me))); \
RETURN_ME; \
}
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); \
- ensure(me, sz + SZ_##n); \
- buf_putmem##w(BUF_B(me), p, sz); assert(BOK(BUF_B(me))); \
+ struct bin in; \
+ if (!PyArg_ParseTuple(arg, "O&:putblk" #w, convbin, &in)) goto end; \
+ if (MASK##W && in.sz > MASK##W) VALERR("too large"); \
+ if (ensurebuf(me, in.sz + SZ_##n)) return (0); \
+ buf_putmem##w(BUF_B(me), in.p, in.sz); assert(BOK(BUF_B(me))); \
RETURN_ME; \
+ end: \
+ return (0); \
}
BUF_DOSUFFIXES(WBMETH_PUTBLK_)
{
mp *x = 0;
if (!PyArg_ParseTuple(arg, "O&:putmp", convmp, &x)) return (0);
- ensure(me, mp_octets(x) + 2);
+ if (ensurebuf(me, mp_octets(x) + 2)) return (0);
buf_putmp(BUF_B(me), x); assert(BOK(BUF_B(me)));
RETURN_ME;
}
{
mp *x = 0;
if (!PyArg_ParseTuple(arg, "O&:putgf", convgf, &x)) return (0);
- ensure(me, mp_octets(x) + 2);
+ if (ensurebuf(me, mp_octets(x) + 2)) return (0);
buf_putmp(BUF_B(me), x); assert(BOK(BUF_B(me)));
MP_DROP(x);
RETURN_ME;
{
ec pt = EC_INIT;
if (!PyArg_ParseTuple(arg, "O&:putecpt", convecpt, &pt)) return (0);
- if (EC_ATINF(&pt)) ensure(me, 2);
- else ensure(me, 4 + mp_octets(pt.x) + mp_octets(pt.y));
+ if (ensurebuf(me, EC_ATINF(&pt) ? 2 :
+ 6 + mp_octets(pt.x) + mp_octets(pt.y)))
+ return (0);
buf_putec(BUF_B(me), &pt); assert(BOK(BUF_B(me)));
EC_DESTROY(&pt);
RETURN_ME;
static PyObject *wbmeth_putecptraw(PyObject *me, PyObject *arg)
{
PyObject *ptobj;
+ ec_curve *cc;
ec pt = EC_INIT;
if (!PyArg_ParseTuple(arg, "O!:putecptraw", ecptcurve_pytype, &ptobj))
return (0);
- EC_OUT(ECPT_C(ptobj), &pt, ECPT_P(ptobj));
- ensure(me, ECPT_C(ptobj)->f->noctets * 2 + 1);
- ec_putraw(ECPT_C(ptobj), BUF_B(me), &pt); assert(BOK(BUF_B(me)));
+ cc = ECPT_C(ptobj);
+ EC_OUT(cc, &pt, ECPT_P(ptobj));
+ if (ensurebuf(me, 2*cc->f->noctets + 1)) return (0);
+ ec_putraw(cc, BUF_B(me), &pt); assert(BOK(BUF_B(me)));
EC_DESTROY(&pt);
RETURN_ME;
}
+static PyObject *wbmeth_ec2osp(PyObject *me, PyObject *arg, PyObject *kw)
+{
+ PyTypeObject *ptobj;
+ ec_curve *cc;
+ ec pt = EC_INIT;
+ unsigned f = EC_EXPLY;
+ static const char *const kwlist[] = { "point", "flags", 0 };
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O!|O&:os2ecp", KWLIST,
+ ecptcurve_pytype, &ptobj, convuint, &f))
+ goto end;
+ cc = ECPT_C(ptobj);
+ EC_OUT(cc, &pt, ECPT_P(ptobj));
+ if (ensurebuf(me, 2*cc->f->noctets + 1)) return (0);
+ if (ec_ec2osp(cc, f, BUF_B(me), &pt)) VALERR("invalid flags");
+ RETURN_ME;
+end:
+ return (0);
+}
+
static PyObject *wbmeth_putge(PyObject *me, PyObject *arg)
{
PyObject *geobj;
if (!PyArg_ParseTuple(arg, "O!:putge", ge_pytype, &geobj)) return (0);
- ensure(me, GE_G(geobj)->noctets);
+ if (ensurebuf(me, GE_G(geobj)->noctets)) return (0);
G_TOBUF(GE_G(geobj), BUF_B(me), GE_X(geobj)); assert(BOK(BUF_B(me)));
RETURN_ME;
}
{
PyObject *geobj;
if (!PyArg_ParseTuple(arg, "O!:putgeraw", ge_pytype, &geobj)) return (0);
- ensure(me, GE_G(geobj)->noctets);
+ if (ensurebuf(me, GE_G(geobj)->noctets)) return (0);
G_TORAW(GE_G(geobj), BUF_B(me), GE_X(geobj)); assert(BOK(BUF_B(me)));
RETURN_ME;
}
static PyObject *wbget_size(PyObject *me, void *hunoz)
{ return (PyInt_FromLong(BLEN(BUF_B(me)))); }
-static PyGetSetDef wbuf_pygetset[] = {
+static PyObject *wbget_contents(PyObject *me, void *hunoz)
+ { return (bytestring_pywrap(BBASE(BUF_B(me)), BLEN(BUF_B(me)))); }
+
+static const PyGetSetDef wbuf_pygetset[] = {
#define GETSETNAME(op, name) wb##op##_##name
- GET (size, "WBUF.size -> SIZE")
+ GET (size, "WBUF.size -> SIZE")
+ GET (contents, "WBUF.contents -> STR")
#undef GETSETNAME
{ 0 }
};
-static PyMethodDef wbuf_pymethods[] = {
+static const PyMethodDef wbuf_pymethods[] = {
#define METHNAME(func) wbmeth_##func
- METH (zero, "WBUF.zero(N)")
- METH (put, "WBUF.put(BYTES)")
+ METH (zero, "WBUF.zero(N)")
+ METH (put, "WBUF.put(BYTES)")
#define WBMETH_DECL_PUTU_(n, W, w) \
- METH(putu##w, "WBUF.putu" #w "(INT)")
+ METH(putu##w, "WBUF.putu" #w "(INT)")
DOUINTCONV(WBMETH_DECL_PUTU_)
#define WBMETH_DECL_PUTBLK_(n, W, w) \
- METH(putblk##w, "WBUF.putblk" #w "(BYTES)")
+ METH(putblk##w, "WBUF.putblk" #w "(BYTES)")
BUF_DOSUFFIXES(WBMETH_DECL_PUTBLK_)
- METH (putmp, "WBUF.putmp(X)")
- METH (putgf, "WBUF.putgf(X)")
- KWMETH(putecpt, "WBUF.putecpt(P)")
- METH (putecptraw, "WBUF.putecptraw(P)")
- METH (putge, "WBUF.putge(X)")
- METH (putgeraw, "WBUF.putgeraw(X)")
+ METH (putmp, "WBUF.putmp(X)")
+ METH (putgf, "WBUF.putgf(X)")
+ METH (putecpt, "WBUF.putecpt(P)")
+ METH (putecptraw, "WBUF.putecptraw(P)")
+ KWMETH(ec2osp, "WBUF.ec2osp(P, [flags = EC_EXPLY])")
+ METH (putge, "WBUF.putge(X)")
+ METH (putgeraw, "WBUF.putgeraw(X)")
#undef METHNAME
{ 0 }
};
-static PyBufferProcs wbuf_pybuffer = {
+static const PyBufferProcs wbuf_pybuffer = {
+#ifdef PY3
+ wbuf_pygetbuf, /* @bf_getbuffer@ */
+ wbuf_pyrlsbuf /* @bf_releasebuffer@ */
+#else
wbuf_pyreadbuf, /* @bf_getreadbuffer@ */
0, /* @bf_getwritebuffer@ */
wbuf_pysegcount, /* @bf_getsegcount@ */
0 /* @bf_getcharbuffer@ */
+#endif
};
-static PyTypeObject wbuf_pytype_skel = {
- PyObject_HEAD_INIT(0) 0, /* Header */
- "catacomb.WriteBuffer", /* @tp_name@ */
+static const PyTypeObject wbuf_pytype_skel = {
+ PyVarObject_HEAD_INIT(0, 0) /* Header */
+ "WriteBuffer", /* @tp_name@ */
sizeof(buf_pyobj), /* @tp_basicsize@ */
0, /* @tp_itemsize@ */
0, /* @tp_str@ */
0, /* @tp_getattro@ */
0, /* @tp_setattro@ */
- &wbuf_pybuffer, /* @tp_as_buffer@ */
+ PYBUFFER(wbuf), /* @tp_as_buffer@ */
Py_TPFLAGS_DEFAULT | /* @tp_flags@ */
Py_TPFLAGS_BASETYPE,
/* @tp_doc@ */
- "A write buffer.",
+ "WriteBuffer([size = ?]): a write buffer.",
0, /* @tp_traverse@ */
0, /* @tp_clear@ */
0, /* @tp_weaklistoffset@ */
0, /* @tp_iter@ */
0, /* @tp_iternext@ */
- wbuf_pymethods, /* @tp_methods@ */
+ PYMETHODS(wbuf), /* @tp_methods@ */
0, /* @tp_members@ */
- wbuf_pygetset, /* @tp_getset@ */
+ PYGETSET(wbuf), /* @tp_getset@ */
0, /* @tp_base@ */
0, /* @tp_dict@ */
0, /* @tp_descr_get@ */
/*----- Initialization ----------------------------------------------------*/
+PyObject *buferr;
+
void buffer_pyinit(void)
{
INITTYPE(rbuf, root);