Skip to content

Instantly share code, notes, and snippets.

@odedlaz
Created December 1, 2016 10:22
Show Gist options
  • Save odedlaz/e03437408d1f4f99b05b45228f5123b2 to your computer and use it in GitHub Desktop.
Save odedlaz/e03437408d1f4f99b05b45228f5123b2 to your computer and use it in GitHub Desktop.
PyBytes_Concat
void
PyBytes_Concat(PyObject **pv, PyObject *w)
{
assert(pv != NULL);
if (*pv == NULL)
return;
if (w == NULL) {
Py_CLEAR(*pv);
return;
}
if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) {
/* Only one reference, so we can resize in place */
Py_ssize_t oldsize;
Py_buffer wb;
wb.len = -1;
if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name);
Py_CLEAR(*pv);
return;
}
oldsize = PyBytes_GET_SIZE(*pv);
if (oldsize > PY_SSIZE_T_MAX - wb.len) {
PyErr_NoMemory();
goto error;
}
if (_PyBytes_Resize(pv, oldsize + wb.len) < 0)
goto error;
memcpy(PyBytes_AS_STRING(*pv) + oldsize, wb.buf, wb.len);
PyBuffer_Release(&wb);
return;
error:
PyBuffer_Release(&wb);
Py_CLEAR(*pv);
return;
}
else {
/* Multiple references, need to create new object */
PyObject *v;
v = bytes_concat(*pv, w);
Py_SETREF(*pv, v);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment