static PyObject *allocate(PyTypeObject *ty, size_t n)
{
- PyStringObject *x;
- x = (PyStringObject *)ty->tp_alloc(ty, n);
+ BINOBJ *x;
+ x = (BINOBJ *)ty->tp_alloc(ty, n);
x->ob_sval[n] = 0;
#if defined(CACHE_HASH) || PY_VERSION_HEX >= 0x02030000
x->ob_shash = -1;
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; }
+ { bytev[ch] = allocate(ty, 1); *BIN_PTR(bytev[ch]) = ch; }
Py_INCREF(bytev[ch]); return (bytev[ch]);
}
}
x = allocate(ty, n);
- if (p) memcpy(PyString_AS_STRING(x), p, n);
+ if (p) memcpy(BIN_PTR(x), p, n);
return (x);
}
static PyObject *bytestring_pynew(PyTypeObject *ty,
PyObject *arg, PyObject *kw)
{
- const char *p;
- Py_ssize_t n;
+ struct bin in;
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))
return (0);
- return (dowrap(ty, p, n));
+ return (dowrap(ty, in.p, in.sz));
}
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))
+ struct bin s0, s1;
+ if (!PyArg_ParseTuple(arg, "O&O&:ctstreq", convbin, &s0 , convbin, &s1))
goto end;
- if (psz == qsz && ct_memeq(p, q, psz)) RETURN_TRUE;
+ if (s0.sz == s1.sz && ct_memeq(s0.p, s1.p, s0.sz)) RETURN_TRUE;
else RETURN_FALSE;
end:
return (0);
PyObject *rc = 0;
if (!PyArg_ParseTuple(arg, "O&:zero", convszt, &sz)) goto end;
rc = bytestring_pywrap(0, sz);
- memset(PyString_AS_STRING(rc), 0, sz);
+ memset(BIN_PTR(rc), 0, sz);
end:
return (rc);
}
static PyObject *bytestring_pyrichcompare(PyObject *me,
PyObject *you, int op)
{
+ struct bin s0, s1;
int b;
- void *mystr, *yourstr;
- Py_ssize_t mylen, yourlen, minlen;
+ Py_ssize_t 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);
+ s0.p = BIN_PTR(me); s0.sz = BIN_LEN(me);
+ if (!convbin(you, &s1)) { PyErr_Clear(); RETURN_NOTIMPL; }
switch (op) {
case Py_EQ:
- b = mylen == yourlen && ct_memeq(mystr, yourstr, mylen);
+ b = s0.sz == s1.sz && ct_memeq(s0.p, s1.p, s1.sz);
break;
case Py_NE:
- b = mylen != yourlen || !ct_memeq(mystr, yourstr, mylen);
+ b = s0.sz != s1.sz || !ct_memeq(s0.p, s1.p, s1.sz);
break;
default:
- minlen = mylen < yourlen ? mylen : yourlen;
- b = memcmp(mystr, yourstr, minlen);
- if (!b) b = mylen < yourlen ? -1 : mylen > yourlen ? +1 : 0;
+ minlen = s0.sz < s1.sz ? s0.sz : s1.sz;
+ b = memcmp(s0.p, s1.p, minlen);
+ if (!b) b = s0.sz < s1.sz ? -1 : s0.sz > s1.sz ? +1 : 0;
switch (op) {
case Py_LT: b = b < 0; break;
case Py_LE: b = b <= 0; break;
static PyObject *bytestring_pyconcat(PyObject *x, PyObject *y)
{
- const void *xv; Py_ssize_t xsz;
- const void *yv; Py_ssize_t ysz;
+ struct bin xx, yy;
PyObject *z = 0; char *zp; size_t zsz;
- if (PyObject_AsReadBuffer(x, &xv, &xsz) ||
- PyObject_AsReadBuffer(y, &yv, &ysz))
- goto end;
- zsz = (size_t)xsz + (size_t)ysz;
- if (xsz < 0 || ysz < 0 || zsz < xsz) VALERR("too long");
- z = bytestring_pywrap(0, zsz); zp = PyString_AS_STRING(z);
- memcpy(zp, xv, xsz); memcpy(zp + xsz, yv, ysz);
+ if (!convbin(x, &xx) || !convbin(y, &yy)) goto end;
+ zsz = (size_t)xx.sz + (size_t)yy.sz;
+ if (xx.sz < 0 || yy.sz < 0 || zsz < xx.sz) VALERR("too long");
+ z = bytestring_pywrap(0, zsz); zp = BIN_PTR(z);
+ memcpy(zp, xx.p, xx.sz); memcpy(zp + xx.sz, yy.p, yy.sz);
end:
return (z);
}
const unsigned char *xp; size_t xsz;
PyObject *z = 0; char *zp; size_t zsz;
- xp = (const unsigned char *)PyString_AS_STRING(me);
- xsz = PyString_GET_SIZE(me);
+ xp = (const unsigned char *)BIN_PTR(me);
+ xsz = BIN_LEN(me);
if (n < 0 || (n && xsz >= (size_t)-1/n)) VALERR("too long");
- zsz = n*xsz; z = bytestring_pywrap(0, zsz); zp = PyString_AS_STRING(z);
+ zsz = n*xsz; z = bytestring_pywrap(0, zsz); zp = BIN_PTR(z);
if (xsz == 1) memset(zp, *xp, zsz);
else while (zsz) { memcpy(zp, xp, xsz); zp += xsz; zsz -= xsz; }
end:
{
PyObject *rc = 0;
- if (i < 0 || i >= PyString_GET_SIZE(me)) IXERR("out of range");
- rc = bytestring_pywrap(PyString_AS_STRING(me) + i, 1);
+ if (i < 0 || i >= BIN_LEN(me)) IXERR("out of range");
+ rc = bytestring_pywrap(BIN_PTR(me) + i, 1);
end:
return (rc);
}
static PyObject *bytestring_pyslice(PyObject *me, Py_ssize_t i, Py_ssize_t j)
{
PyObject *rc = 0;
- size_t n = PyString_GET_SIZE(me);
+ size_t n = BIN_LEN(me);
if (i < 0) i = 0;
if (j < 0) j = 0;
if (j < i) i = j = 0;
if (i == 0 && j == n && Py_TYPE(me) == bytestring_pytype)
{ Py_INCREF(me); rc = me; goto end; }
- rc = bytestring_pywrap(PyString_AS_STRING(me) + i, j - i);
+ rc = bytestring_pywrap(BIN_PTR(me) + i, j - i);
end:
return (rc);
}
if (PyIndex_Check(ix)) {
i = PyNumber_AsSsize_t(ix, PyExc_IndexError);
if (i == -1 && PyErr_Occurred()) return (0);
- if (i < 0) i += PyString_GET_SIZE(me);
+ if (i < 0) i += BIN_LEN(me);
rc = bytestring_pyitem(me, i);
} else if (PySlice_Check(ix)) {
- if (PySlice_GetIndicesEx((PySliceObject *)ix, PyString_GET_SIZE(me),
+ if (PySlice_GetIndicesEx((PySliceObject *)ix, BIN_LEN(me),
&i, &j, &k, &n))
return (0);
if (k == 1) return bytestring_pyslice(me, i, j);
rc = bytestring_pywrap(0, n);
- p = (unsigned char *)PyString_AS_STRING(me) + i;
- q = (unsigned char *)PyString_AS_STRING(rc);
+ p = (unsigned char *)BIN_PTR(me) + i;
+ q = (unsigned char *)BIN_PTR(rc);
while (n--) { *q++ = *p; p += k; }
} else
TYERR("wanted integer or slice");
#define BINOP(name, op) \
static PyObject *bytestring_py##name(PyObject *x, PyObject *y) { \
- const void *xv, *yv; \
+ struct bin xx, yy; \
const unsigned char *xp, *yp; \
unsigned char *zp; \
- Py_ssize_t xsz, ysz; \
int i; \
PyObject *rc = 0; \
- if (PyObject_AsReadBuffer(x, &xv, &xsz) || \
- PyObject_AsReadBuffer(y, &yv, &ysz)) \
- goto end; \
- if (xsz != ysz) VALERR("length mismatch"); \
- rc = bytestring_pywrap(0, xsz); \
- xp = xv; yp = yv; zp = (unsigned char *)PyString_AS_STRING(rc); \
- for (i = xsz; i > 0; i--) *zp++ = *xp++ op *yp++; \
+ if (!convbin(x, &xx) || !convbin(y, &yy)) goto end; \
+ if (xx.sz != yy.sz) VALERR("length mismatch"); \
+ rc = bytestring_pywrap(0, xx.sz); \
+ xp = xx.p; yp = yy.p; zp = (unsigned char *)BIN_PTR(rc); \
+ for (i = xx.sz; i > 0; i--) *zp++ = *xp++ op *yp++; \
end: \
return (rc); \
}
#define UNOP(name, op) \
static PyObject *bytestring_py##name(PyObject *x) { \
- const void *xv; \
+ struct bin xx; \
const unsigned char *xp; \
unsigned char *zp; \
- Py_ssize_t xsz; \
int i; \
PyObject *rc = 0; \
- if (PyObject_AsReadBuffer(x, &xv, &xsz)) goto end; \
- rc = bytestring_pywrap(0, xsz); \
- xp = xv; zp = (unsigned char *)PyString_AS_STRING(rc); \
- for (i = xsz; i > 0; i--) *zp++ = op *xp++; \
+ if (!convbin(x, &xx)) goto end; \
+ rc = bytestring_pywrap(0, xx.sz); \
+ xp = xx.p; zp = (unsigned char *)BIN_PTR(rc); \
+ for (i = xx.sz; i > 0; i--) *zp++ = op *xp++; \
end: \
return (rc); \
}
{ 0 }
};
-#define string_pytype &PyString_Type
+#define string_pytype &BIN_TYPE
void bytestring_pyinit(void)
{
INITTYPE(bytestring, string);