mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +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
|
|
@ -4,6 +4,7 @@
|
|||
#include "Python.h"
|
||||
#include "pycore_abstract.h" // _PyIndex_Check()
|
||||
#include "pycore_bytes_methods.h"
|
||||
#include "pycore_bytesobject.h"
|
||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||
#include "pycore_strhex.h" // _Py_strhex_with_sep()
|
||||
#include "pycore_long.h" // _PyLong_FromUnsignedChar()
|
||||
|
|
@ -319,37 +320,16 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
|
|||
static PyObject *
|
||||
bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
|
||||
{
|
||||
PyByteArrayObject *result;
|
||||
Py_ssize_t mysize;
|
||||
Py_ssize_t size;
|
||||
const char *buf;
|
||||
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
mysize = Py_SIZE(self);
|
||||
const Py_ssize_t mysize = Py_SIZE(self);
|
||||
if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
|
||||
return PyErr_NoMemory();
|
||||
size = mysize * count;
|
||||
result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
|
||||
buf = PyByteArray_AS_STRING(self);
|
||||
Py_ssize_t size = mysize * count;
|
||||
PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
|
||||
const char* buf = PyByteArray_AS_STRING(self);
|
||||
if (result != NULL && size != 0) {
|
||||
if (mysize == 1)
|
||||
memset(result->ob_bytes, buf[0], size);
|
||||
else {
|
||||
Py_ssize_t i, j;
|
||||
|
||||
i = 0;
|
||||
if (i < size) {
|
||||
memcpy(result->ob_bytes, buf, mysize);
|
||||
i = mysize;
|
||||
}
|
||||
// repeatedly double the number of bytes copied
|
||||
while (i < size) {
|
||||
j = Py_MIN(i, size - i);
|
||||
memcpy(result->ob_bytes + i, result->ob_bytes, j);
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
_PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
|
||||
}
|
||||
return (PyObject *)result;
|
||||
}
|
||||
|
|
@ -357,33 +337,22 @@ bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
|
|||
static PyObject *
|
||||
bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
|
||||
{
|
||||
Py_ssize_t mysize;
|
||||
Py_ssize_t size;
|
||||
char *buf;
|
||||
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
mysize = Py_SIZE(self);
|
||||
else if (count == 1) {
|
||||
Py_INCREF(self);
|
||||
return (PyObject*)self;
|
||||
}
|
||||
|
||||
const Py_ssize_t mysize = Py_SIZE(self);
|
||||
if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
|
||||
return PyErr_NoMemory();
|
||||
size = mysize * count;
|
||||
const Py_ssize_t size = mysize * count;
|
||||
if (PyByteArray_Resize((PyObject *)self, size) < 0)
|
||||
return NULL;
|
||||
|
||||
buf = PyByteArray_AS_STRING(self);
|
||||
if (mysize == 1)
|
||||
memset(buf, buf[0], size);
|
||||
else {
|
||||
Py_ssize_t i, j;
|
||||
|
||||
i = mysize;
|
||||
// repeatedly double the number of bytes copied
|
||||
while (i < size) {
|
||||
j = Py_MIN(i, size - i);
|
||||
memcpy(buf + i, buf, j);
|
||||
i += j;
|
||||
}
|
||||
}
|
||||
char* buf = PyByteArray_AS_STRING(self);
|
||||
_PyBytes_Repeat(buf, size, buf, mysize);
|
||||
|
||||
Py_INCREF(self);
|
||||
return (PyObject *)self;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue