/* -*-c-*-
- *
- * $Id$
*
* Byte strings
*
* (c) 2004 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.
PyTypeObject *bytestring_pytype;
-PyObject *bytestring_pywrap(const void *p, size_t n)
+static PyObject *dowrap(PyTypeObject *ty, const void *p, size_t n)
{
- PyStringObject *x = PyObject_NewVar(PyStringObject, bytestring_pytype, 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
-#ifdef INTERN_STRINGS
- x->ob_sinterned = NULL;
-#endif
+ x->ob_sstate = SSTATE_NOT_INTERNED;
return ((PyObject *)x);
}
+PyObject *bytestring_pywrap(const void *p, size_t n)
+ { return (dowrap(bytestring_pytype, p, n)); }
+
PyObject *bytestring_pywrapbuf(buf *b)
- { return bytestring_pywrap(BCUR(b), BLEFT(b)); }
+ { return (dowrap(bytestring_pytype, BCUR(b), BLEFT(b))); }
+
+static PyObject *bytestring_pynew(PyTypeObject *ty,
+ PyObject *arg, PyObject *kw)
+{
+ const char *p;
+ 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) || \
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; \
static PyBufferProcs bytestring_pybuffer;
static PyTypeObject bytestring_pytype_skel = {
- PyObject_HEAD_INIT(&PyType_Type) 0, /* Header */
- "catacomb.ByteString", /* @tp_name@ */
+ PyObject_HEAD_INIT(0) 0, /* Header */
+ "ByteString", /* @tp_name@ */
0, /* @tp_basicsize@ */
0, /* @tp_itemsize@ */
0, /* @tp_traverse@ */
0, /* @tp_clear@ */
- 0, /* @tp_richcompare@ */
+ bytestring_pyrichcompare, /* @tp_richcompare@ */
0, /* @tp_weaklistoffset@ */
0, /* @tp_iter@ */
- 0, /* @tp_iternexr@ */
+ 0, /* @tp_iternext@ */
0, /* @tp_methods@ */
0, /* @tp_members@ */
0, /* @tp_getset@ */
0, /* @tp_dictoffset@ */
0, /* @tp_init@ */
PyType_GenericAlloc, /* @tp_alloc@ */
- 0, /* @tp_new@ */
- _PyObject_Del, /* @tp_free@ */
+ bytestring_pynew, /* @tp_new@ */
+ 0, /* @tp_free@ */
0 /* @tp_is_gc@ */
};
/*----- 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)