+static PyObject *bytestring_pyconcat(PyObject *x, PyObject *y)
+{
+ struct bin xx, yy;
+ PyObject *z = 0; char *zp; size_t zsz;
+
+ 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);
+}
+
+static PyObject *bytestring_pyrepeat(PyObject *me, Py_ssize_t n)
+{
+ const unsigned char *xp; size_t xsz;
+ PyObject *z = 0; char *zp; size_t zsz;
+
+ 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 = BIN_PTR(z);
+ if (xsz == 1) memset(zp, *xp, zsz);
+ else while (zsz) { memcpy(zp, xp, xsz); zp += xsz; zsz -= xsz; }
+end:
+ return (z);
+}
+
+static PyObject *bytestring_pyitem(PyObject *me, Py_ssize_t i)
+{
+ PyObject *rc = 0;
+
+ if (i < 0 || i >= BIN_LEN(me)) IXERR("out of range");
+#ifdef PY3
+ rc = getulong(BIN_PTR(me)[i]&0xff);
+#else
+ rc = bytestring_pywrap(BIN_PTR(me) + i, 1);
+#endif
+end:
+ return (rc);
+}
+
+static PyObject *bytestring_pyslice(PyObject *me, Py_ssize_t i, Py_ssize_t j)
+{
+ PyObject *rc = 0;
+ size_t n = BIN_LEN(me);
+
+ if (i < 0) i = 0;
+ if (j < 0) j = 0;
+ else if (j > n) j = n;
+ 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(BIN_PTR(me) + i, j - i);
+end:
+ return (rc);
+}
+
+static PyObject *bytestring_pysubscript(PyObject *me, PyObject *ix)
+{
+ Py_ssize_t i, j, k, n;
+ const unsigned char *p;
+ unsigned char *q;
+ PyObject *rc = 0;
+
+ if (PyIndex_Check(ix)) {
+ i = PyNumber_AsSsize_t(ix, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred()) return (0);
+ if (i < 0) i += BIN_LEN(me);
+ rc = bytestring_pyitem(me, i);
+ } else if (PySlice_Check(ix)) {
+ if (PySlice_GetIndicesEx(PY23((PySliceObject *), NOTHING)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 *)BIN_PTR(me) + i;
+ q = (unsigned char *)BIN_PTR(rc);
+ while (n--) { *q++ = *p; p += k; }
+ } else
+ TYERR("wanted integer or slice");
+end:
+ return (rc);
+}
+