X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-python/blobdiff_plain/457b4e971a2795898c83a53ae4c27d6a893690d1..4d09d07e731d0454bf9f103ba486f06edcc6c2df:/bytestring.c diff --git a/bytestring.c b/bytestring.c index 4abb260..124ae9a 100644 --- a/bytestring.c +++ b/bytestring.c @@ -32,10 +32,12 @@ PyTypeObject *bytestring_pytype; -static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n) +static PyObject *empty, *bytev[256]; + +static PyObject *allocate(PyTypeObject *ty, size_t n) { - PyStringObject *x = (PyStringObject *)ty->tp_alloc(ty, n); - if (p) memcpy(x->ob_sval, p, n); + PyStringObject *x; + x = (PyStringObject *)ty->tp_alloc(ty, n); x->ob_sval[n] = 0; #if defined(CACHE_HASH) || PY_VERSION_HEX >= 0x02030000 x->ob_shash = -1; @@ -44,6 +46,27 @@ static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n) return ((PyObject *)x); } +static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n) +{ + PyObject *x; + int ch; + + if (p && ty == bytestring_pytype) { + if (!n) { + if (!empty) empty = allocate(ty, 0); + Py_INCREF(empty); return (empty); + } else if (n == 1 && (ch = *(unsigned char *)p) < sizeof(bytev)) { + if (!bytev[ch]) + { bytev[ch] = allocate(ty, 1); *PyString_AS_STRING(bytev[ch]) = ch; } + Py_INCREF(bytev[ch]); return (bytev[ch]); + } + } + + x = allocate(ty, n); + if (p) memcpy(PyString_AS_STRING(x), p, n); + return (x); +} + PyObject *bytestring_pywrap(const void *p, size_t n) { return (dowrap(bytestring_pytype, p, n)); } @@ -55,17 +78,17 @@ static PyObject *bytestring_pynew(PyTypeObject *ty, { const char *p; Py_ssize_t n; - static char *kwlist[] = { "data", 0 }; - if (!PyArg_ParseTupleAndKeywords(arg, kw, "s#:new", kwlist, &p, &n)) + static const char *const 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 *args) +static PyObject *meth_ctstreq(PyObject *me, PyObject *arg) { char *p, *q; Py_ssize_t psz, qsz; - if (!PyArg_ParseTuple(args, "s#s#:ctstreq", &p, &psz, &q, &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; @@ -73,6 +96,17 @@ 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) { @@ -200,7 +234,7 @@ static PyTypeObject bytestring_pytype_skel = { Py_TPFLAGS_BASETYPE, /* @tp_doc@ */ -"Byte string class.", +"ByteString(STR): byte string class.", 0, /* @tp_traverse@ */ 0, /* @tp_clear@ */ @@ -228,6 +262,7 @@ static PyTypeObject bytestring_pytype_skel = { static PyMethodDef methods[] = { #define METHNAME(func) meth_##func METH (ctstreq, "ctstreq(S, T) -> BOOL") + METH (_ByteString_zero, "zero(N) -> 0000...00") #undef METHNAME { 0 } };