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;
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)); }
{
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));
}