summaryrefslogtreecommitdiff
path: root/Objects/bytearrayobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/bytearrayobject.c')
-rw-r--r--Objects/bytearrayobject.c440
1 files changed, 211 insertions, 229 deletions
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 50667a646a..5b75705abf 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -150,6 +150,7 @@ PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
}
Py_SIZE(new) = size;
new->ob_alloc = alloc;
+ new->ob_start = new->ob_bytes;
new->ob_exports = 0;
return (PyObject *)new;
@@ -177,48 +178,70 @@ int
PyByteArray_Resize(PyObject *self, Py_ssize_t size)
{
void *sval;
- Py_ssize_t alloc = ((PyByteArrayObject *)self)->ob_alloc;
+ PyByteArrayObject *obj = ((PyByteArrayObject *)self);
+ Py_ssize_t alloc = obj->ob_alloc;
+ Py_ssize_t logical_offset = obj->ob_start - obj->ob_bytes;
assert(self != NULL);
assert(PyByteArray_Check(self));
assert(size >= 0);
+ assert(logical_offset >= 0);
+ assert(logical_offset <= alloc);
if (size == Py_SIZE(self)) {
return 0;
}
- if (!_canresize((PyByteArrayObject *)self)) {
+ if (!_canresize(obj)) {
return -1;
}
- if (size < alloc / 2) {
- /* Major downsize; resize down to exact size */
- alloc = size + 1;
- }
- else if (size < alloc) {
- /* Within allocated size; quick exit */
- Py_SIZE(self) = size;
- ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null */
- return 0;
- }
- else if (size <= alloc * 1.125) {
- /* Moderate upsize; overallocate similar to list_resize() */
- alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
+ if (size + logical_offset + 1 < alloc) {
+ /* Current buffer is large enough to host the requested size,
+ decide on a strategy. */
+ if (size < alloc / 2) {
+ /* Major downsize; resize down to exact size */
+ alloc = size + 1;
+ }
+ else {
+ /* Minor downsize; quick exit */
+ Py_SIZE(self) = size;
+ PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
+ return 0;
+ }
}
else {
- /* Major upsize; resize up to exact size */
- alloc = size + 1;
+ /* Need growing, decide on a strategy */
+ if (size <= alloc * 1.125) {
+ /* Moderate upsize; overallocate similar to list_resize() */
+ alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
+ }
+ else {
+ /* Major upsize; resize up to exact size */
+ alloc = size + 1;
+ }
}
- sval = PyObject_Realloc(((PyByteArrayObject *)self)->ob_bytes, alloc);
- if (sval == NULL) {
- PyErr_NoMemory();
- return -1;
+ if (logical_offset > 0) {
+ sval = PyObject_Malloc(alloc);
+ if (sval == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ memcpy(sval, PyByteArray_AS_STRING(self), Py_MIN(size, Py_SIZE(self)));
+ PyObject_Free(obj->ob_bytes);
+ }
+ else {
+ sval = PyObject_Realloc(obj->ob_bytes, alloc);
+ if (sval == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
}
- ((PyByteArrayObject *)self)->ob_bytes = sval;
+ obj->ob_bytes = obj->ob_start = sval;
Py_SIZE(self) = size;
- ((PyByteArrayObject *)self)->ob_alloc = alloc;
- ((PyByteArrayObject *)self)->ob_bytes[size] = '\0'; /* Trailing null byte */
+ obj->ob_alloc = alloc;
+ obj->ob_bytes[size] = '\0'; /* Trailing null byte */
return 0;
}
@@ -288,13 +311,13 @@ bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
}
if (size < self->ob_alloc) {
Py_SIZE(self) = size;
- self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
+ PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0'; /* Trailing null byte */
}
else if (PyByteArray_Resize((PyObject *)self, size) < 0) {
PyBuffer_Release(&vo);
return NULL;
}
- memcpy(self->ob_bytes + mysize, vo.buf, vo.len);
+ memcpy(PyByteArray_AS_STRING(self) + mysize, vo.buf, vo.len);
PyBuffer_Release(&vo);
Py_INCREF(self);
return (PyObject *)self;
@@ -331,6 +354,7 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
{
Py_ssize_t mysize;
Py_ssize_t size;
+ char *buf;
if (count < 0)
count = 0;
@@ -338,19 +362,16 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
return PyErr_NoMemory();
size = mysize * count;
- if (size < self->ob_alloc) {
- Py_SIZE(self) = size;
- self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */
- }
- else if (PyByteArray_Resize((PyObject *)self, size) < 0)
+ if (PyByteArray_Resize((PyObject *)self, size) < 0)
return NULL;
+ buf = PyByteArray_AS_STRING(self);
if (mysize == 1)
- memset(self->ob_bytes, self->ob_bytes[0], size);
+ memset(buf, buf[0], size);
else {
Py_ssize_t i;
for (i = 1; i < count; i++)
- memcpy(self->ob_bytes + i*mysize, self->ob_bytes, mysize);
+ memcpy(buf + i*mysize, buf, mysize);
}
Py_INCREF(self);
@@ -366,7 +387,7 @@ bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
return NULL;
}
- return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
+ return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
}
static PyObject *
@@ -385,7 +406,7 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index)
PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
return NULL;
}
- return PyLong_FromLong((unsigned char)(self->ob_bytes[i]));
+ return PyLong_FromLong((unsigned char)(PyByteArray_AS_STRING(self)[i]));
}
else if (PySlice_Check(index)) {
Py_ssize_t start, stop, step, slicelength, cur, i;
@@ -398,8 +419,8 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index)
if (slicelength <= 0)
return PyByteArray_FromStringAndSize("", 0);
else if (step == 1) {
- return PyByteArray_FromStringAndSize(self->ob_bytes + start,
- slicelength);
+ return PyByteArray_FromStringAndSize(
+ PyByteArray_AS_STRING(self) + start, slicelength);
}
else {
char *source_buf = PyByteArray_AS_STRING(self);
@@ -425,10 +446,94 @@ bytearray_subscript(PyByteArrayObject *self, PyObject *index)
}
static int
+bytearray_setslice_linear(PyByteArrayObject *self,
+ Py_ssize_t lo, Py_ssize_t hi,
+ char *bytes, Py_ssize_t bytes_len)
+{
+ Py_ssize_t avail = hi - lo;
+ char *buf = PyByteArray_AS_STRING(self);
+ Py_ssize_t growth = bytes_len - avail;
+ int res = 0;
+ assert(avail >= 0);
+
+ if (growth < 0) {
+ if (!_canresize(self))
+ return -1;
+
+ if (lo == 0) {
+ /* Shrink the buffer by advancing its logical start */
+ self->ob_start -= growth;
+ /*
+ 0 lo hi old_size
+ | |<----avail----->|<-----tail------>|
+ | |<-bytes_len->|<-----tail------>|
+ 0 new_lo new_hi new_size
+ */
+ }
+ else {
+ /*
+ 0 lo hi old_size
+ | |<----avail----->|<-----tomove------>|
+ | |<-bytes_len->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(buf + lo + bytes_len, buf + hi,
+ Py_SIZE(self) - hi);
+ }
+ if (PyByteArray_Resize((PyObject *)self,
+ Py_SIZE(self) + growth) < 0) {
+ /* Issue #19578: Handling the memory allocation failure here is
+ tricky here because the bytearray object has already been
+ modified. Depending on growth and lo, the behaviour is
+ different.
+
+ If growth < 0 and lo != 0, the operation is completed, but a
+ MemoryError is still raised and the memory block is not
+ shrinked. Otherwise, the bytearray is restored in its previous
+ state and a MemoryError is raised. */
+ if (lo == 0) {
+ self->ob_start += growth;
+ return -1;
+ }
+ /* memmove() removed bytes, the bytearray object cannot be
+ restored in its previous state. */
+ Py_SIZE(self) += growth;
+ res = -1;
+ }
+ buf = PyByteArray_AS_STRING(self);
+ }
+ else if (growth > 0) {
+ if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ if (PyByteArray_Resize((PyObject *)self,
+ Py_SIZE(self) + growth) < 0) {
+ return -1;
+ }
+ buf = PyByteArray_AS_STRING(self);
+ /* Make the place for the additional bytes */
+ /*
+ 0 lo hi old_size
+ | |<-avail->|<-----tomove------>|
+ | |<---bytes_len-->|<-----tomove------>|
+ 0 lo new_hi new_size
+ */
+ memmove(buf + lo + bytes_len, buf + hi,
+ Py_SIZE(self) - lo - bytes_len);
+ }
+
+ if (bytes_len > 0)
+ memcpy(buf + lo, bytes, bytes_len);
+ return res;
+}
+
+static int
bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
PyObject *values)
{
- Py_ssize_t avail, needed;
+ Py_ssize_t needed;
void *bytes;
Py_buffer vbytes;
int res = 0;
@@ -467,50 +572,9 @@ bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
if (hi > Py_SIZE(self))
hi = Py_SIZE(self);
- avail = hi - lo;
- if (avail < 0)
- lo = hi = avail = 0;
-
- if (avail != needed) {
- if (avail > needed) {
- if (!_canresize(self)) {
- res = -1;
- goto finish;
- }
- /*
- 0 lo hi old_size
- | |<----avail----->|<-----tomove------>|
- | |<-needed->|<-----tomove------>|
- 0 lo new_hi new_size
- */
- memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
- Py_SIZE(self) - hi);
- }
- /* XXX(nnorwitz): need to verify this can't overflow! */
- if (PyByteArray_Resize((PyObject *)self,
- Py_SIZE(self) + needed - avail) < 0) {
- res = -1;
- goto finish;
- }
- if (avail < needed) {
- /*
- 0 lo hi old_size
- | |<-avail->|<-----tomove------>|
- | |<----needed---->|<-----tomove------>|
- 0 lo new_hi new_size
- */
- memmove(self->ob_bytes + lo + needed, self->ob_bytes + hi,
- Py_SIZE(self) - lo - needed);
- }
- }
-
- if (needed > 0)
- memcpy(self->ob_bytes + lo, bytes, needed);
-
-
- finish:
+ res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
if (vbytes.len != -1)
- PyBuffer_Release(&vbytes);
+ PyBuffer_Release(&vbytes);
return res;
}
@@ -533,7 +597,7 @@ bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
if (!_getbytevalue(value, &ival))
return -1;
- self->ob_bytes[i] = ival;
+ PyByteArray_AS_STRING(self)[i] = ival;
return 0;
}
@@ -541,7 +605,8 @@ static int
bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
{
Py_ssize_t start, stop, step, slicelen, needed;
- char *bytes;
+ char *buf, *bytes;
+ buf = PyByteArray_AS_STRING(self);
if (PyIndex_Check(index)) {
Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
@@ -568,7 +633,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
int ival;
if (!_getbytevalue(values, &ival))
return -1;
- self->ob_bytes[i] = (char)ival;
+ buf[i] = (char)ival;
return 0;
}
}
@@ -606,7 +671,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
}
else {
assert(PyByteArray_Check(values));
- bytes = ((PyByteArrayObject *)values)->ob_bytes;
+ bytes = PyByteArray_AS_STRING(values);
needed = Py_SIZE(values);
}
/* Make sure b[5:2] = ... inserts before 5, not before 2. */
@@ -614,38 +679,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
(step > 0 && start > stop))
stop = start;
if (step == 1) {
- if (slicelen != needed) {
- if (!_canresize(self))
- return -1;
- if (slicelen > needed) {
- /*
- 0 start stop old_size
- | |<---slicelen--->|<-----tomove------>|
- | |<-needed->|<-----tomove------>|
- 0 lo new_hi new_size
- */
- memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
- Py_SIZE(self) - stop);
- }
- if (PyByteArray_Resize((PyObject *)self,
- Py_SIZE(self) + needed - slicelen) < 0)
- return -1;
- if (slicelen < needed) {
- /*
- 0 lo hi old_size
- | |<-avail->|<-----tomove------>|
- | |<----needed---->|<-----tomove------>|
- 0 lo new_hi new_size
- */
- memmove(self->ob_bytes + start + needed, self->ob_bytes + stop,
- Py_SIZE(self) - start - needed);
- }
- }
-
- if (needed > 0)
- memcpy(self->ob_bytes + start, bytes, needed);
-
- return 0;
+ return bytearray_setslice_linear(self, start, stop, bytes, needed);
}
else {
if (needed == 0) {
@@ -672,14 +706,14 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
lim = PyByteArray_GET_SIZE(self) - cur - 1;
- memmove(self->ob_bytes + cur - i,
- self->ob_bytes + cur + 1, lim);
+ memmove(buf + cur - i,
+ buf + cur + 1, lim);
}
/* Move the tail of the bytes, in one chunk */
cur = start + (size_t)slicelen*step;
if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
- memmove(self->ob_bytes + cur - slicelen,
- self->ob_bytes + cur,
+ memmove(buf + cur - slicelen,
+ buf + cur,
PyByteArray_GET_SIZE(self) - cur);
}
if (PyByteArray_Resize((PyObject *)self,
@@ -701,7 +735,7 @@ bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *valu
return -1;
}
for (cur = start, i = 0; i < slicelen; cur += step, i++)
- self->ob_bytes[cur] = bytes[i];
+ buf[cur] = bytes[i];
return 0;
}
}
@@ -781,7 +815,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
if (count > 0) {
if (PyByteArray_Resize((PyObject *)self, count))
return -1;
- memset(self->ob_bytes, 0, count);
+ memset(PyByteArray_AS_STRING(self), 0, count);
}
return 0;
}
@@ -794,7 +828,8 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
return -1;
size = view.len;
if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
- if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0)
+ if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
+ &view, size, 'C') < 0)
goto fail;
PyBuffer_Release(&view);
return 0;
@@ -838,7 +873,7 @@ bytearray_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds)
Py_SIZE(self)++;
else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
goto error;
- self->ob_bytes[Py_SIZE(self)-1] = value;
+ PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
}
/* Clean up and return success */
@@ -862,9 +897,10 @@ bytearray_repr(PyByteArrayObject *self)
/* 15 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
size_t newsize;
PyObject *v;
- register Py_ssize_t i;
- register char c;
- register char *p;
+ Py_ssize_t i;
+ char *bytes;
+ char c;
+ char *p;
int quote;
char *test, *start;
char *buffer;
@@ -899,11 +935,12 @@ bytearray_repr(PyByteArrayObject *self)
*p++ = *quote_prefix++;
*p++ = quote;
+ bytes = PyByteArray_AS_STRING(self);
for (i = 0; i < length; i++) {
/* There's at least enough room for a hex escape
and a closing quote. */
assert(newsize - (p - buffer) >= 5);
- c = self->ob_bytes[i];
+ c = bytes[i];
if (c == '\'' || c == '\\')
*p++ = '\\', *p++ = c;
else if (c == '\t')
@@ -1038,6 +1075,7 @@ bytearray_dealloc(PyByteArrayObject *self)
#define FASTSEARCH fastsearch
#define STRINGLIB(F) stringlib_##F
#define STRINGLIB_CHAR char
+#define STRINGLIB_SIZEOF_CHAR 1
#define STRINGLIB_LEN PyByteArray_GET_SIZE
#define STRINGLIB_STR PyByteArray_AS_STRING
#define STRINGLIB_NEW PyByteArray_FromStringAndSize
@@ -1049,6 +1087,7 @@ bytearray_dealloc(PyByteArrayObject *self)
#include "stringlib/fastsearch.h"
#include "stringlib/count.h"
#include "stringlib/find.h"
+#include "stringlib/join.h"
#include "stringlib/partition.h"
#include "stringlib/split.h"
#include "stringlib/ctype.h"
@@ -1429,9 +1468,9 @@ table, which must be a bytes object of length 256.");
static PyObject *
bytearray_translate(PyByteArrayObject *self, PyObject *args)
{
- register char *input, *output;
- register const char *table;
- register Py_ssize_t i, c;
+ char *input, *output;
+ const char *table;
+ Py_ssize_t i, c;
PyObject *input_obj = (PyObject*)self;
const char *output_start;
Py_ssize_t inlen;
@@ -2192,7 +2231,7 @@ bytearray_reverse(PyByteArrayObject *self, PyObject *unused)
Py_ssize_t i, j, n = Py_SIZE(self);
j = n / 2;
- head = self->ob_bytes;
+ head = PyByteArray_AS_STRING(self);
tail = head + n - 1;
for (i = 0; i < j; i++) {
swap = *head;
@@ -2213,6 +2252,7 @@ bytearray_insert(PyByteArrayObject *self, PyObject *args)
PyObject *value;
int ival;
Py_ssize_t where, n = Py_SIZE(self);
+ char *buf;
if (!PyArg_ParseTuple(args, "nO:insert", &where, &value))
return NULL;
@@ -2226,6 +2266,7 @@ bytearray_insert(PyByteArrayObject *self, PyObject *args)
return NULL;
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
return NULL;
+ buf = PyByteArray_AS_STRING(self);
if (where < 0) {
where += n;
@@ -2234,8 +2275,8 @@ bytearray_insert(PyByteArrayObject *self, PyObject *args)
}
if (where > n)
where = n;
- memmove(self->ob_bytes + where + 1, self->ob_bytes + where, n - where);
- self->ob_bytes[where] = ival;
+ memmove(buf + where + 1, buf + where, n - where);
+ buf[where] = ival;
Py_RETURN_NONE;
}
@@ -2260,7 +2301,7 @@ bytearray_append(PyByteArrayObject *self, PyObject *arg)
if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
return NULL;
- self->ob_bytes[n] = value;
+ PyByteArray_AS_STRING(self)[n] = value;
Py_RETURN_NONE;
}
@@ -2291,7 +2332,7 @@ bytearray_extend(PyByteArrayObject *self, PyObject *arg)
return NULL;
/* Try to determine the length of the argument. 32 is arbitrary. */
- buf_size = _PyObject_LengthHint(arg, 32);
+ buf_size = PyObject_LengthHint(arg, 32);
if (buf_size == -1) {
Py_DECREF(it);
return NULL;
@@ -2353,6 +2394,7 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args)
{
int value;
Py_ssize_t where = -1, n = Py_SIZE(self);
+ char *buf;
if (!PyArg_ParseTuple(args, "|n:pop", &where))
return NULL;
@@ -2371,8 +2413,9 @@ bytearray_pop(PyByteArrayObject *self, PyObject *args)
if (!_canresize(self))
return NULL;
- value = self->ob_bytes[where];
- memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+ buf = PyByteArray_AS_STRING(self);
+ value = buf[where];
+ memmove(buf + where, buf + where + 1, n - where);
if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
return NULL;
@@ -2388,12 +2431,13 @@ bytearray_remove(PyByteArrayObject *self, PyObject *arg)
{
int value;
Py_ssize_t where, n = Py_SIZE(self);
+ char *buf = PyByteArray_AS_STRING(self);
if (! _getbytevalue(arg, &value))
return NULL;
for (where = 0; where < n; where++) {
- if (self->ob_bytes[where] == value)
+ if (buf[where] == value)
break;
}
if (where == n) {
@@ -2403,7 +2447,7 @@ bytearray_remove(PyByteArrayObject *self, PyObject *arg)
if (!_canresize(self))
return NULL;
- memmove(self->ob_bytes + where, self->ob_bytes + where + 1, n - where);
+ memmove(buf + where, buf + where + 1, n - where);
if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
return NULL;
@@ -2413,21 +2457,21 @@ bytearray_remove(PyByteArrayObject *self, PyObject *arg)
/* XXX These two helpers could be optimized if argsize == 1 */
static Py_ssize_t
-lstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+lstrip_helper(char *myptr, Py_ssize_t mysize,
void *argptr, Py_ssize_t argsize)
{
Py_ssize_t i = 0;
- while (i < mysize && memchr(argptr, myptr[i], argsize))
+ while (i < mysize && memchr(argptr, (unsigned char) myptr[i], argsize))
i++;
return i;
}
static Py_ssize_t
-rstrip_helper(unsigned char *myptr, Py_ssize_t mysize,
+rstrip_helper(char *myptr, Py_ssize_t mysize,
void *argptr, Py_ssize_t argsize)
{
Py_ssize_t i = mysize - 1;
- while (i >= 0 && memchr(argptr, myptr[i], argsize))
+ while (i >= 0 && memchr(argptr, (unsigned char) myptr[i], argsize))
i--;
return i + 1;
}
@@ -2442,7 +2486,7 @@ static PyObject *
bytearray_strip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t left, right, mysize, argsize;
- void *myptr, *argptr;
+ char *myptr, *argptr;
PyObject *arg = Py_None;
Py_buffer varg;
if (!PyArg_ParseTuple(args, "|O:strip", &arg))
@@ -2454,10 +2498,10 @@ bytearray_strip(PyByteArrayObject *self, PyObject *args)
else {
if (_getbuffer(arg, &varg) < 0)
return NULL;
- argptr = varg.buf;
+ argptr = (char *) varg.buf;
argsize = varg.len;
}
- myptr = self->ob_bytes;
+ myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
left = lstrip_helper(myptr, mysize, argptr, argsize);
if (left == mysize)
@@ -2466,7 +2510,7 @@ bytearray_strip(PyByteArrayObject *self, PyObject *args)
right = rstrip_helper(myptr, mysize, argptr, argsize);
if (arg != Py_None)
PyBuffer_Release(&varg);
- return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+ return PyByteArray_FromStringAndSize(myptr + left, right - left);
}
PyDoc_STRVAR(lstrip__doc__,
@@ -2479,7 +2523,7 @@ static PyObject *
bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t left, right, mysize, argsize;
- void *myptr, *argptr;
+ char *myptr, *argptr;
PyObject *arg = Py_None;
Py_buffer varg;
if (!PyArg_ParseTuple(args, "|O:lstrip", &arg))
@@ -2491,16 +2535,16 @@ bytearray_lstrip(PyByteArrayObject *self, PyObject *args)
else {
if (_getbuffer(arg, &varg) < 0)
return NULL;
- argptr = varg.buf;
+ argptr = (char *) varg.buf;
argsize = varg.len;
}
- myptr = self->ob_bytes;
+ myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
left = lstrip_helper(myptr, mysize, argptr, argsize);
right = mysize;
if (arg != Py_None)
PyBuffer_Release(&varg);
- return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left);
+ return PyByteArray_FromStringAndSize(myptr + left, right - left);
}
PyDoc_STRVAR(rstrip__doc__,
@@ -2513,7 +2557,7 @@ static PyObject *
bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
{
Py_ssize_t right, mysize, argsize;
- void *myptr, *argptr;
+ char *myptr, *argptr;
PyObject *arg = Py_None;
Py_buffer varg;
if (!PyArg_ParseTuple(args, "|O:rstrip", &arg))
@@ -2525,15 +2569,15 @@ bytearray_rstrip(PyByteArrayObject *self, PyObject *args)
else {
if (_getbuffer(arg, &varg) < 0)
return NULL;
- argptr = varg.buf;
+ argptr = (char *) varg.buf;
argsize = varg.len;
}
- myptr = self->ob_bytes;
+ myptr = PyByteArray_AS_STRING(self);
mysize = Py_SIZE(self);
right = rstrip_helper(myptr, mysize, argptr, argsize);
if (arg != Py_None)
PyBuffer_Release(&varg);
- return PyByteArray_FromStringAndSize(self->ob_bytes, right);
+ return PyByteArray_FromStringAndSize(myptr, right);
}
PyDoc_STRVAR(decode_doc,
@@ -2578,73 +2622,9 @@ Concatenate any number of bytes/bytearray objects, with B\n\
in between each pair, and return the result as a new bytearray.");
static PyObject *
-bytearray_join(PyByteArrayObject *self, PyObject *it)
+bytearray_join(PyObject *self, PyObject *iterable)
{
- PyObject *seq;
- Py_ssize_t mysize = Py_SIZE(self);
- Py_ssize_t i;
- Py_ssize_t n;
- PyObject **items;
- Py_ssize_t totalsize = 0;
- PyObject *result;
- char *dest;
-
- seq = PySequence_Fast(it, "can only join an iterable");
- if (seq == NULL)
- return NULL;
- n = PySequence_Fast_GET_SIZE(seq);
- items = PySequence_Fast_ITEMS(seq);
-
- /* Compute the total size, and check that they are all bytes */
- /* XXX Shouldn't we use _getbuffer() on these items instead? */
- for (i = 0; i < n; i++) {
- PyObject *obj = items[i];
- if (!PyByteArray_Check(obj) && !PyBytes_Check(obj)) {
- PyErr_Format(PyExc_TypeError,
- "can only join an iterable of bytes "
- "(item %ld has type '%.100s')",
- /* XXX %ld isn't right on Win64 */
- (long)i, Py_TYPE(obj)->tp_name);
- goto error;
- }
- if (i > 0)
- totalsize += mysize;
- totalsize += Py_SIZE(obj);
- if (totalsize < 0) {
- PyErr_NoMemory();
- goto error;
- }
- }
-
- /* Allocate the result, and copy the bytes */
- result = PyByteArray_FromStringAndSize(NULL, totalsize);
- if (result == NULL)
- goto error;
- dest = PyByteArray_AS_STRING(result);
- for (i = 0; i < n; i++) {
- PyObject *obj = items[i];
- Py_ssize_t size = Py_SIZE(obj);
- char *buf;
- if (PyByteArray_Check(obj))
- buf = PyByteArray_AS_STRING(obj);
- else
- buf = PyBytes_AS_STRING(obj);
- if (i) {
- memcpy(dest, self->ob_bytes, mysize);
- dest += mysize;
- }
- memcpy(dest, buf, size);
- dest += size;
- }
-
- /* Done */
- Py_DECREF(seq);
- return result;
-
- /* Error handling */
- error:
- Py_DECREF(seq);
- return NULL;
+ return stringlib_bytes_join(self, iterable);
}
PyDoc_STRVAR(splitlines__doc__,
@@ -2748,6 +2728,7 @@ _common_reduce(PyByteArrayObject *self, int proto)
{
PyObject *dict;
_Py_IDENTIFIER(__dict__);
+ char *buf;
dict = _PyObject_GetAttrId((PyObject *)self, &PyId___dict__);
if (dict == NULL) {
@@ -2756,19 +2737,20 @@ _common_reduce(PyByteArrayObject *self, int proto)
Py_INCREF(dict);
}
+ buf = PyByteArray_AS_STRING(self);
if (proto < 3) {
/* use str based reduction for backwards compatibility with Python 2.x */
PyObject *latin1;
- if (self->ob_bytes)
- latin1 = PyUnicode_DecodeLatin1(self->ob_bytes, Py_SIZE(self), NULL);
+ if (Py_SIZE(self))
+ latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
else
latin1 = PyUnicode_FromString("");
return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", dict);
}
else {
/* use more efficient byte based reduction */
- if (self->ob_bytes) {
- return Py_BuildValue("(O(y#)N)", Py_TYPE(self), self->ob_bytes, Py_SIZE(self), dict);
+ if (Py_SIZE(self)) {
+ return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), dict);
}
else {
return Py_BuildValue("(O()N)", Py_TYPE(self), dict);
@@ -2849,7 +2831,7 @@ bytearray_methods[] = {
{"count", (PyCFunction)bytearray_count, METH_VARARGS, count__doc__},
{"decode", (PyCFunction)bytearray_decode, METH_VARARGS | METH_KEYWORDS, decode_doc},
{"endswith", (PyCFunction)bytearray_endswith, METH_VARARGS, endswith__doc__},
- {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
+ {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
expandtabs__doc__},
{"extend", (PyCFunction)bytearray_extend, METH_O, extend__doc__},
{"find", (PyCFunction)bytearray_find, METH_VARARGS, find__doc__},
@@ -3000,7 +2982,7 @@ bytearrayiter_next(bytesiterobject *it)
if (it->it_index < PyByteArray_GET_SIZE(seq)) {
item = PyLong_FromLong(
- (unsigned char)seq->ob_bytes[it->it_index]);
+ (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index]);
if (item != NULL)
++it->it_index;
return item;