mirror of
https://github.com/python/cpython.git
synced 2025-08-30 05:35:08 +00:00
bpo-47070: Add _PyBytes_Repeat() (GH-31999)
Use it where appropriate: the repeat functions of `array.array`, `bytes`, `bytearray`, and `str`.
This commit is contained in:
parent
86384cf83f
commit
850687df47
6 changed files with 81 additions and 103 deletions
|
@ -10,6 +10,7 @@
|
|||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||
#include "pycore_bytesobject.h" // _PyBytes_Repeat
|
||||
#include "structmember.h" // PyMemberDef
|
||||
#include <stddef.h> // offsetof()
|
||||
#include <stddef.h>
|
||||
|
@ -910,34 +911,24 @@ static PyObject *
|
|||
array_repeat(arrayobject *a, Py_ssize_t n)
|
||||
{
|
||||
array_state *state = find_array_state_by_type(Py_TYPE(a));
|
||||
Py_ssize_t size;
|
||||
arrayobject *np;
|
||||
Py_ssize_t oldbytes, newbytes;
|
||||
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
if ((Py_SIZE(a) != 0) && (n > PY_SSIZE_T_MAX / Py_SIZE(a))) {
|
||||
const Py_ssize_t array_length = Py_SIZE(a);
|
||||
if ((array_length != 0) && (n > PY_SSIZE_T_MAX / array_length)) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
size = Py_SIZE(a) * n;
|
||||
np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
|
||||
Py_ssize_t size = array_length * n;
|
||||
arrayobject* np = (arrayobject *) newarrayobject(state->ArrayType, size, a->ob_descr);
|
||||
if (np == NULL)
|
||||
return NULL;
|
||||
if (size == 0)
|
||||
return (PyObject *)np;
|
||||
oldbytes = Py_SIZE(a) * a->ob_descr->itemsize;
|
||||
newbytes = oldbytes * n;
|
||||
/* this follows the code in unicode_repeat */
|
||||
if (oldbytes == 1) {
|
||||
memset(np->ob_item, a->ob_item[0], newbytes);
|
||||
} else {
|
||||
Py_ssize_t done = oldbytes;
|
||||
memcpy(np->ob_item, a->ob_item, oldbytes);
|
||||
while (done < newbytes) {
|
||||
Py_ssize_t ncopy = (done <= newbytes-done) ? done : newbytes-done;
|
||||
memcpy(np->ob_item+done, np->ob_item, ncopy);
|
||||
done += ncopy;
|
||||
}
|
||||
}
|
||||
|
||||
const Py_ssize_t oldbytes = array_length * a->ob_descr->itemsize;
|
||||
const Py_ssize_t newbytes = oldbytes * n;
|
||||
_PyBytes_Repeat(np->ob_item, newbytes, a->ob_item, oldbytes);
|
||||
|
||||
return (PyObject *)np;
|
||||
}
|
||||
|
||||
|
@ -1075,27 +1066,23 @@ array_inplace_concat(arrayobject *self, PyObject *bb)
|
|||
static PyObject *
|
||||
array_inplace_repeat(arrayobject *self, Py_ssize_t n)
|
||||
{
|
||||
char *items, *p;
|
||||
Py_ssize_t size, i;
|
||||
const Py_ssize_t array_size = Py_SIZE(self);
|
||||
|
||||
if (Py_SIZE(self) > 0) {
|
||||
if (array_size > 0 && n != 1 ) {
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
if ((self->ob_descr->itemsize != 0) &&
|
||||
(Py_SIZE(self) > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
|
||||
(array_size > PY_SSIZE_T_MAX / self->ob_descr->itemsize)) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
size = Py_SIZE(self) * self->ob_descr->itemsize;
|
||||
Py_ssize_t size = array_size * self->ob_descr->itemsize;
|
||||
if (n > 0 && size > PY_SSIZE_T_MAX / n) {
|
||||
return PyErr_NoMemory();
|
||||
}
|
||||
if (array_resize(self, n * Py_SIZE(self)) == -1)
|
||||
if (array_resize(self, n * array_size) == -1)
|
||||
return NULL;
|
||||
items = p = self->ob_item;
|
||||
for (i = 1; i < n; i++) {
|
||||
p += size;
|
||||
memcpy(p, items, size);
|
||||
}
|
||||
|
||||
_PyBytes_Repeat(self->ob_item, n*size, self->ob_item, size);
|
||||
}
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue