X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~mdw/git/catacomb-python/blobdiff_plain/963a61481edc7a83698b18b518bf20cd93d268a6..278e43d0c27875a1355ebaf3bef6d0f5df739626:/bytestring.c diff --git a/bytestring.c b/bytestring.c index fac797c..2b74648 100644 --- a/bytestring.c +++ b/bytestring.c @@ -1,13 +1,11 @@ /* -*-c-*- - * - * $Id$ * * Byte strings * * (c) 2004 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. @@ -39,7 +37,7 @@ static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n) PyStringObject *x = (PyStringObject *)ty->tp_alloc(ty, n); if (p) memcpy(x->ob_sval, p, n); x->ob_sval[n] = 0; -#ifdef CACHE_HASH +#if defined(CACHE_HASH) || PY_VERSION_HEX >= 0x02030000 x->ob_shash = -1; #endif x->ob_sstate = SSTATE_NOT_INTERNED; @@ -56,19 +54,76 @@ static PyObject *bytestring_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) { const char *p; - int n; + Py_ssize_t n; static char *kwlist[] = { "data", 0 }; if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &p, &n)) return (0); return (dowrap(ty, p, n)); } +static PyObject *meth_ctstreq(PyObject *me, PyObject *arg) +{ + char *p, *q; + Py_ssize_t psz, qsz; + if (!PyArg_ParseTuple(arg, "s#s#:ctstreq", &p, &psz, &q, &qsz)) + goto end; + if (psz == qsz && ct_memeq(p, q, psz)) RETURN_TRUE; + else RETURN_FALSE; +end: + return (0); +} + +static PyObject *meth__ByteString_zero(PyObject *me, PyObject *arg) +{ + size_t sz; + PyObject *rc = 0; + if (!PyArg_ParseTuple(arg, "OO&:zero", &me, convszt, &sz)) goto end; + rc = bytestring_pywrap(0, sz); + memset(PyString_AS_STRING(rc), 0, sz); +end: + return (rc); +} + +static PyObject *bytestring_pyrichcompare(PyObject *me, + PyObject *you, int op) +{ + int b; + void *mystr, *yourstr; + Py_ssize_t mylen, yourlen, minlen; + + if (!PyString_Check(me) || !PyString_Check(you)) RETURN_NOTIMPL; + mystr = PyString_AS_STRING(me); mylen = PyString_GET_SIZE(me); + yourstr = PyString_AS_STRING(you); yourlen = PyString_GET_SIZE(you); + + switch (op) { + case Py_EQ: + b = mylen == yourlen && ct_memeq(mystr, yourstr, mylen); + break; + case Py_NE: + b = mylen != yourlen || !ct_memeq(mystr, yourstr, mylen); + break; + default: + minlen = mylen < yourlen ? mylen : yourlen; + b = memcmp(mystr, yourstr, minlen); + if (!b) b = mylen < yourlen ? -1 : mylen > yourlen ? +1 : 0; + switch (op) { + case Py_LT: b = b < 0; break; + case Py_LE: b = b <= 0; break; + case Py_GE: b = b >= 0; break; + case Py_GT: b = b > 0; break; + default: abort(); + } + } + if (b) RETURN_TRUE; + else RETURN_FALSE; +} + #define BINOP(name, op) \ static PyObject *bytestring_py##name(PyObject *x, PyObject *y) { \ const void *xv, *yv; \ const unsigned char *xp, *yp; \ unsigned char *zp; \ - int xsz, ysz; \ + Py_ssize_t xsz, ysz; \ int i; \ PyObject *rc = 0; \ if (PyObject_AsReadBuffer(x, &xv, &xsz) || \ @@ -90,7 +145,7 @@ BINOP(xor, ^) const void *xv; \ const unsigned char *xp; \ unsigned char *zp; \ - int xsz; \ + Py_ssize_t xsz; \ int i; \ PyObject *rc = 0; \ if (PyObject_AsReadBuffer(x, &xv, &xsz)) goto end; \ @@ -132,7 +187,7 @@ static PyBufferProcs bytestring_pybuffer; static PyTypeObject bytestring_pytype_skel = { PyObject_HEAD_INIT(0) 0, /* Header */ - "catacomb.ByteString", /* @tp_name@ */ + "ByteString", /* @tp_name@ */ 0, /* @tp_basicsize@ */ 0, /* @tp_itemsize@ */ @@ -160,7 +215,7 @@ static PyTypeObject bytestring_pytype_skel = { 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ - 0, /* @tp_richcompare@ */ + bytestring_pyrichcompare, /* @tp_richcompare@ */ 0, /* @tp_weaklistoffset@ */ 0, /* @tp_iter@ */ 0, /* @tp_iternext@ */ @@ -181,10 +236,19 @@ static PyTypeObject bytestring_pytype_skel = { /*----- Initialization ----------------------------------------------------*/ +static PyMethodDef methods[] = { +#define METHNAME(func) meth_##func + METH (ctstreq, "ctstreq(S, T) -> BOOL") + METH (_ByteString_zero, "zero(N) -> 0000...00") +#undef METHNAME + { 0 } +}; + #define string_pytype &PyString_Type void bytestring_pyinit(void) { INITTYPE(bytestring, string); + addmethods(methods); } void bytestring_pyinsert(PyObject *mod)