Split PyBytes_FromObject() into subfunctions

This commit is contained in:
Victor Stinner 2015-10-14 13:44:29 +02:00
parent 2ec8063cc9
commit f2eafa323b
1 changed files with 122 additions and 79 deletions

View File

@ -3384,27 +3384,15 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return PyBytes_FromObject(x); return PyBytes_FromObject(x);
} }
PyObject * static PyObject*
PyBytes_FromObject(PyObject *x) _PyBytes_FromBuffer(PyObject *x)
{ {
PyObject *new, *it; PyObject *new;
Py_ssize_t i, size;
if (x == NULL) {
PyErr_BadInternalCall();
return NULL;
}
if (PyBytes_CheckExact(x)) {
Py_INCREF(x);
return x;
}
/* Use the modern buffer interface */
if (PyObject_CheckBuffer(x)) {
Py_buffer view; Py_buffer view;
if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0)
return NULL; return NULL;
new = PyBytes_FromStringAndSize(NULL, view.len); new = PyBytes_FromStringAndSize(NULL, view.len);
if (!new) if (!new)
goto fail; goto fail;
@ -3413,59 +3401,82 @@ PyBytes_FromObject(PyObject *x)
goto fail; goto fail;
PyBuffer_Release(&view); PyBuffer_Release(&view);
return new; return new;
fail: fail:
Py_XDECREF(new); Py_XDECREF(new);
PyBuffer_Release(&view); PyBuffer_Release(&view);
return NULL; return NULL;
} }
if (PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError, static PyObject*
"cannot convert unicode object to bytes"); _PyBytes_FromList(PyObject *x)
{
PyObject *new;
Py_ssize_t i;
Py_ssize_t value;
char *str;
new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x));
if (new == NULL)
return NULL;
str = ((PyBytesObject *)new)->ob_sval;
for (i = 0; i < Py_SIZE(x); i++) {
value = PyNumber_AsSsize_t(PyList_GET_ITEM(x, i), PyExc_ValueError);
if (value == -1 && PyErr_Occurred())
goto error;
if (value < 0 || value >= 256) {
PyErr_SetString(PyExc_ValueError,
"bytes must be in range(0, 256)");
goto error;
}
*str++ = (char) value;
}
return new;
error:
Py_DECREF(new);
return NULL; return NULL;
} }
if (PyList_CheckExact(x)) { static PyObject*
_PyBytes_FromTuple(PyObject *x)
{
PyObject *new;
Py_ssize_t i;
Py_ssize_t value;
char *str;
new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x)); new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x));
if (new == NULL) if (new == NULL)
return NULL; return NULL;
str = ((PyBytesObject *)new)->ob_sval;
for (i = 0; i < Py_SIZE(x); i++) { for (i = 0; i < Py_SIZE(x); i++) {
Py_ssize_t value = PyNumber_AsSsize_t( value = PyNumber_AsSsize_t(PyTuple_GET_ITEM(x, i), PyExc_ValueError);
PyList_GET_ITEM(x, i), PyExc_ValueError); if (value == -1 && PyErr_Occurred())
if (value == -1 && PyErr_Occurred()) { goto error;
Py_DECREF(new);
return NULL;
}
if (value < 0 || value >= 256) { if (value < 0 || value >= 256) {
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"bytes must be in range(0, 256)"); "bytes must be in range(0, 256)");
Py_DECREF(new); goto error;
return NULL;
} }
((PyBytesObject *)new)->ob_sval[i] = (char) value; *str++ = (char) value;
} }
return new; return new;
}
if (PyTuple_CheckExact(x)) { error:
new = PyBytes_FromStringAndSize(NULL, Py_SIZE(x));
if (new == NULL)
return NULL;
for (i = 0; i < Py_SIZE(x); i++) {
Py_ssize_t value = PyNumber_AsSsize_t(
PyTuple_GET_ITEM(x, i), PyExc_ValueError);
if (value == -1 && PyErr_Occurred()) {
Py_DECREF(new); Py_DECREF(new);
return NULL; return NULL;
} }
if (value < 0 || value >= 256) {
PyErr_SetString(PyExc_ValueError, static PyObject *
"bytes must be in range(0, 256)"); _PyBytes_FromIterator(PyObject *x)
Py_DECREF(new); {
return NULL; PyObject *new, *it;
} Py_ssize_t i, size;
((PyBytesObject *)new)->ob_sval[i] = (char) value;
}
return new;
}
/* For iterator version, create a string object and resize as needed */ /* For iterator version, create a string object and resize as needed */
size = PyObject_LengthHint(x, 64); size = PyObject_LengthHint(x, 64);
@ -3533,6 +3544,38 @@ PyBytes_FromObject(PyObject *x)
return NULL; return NULL;
} }
PyObject *
PyBytes_FromObject(PyObject *x)
{
if (x == NULL) {
PyErr_BadInternalCall();
return NULL;
}
if (PyBytes_CheckExact(x)) {
Py_INCREF(x);
return x;
}
/* Use the modern buffer interface */
if (PyObject_CheckBuffer(x))
return _PyBytes_FromBuffer(x);
if (PyList_CheckExact(x))
return _PyBytes_FromList(x);
if (PyTuple_CheckExact(x))
return _PyBytes_FromTuple(x);
if (PyUnicode_Check(x)) {
PyErr_SetString(PyExc_TypeError,
"cannot convert unicode object to bytes");
return NULL;
}
return _PyBytes_FromIterator(x);
}
static PyObject * static PyObject *
str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {