summaryrefslogtreecommitdiff
path: root/Objects/bytesobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/bytesobject.c')
-rw-r--r--Objects/bytesobject.c470
1 files changed, 198 insertions, 272 deletions
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 32c5d71ecd..27f4069472 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -7,24 +7,6 @@
#include "bytes_methods.h"
#include <stddef.h>
-static Py_ssize_t
-_getbuffer(PyObject *obj, Py_buffer *view)
-{
- PyBufferProcs *buffer = Py_TYPE(obj)->tp_as_buffer;
-
- if (buffer == NULL || buffer->bf_getbuffer == NULL)
- {
- PyErr_Format(PyExc_TypeError,
- "Type %.100s doesn't support the buffer API",
- Py_TYPE(obj)->tp_name);
- return -1;
- }
-
- if (buffer->bf_getbuffer(obj, view, PyBUF_SIMPLE) < 0)
- return -1;
- return view->len;
-}
-
#ifdef COUNT_ALLOCS
Py_ssize_t null_strings, one_strings;
#endif
@@ -65,7 +47,7 @@ static PyBytesObject *nullstring;
PyObject *
PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
{
- register PyBytesObject *op;
+ PyBytesObject *op;
if (size < 0) {
PyErr_SetString(PyExc_SystemError,
"Negative size passed to PyBytes_FromStringAndSize");
@@ -98,7 +80,7 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyBytes_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
op->ob_shash = -1;
if (str != NULL)
Py_MEMCPY(op->ob_sval, str, size);
@@ -117,8 +99,8 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)
PyObject *
PyBytes_FromString(const char *str)
{
- register size_t size;
- register PyBytesObject *op;
+ size_t size;
+ PyBytesObject *op;
assert(str != NULL);
size = strlen(str);
@@ -146,7 +128,7 @@ PyBytes_FromString(const char *str)
op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyBytes_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
op->ob_shash = -1;
Py_MEMCPY(op->ob_sval, str, size+1);
/* share short strings */
@@ -517,7 +499,7 @@ PyObject *PyBytes_DecodeEscape(const char *s,
/* object api */
Py_ssize_t
-PyBytes_Size(register PyObject *op)
+PyBytes_Size(PyObject *op)
{
if (!PyBytes_Check(op)) {
PyErr_Format(PyExc_TypeError,
@@ -528,7 +510,7 @@ PyBytes_Size(register PyObject *op)
}
char *
-PyBytes_AsString(register PyObject *op)
+PyBytes_AsString(PyObject *op)
{
if (!PyBytes_Check(op)) {
PyErr_Format(PyExc_TypeError,
@@ -539,9 +521,9 @@ PyBytes_AsString(register PyObject *op)
}
int
-PyBytes_AsStringAndSize(register PyObject *obj,
- register char **s,
- register Py_ssize_t *len)
+PyBytes_AsStringAndSize(PyObject *obj,
+ char **s,
+ Py_ssize_t *len)
{
if (s == NULL) {
PyErr_BadInternalCall();
@@ -573,6 +555,7 @@ PyBytes_AsStringAndSize(register PyObject *obj,
#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"
@@ -582,7 +565,7 @@ PyBytes_AsStringAndSize(register PyObject *obj,
PyObject *
PyBytes_Repr(PyObject *obj, int smartquotes)
{
- register PyBytesObject* op = (PyBytesObject*) obj;
+ PyBytesObject* op = (PyBytesObject*) obj;
Py_ssize_t i, length = Py_SIZE(op);
Py_ssize_t newsize, squotes, dquotes;
PyObject *v;
@@ -685,8 +668,8 @@ bytes_concat(PyObject *a, PyObject *b)
va.len = -1;
vb.len = -1;
- if (_getbuffer(a, &va) < 0 ||
- _getbuffer(b, &vb) < 0) {
+ if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
+ PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
Py_TYPE(a)->tp_name, Py_TYPE(b)->tp_name);
goto done;
@@ -725,12 +708,12 @@ bytes_concat(PyObject *a, PyObject *b)
}
static PyObject *
-bytes_repeat(register PyBytesObject *a, register Py_ssize_t n)
+bytes_repeat(PyBytesObject *a, Py_ssize_t n)
{
- register Py_ssize_t i;
- register Py_ssize_t j;
- register Py_ssize_t size;
- register PyBytesObject *op;
+ Py_ssize_t i;
+ Py_ssize_t j;
+ Py_ssize_t size;
+ PyBytesObject *op;
size_t nbytes;
if (n < 0)
n = 0;
@@ -756,7 +739,7 @@ bytes_repeat(register PyBytesObject *a, register Py_ssize_t n)
op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes);
if (op == NULL)
return PyErr_NoMemory();
- PyObject_INIT_VAR(op, &PyBytes_Type, size);
+ (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
op->ob_shash = -1;
op->ob_sval[size] = '\0';
if (Py_SIZE(a) == 1 && n > 0) {
@@ -784,7 +767,7 @@ bytes_contains(PyObject *self, PyObject *arg)
Py_buffer varg;
Py_ssize_t pos;
PyErr_Clear();
- if (_getbuffer(arg, &varg) < 0)
+ if (PyObject_GetBuffer(arg, &varg, PyBUF_SIMPLE) != 0)
return -1;
pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self),
varg.buf, varg.len, 0);
@@ -800,7 +783,7 @@ bytes_contains(PyObject *self, PyObject *arg)
}
static PyObject *
-bytes_item(PyBytesObject *a, register Py_ssize_t i)
+bytes_item(PyBytesObject *a, Py_ssize_t i)
{
if (i < 0 || i >= Py_SIZE(a)) {
PyErr_SetString(PyExc_IndexError, "index out of range");
@@ -809,6 +792,23 @@ bytes_item(PyBytesObject *a, register Py_ssize_t i)
return PyLong_FromLong((unsigned char)a->ob_sval[i]);
}
+Py_LOCAL(int)
+bytes_compare_eq(PyBytesObject *a, PyBytesObject *b)
+{
+ int cmp;
+ Py_ssize_t len;
+
+ len = Py_SIZE(a);
+ if (Py_SIZE(b) != len)
+ return 0;
+
+ if (a->ob_sval[0] != b->ob_sval[0])
+ return 0;
+
+ cmp = memcmp(a->ob_sval, b->ob_sval, len);
+ return (cmp == 0);
+}
+
static PyObject*
bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
{
@@ -816,66 +816,74 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
Py_ssize_t len_a, len_b;
Py_ssize_t min_len;
PyObject *result;
+ int rc;
/* Make sure both arguments are strings. */
if (!(PyBytes_Check(a) && PyBytes_Check(b))) {
- if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE) &&
- (PyObject_IsInstance((PyObject*)a,
- (PyObject*)&PyUnicode_Type) ||
- PyObject_IsInstance((PyObject*)b,
- (PyObject*)&PyUnicode_Type))) {
- if (PyErr_WarnEx(PyExc_BytesWarning,
- "Comparison between bytes and string", 1))
+ if (Py_BytesWarningFlag && (op == Py_EQ || op == Py_NE)) {
+ rc = PyObject_IsInstance((PyObject*)a,
+ (PyObject*)&PyUnicode_Type);
+ if (!rc)
+ rc = PyObject_IsInstance((PyObject*)b,
+ (PyObject*)&PyUnicode_Type);
+ if (rc < 0)
return NULL;
+ if (rc) {
+ if (PyErr_WarnEx(PyExc_BytesWarning,
+ "Comparison between bytes and string", 1))
+ return NULL;
+ }
}
result = Py_NotImplemented;
- goto out;
}
- if (a == b) {
+ else if (a == b) {
switch (op) {
- case Py_EQ:case Py_LE:case Py_GE:
+ case Py_EQ:
+ case Py_LE:
+ case Py_GE:
+ /* a string is equal to itself */
result = Py_True;
- goto out;
- case Py_NE:case Py_LT:case Py_GT:
+ break;
+ case Py_NE:
+ case Py_LT:
+ case Py_GT:
result = Py_False;
- goto out;
+ break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
}
}
- if (op == Py_EQ) {
- /* Supporting Py_NE here as well does not save
- much time, since Py_NE is rarely used. */
- if (Py_SIZE(a) == Py_SIZE(b)
- && (a->ob_sval[0] == b->ob_sval[0]
- && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) {
- result = Py_True;
- } else {
- result = Py_False;
+ else if (op == Py_EQ || op == Py_NE) {
+ int eq = bytes_compare_eq(a, b);
+ eq ^= (op == Py_NE);
+ result = eq ? Py_True : Py_False;
+ }
+ else {
+ len_a = Py_SIZE(a);
+ len_b = Py_SIZE(b);
+ min_len = Py_MIN(len_a, len_b);
+ if (min_len > 0) {
+ c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
+ if (c == 0)
+ c = memcmp(a->ob_sval, b->ob_sval, min_len);
}
- goto out;
- }
- len_a = Py_SIZE(a); len_b = Py_SIZE(b);
- min_len = (len_a < len_b) ? len_a : len_b;
- if (min_len > 0) {
- c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
- if (c==0)
- c = memcmp(a->ob_sval, b->ob_sval, min_len);
- } else
- c = 0;
- if (c == 0)
- c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
- switch (op) {
- case Py_LT: c = c < 0; break;
- case Py_LE: c = c <= 0; break;
- case Py_EQ: assert(0); break; /* unreachable */
- case Py_NE: c = c != 0; break;
- case Py_GT: c = c > 0; break;
- case Py_GE: c = c >= 0; break;
- default:
- result = Py_NotImplemented;
- goto out;
+ else
+ c = 0;
+ if (c == 0)
+ c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
+ switch (op) {
+ case Py_LT: c = c < 0; break;
+ case Py_LE: c = c <= 0; break;
+ case Py_GT: c = c > 0; break;
+ case Py_GE: c = c >= 0; break;
+ default:
+ PyErr_BadArgument();
+ return NULL;
+ }
+ result = c ? Py_True : Py_False;
}
- result = c ? Py_True : Py_False;
- out:
+
Py_INCREF(result);
return result;
}
@@ -885,7 +893,7 @@ bytes_hash(PyBytesObject *a)
{
if (a->ob_shash == -1) {
/* Can't fail */
- a->ob_shash = _Py_HashBytes((unsigned char *) a->ob_sval, Py_SIZE(a));
+ a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a));
}
return a->ob_shash;
}
@@ -1019,7 +1027,7 @@ bytes_split(PyBytesObject *self, PyObject *args, PyObject *kwds)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(subobj, &vsub) < 0)
+ if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
@@ -1039,21 +1047,19 @@ found, returns B and two empty bytes objects.");
static PyObject *
bytes_partition(PyBytesObject *self, PyObject *sep_obj)
{
- const char *sep;
- Py_ssize_t sep_len;
+ Py_buffer sep = {NULL, NULL};
+ PyObject *res;
- if (PyBytes_Check(sep_obj)) {
- sep = PyBytes_AS_STRING(sep_obj);
- sep_len = PyBytes_GET_SIZE(sep_obj);
- }
- else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+ if (PyObject_GetBuffer(sep_obj, &sep, PyBUF_SIMPLE) != 0)
return NULL;
- return stringlib_partition(
+ res = stringlib_partition(
(PyObject*) self,
PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
- sep_obj, sep, sep_len
+ sep_obj, sep.buf, sep.len
);
+ PyBuffer_Release(&sep);
+ return res;
}
PyDoc_STRVAR(rpartition__doc__,
@@ -1067,21 +1073,19 @@ bytes objects and B.");
static PyObject *
bytes_rpartition(PyBytesObject *self, PyObject *sep_obj)
{
- const char *sep;
- Py_ssize_t sep_len;
+ Py_buffer sep = {NULL, NULL};
+ PyObject *res;
- if (PyBytes_Check(sep_obj)) {
- sep = PyBytes_AS_STRING(sep_obj);
- sep_len = PyBytes_GET_SIZE(sep_obj);
- }
- else if (PyObject_AsCharBuffer(sep_obj, &sep, &sep_len))
+ if (PyObject_GetBuffer(sep_obj, &sep, PyBUF_SIMPLE) != 0)
return NULL;
- return stringlib_rpartition(
+ res = stringlib_rpartition(
(PyObject*) self,
PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self),
- sep_obj, sep, sep_len
+ sep_obj, sep.buf, sep.len
);
+ PyBuffer_Release(&sep);
+ return res;
}
PyDoc_STRVAR(rsplit__doc__,
@@ -1111,7 +1115,7 @@ bytes_rsplit(PyBytesObject *self, PyObject *args, PyObject *kwds)
maxsplit = PY_SSIZE_T_MAX;
if (subobj == Py_None)
return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
- if (_getbuffer(subobj, &vsub) < 0)
+ if (PyObject_GetBuffer(subobj, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
n = vsub.len;
@@ -1129,94 +1133,9 @@ Concatenate any number of bytes objects, with B in between each pair.\n\
Example: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'.");
static PyObject *
-bytes_join(PyObject *self, PyObject *orig)
-{
- char *sep = PyBytes_AS_STRING(self);
- const Py_ssize_t seplen = PyBytes_GET_SIZE(self);
- PyObject *res = NULL;
- char *p;
- Py_ssize_t seqlen = 0;
- size_t sz = 0;
- Py_ssize_t i;
- PyObject *seq, *item;
-
- seq = PySequence_Fast(orig, "");
- if (seq == NULL) {
- return NULL;
- }
-
- seqlen = PySequence_Size(seq);
- if (seqlen == 0) {
- Py_DECREF(seq);
- return PyBytes_FromString("");
- }
- if (seqlen == 1) {
- item = PySequence_Fast_GET_ITEM(seq, 0);
- if (PyBytes_CheckExact(item)) {
- Py_INCREF(item);
- Py_DECREF(seq);
- return item;
- }
- }
-
- /* There are at least two things to join, or else we have a subclass
- * of the builtin types in the sequence.
- * Do a pre-pass to figure out the total amount of space we'll
- * need (sz), and see whether all argument are bytes.
- */
- /* XXX Shouldn't we use _getbuffer() on these items instead? */
- for (i = 0; i < seqlen; i++) {
- const size_t old_sz = sz;
- item = PySequence_Fast_GET_ITEM(seq, i);
- if (!PyBytes_Check(item) && !PyByteArray_Check(item)) {
- PyErr_Format(PyExc_TypeError,
- "sequence item %zd: expected bytes,"
- " %.80s found",
- i, Py_TYPE(item)->tp_name);
- Py_DECREF(seq);
- return NULL;
- }
- sz += Py_SIZE(item);
- if (i != 0)
- sz += seplen;
- if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "join() result is too long for bytes");
- Py_DECREF(seq);
- return NULL;
- }
- }
-
- /* Allocate result space. */
- res = PyBytes_FromStringAndSize((char*)NULL, sz);
- if (res == NULL) {
- Py_DECREF(seq);
- return NULL;
- }
-
- /* Catenate everything. */
- /* I'm not worried about a PyByteArray item growing because there's
- nowhere in this function where we release the GIL. */
- p = PyBytes_AS_STRING(res);
- for (i = 0; i < seqlen; ++i) {
- size_t n;
- char *q;
- if (i) {
- Py_MEMCPY(p, sep, seplen);
- p += seplen;
- }
- item = PySequence_Fast_GET_ITEM(seq, i);
- n = Py_SIZE(item);
- if (PyBytes_Check(item))
- q = PyBytes_AS_STRING(item);
- else
- q = PyByteArray_AS_STRING(item);
- Py_MEMCPY(p, q, n);
- p += n;
- }
-
- Py_DECREF(seq);
- return res;
+bytes_join(PyObject *self, PyObject *iterable)
+{
+ return stringlib_bytes_join(self, iterable);
}
PyObject *
@@ -1258,7 +1177,7 @@ bytes_find_internal(PyBytesObject *self, PyObject *args, int dir)
return -2;
if (subobj) {
- if (_getbuffer(subobj, &subbuf) < 0)
+ if (PyObject_GetBuffer(subobj, &subbuf, PyBUF_SIMPLE) != 0)
return -2;
sub = subbuf.buf;
@@ -1373,7 +1292,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj)
Py_ssize_t seplen;
Py_ssize_t i, j;
- if (_getbuffer(sepobj, &vsep) < 0)
+ if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0)
return NULL;
sep = vsep.buf;
seplen = vsep.len;
@@ -1439,7 +1358,7 @@ do_argstrip(PyBytesObject *self, int striptype, PyObject *args)
{
PyObject *sep = NULL;
- if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
+ if (!PyArg_ParseTuple(args, stripformat[striptype], &sep))
return NULL;
if (sep != NULL && sep != Py_None) {
@@ -1518,7 +1437,7 @@ bytes_count(PyBytesObject *self, PyObject *args)
return NULL;
if (sub_obj) {
- if (_getbuffer(sub_obj, &vsub) < 0)
+ if (PyObject_GetBuffer(sub_obj, &vsub, PyBUF_SIMPLE) != 0)
return NULL;
sub = vsub.buf;
@@ -1553,9 +1472,11 @@ table, which must be a bytes object of length 256.");
static PyObject *
bytes_translate(PyBytesObject *self, PyObject *args)
{
- register char *input, *output;
+ char *input, *output;
+ Py_buffer table_view = {NULL, NULL};
+ Py_buffer del_table_view = {NULL, NULL};
const char *table;
- register Py_ssize_t i, c, changed = 0;
+ Py_ssize_t i, c, changed = 0;
PyObject *input_obj = (PyObject*)self;
const char *output_start, *del_table=NULL;
Py_ssize_t inlen, tablen, dellen = 0;
@@ -1575,12 +1496,17 @@ bytes_translate(PyBytesObject *self, PyObject *args)
table = NULL;
tablen = 256;
}
- else if (PyObject_AsCharBuffer(tableobj, &table, &tablen))
- return NULL;
+ else {
+ if (PyObject_GetBuffer(tableobj, &table_view, PyBUF_SIMPLE) != 0)
+ return NULL;
+ table = table_view.buf;
+ tablen = table_view.len;
+ }
if (tablen != 256) {
PyErr_SetString(PyExc_ValueError,
"translation table must be 256 characters long");
+ PyBuffer_Release(&table_view);
return NULL;
}
@@ -1589,8 +1515,14 @@ bytes_translate(PyBytesObject *self, PyObject *args)
del_table = PyBytes_AS_STRING(delobj);
dellen = PyBytes_GET_SIZE(delobj);
}
- else if (PyObject_AsCharBuffer(delobj, &del_table, &dellen))
- return NULL;
+ else {
+ if (PyObject_GetBuffer(delobj, &del_table_view, PyBUF_SIMPLE) != 0) {
+ PyBuffer_Release(&table_view);
+ return NULL;
+ }
+ del_table = del_table_view.buf;
+ dellen = del_table_view.len;
+ }
}
else {
del_table = NULL;
@@ -1599,8 +1531,11 @@ bytes_translate(PyBytesObject *self, PyObject *args)
inlen = PyBytes_GET_SIZE(input_obj);
result = PyBytes_FromStringAndSize((char *)NULL, inlen);
- if (result == NULL)
+ if (result == NULL) {
+ PyBuffer_Release(&del_table_view);
+ PyBuffer_Release(&table_view);
return NULL;
+ }
output_start = output = PyBytes_AsString(result);
input = PyBytes_AS_STRING(input_obj);
@@ -1611,11 +1546,14 @@ bytes_translate(PyBytesObject *self, PyObject *args)
if (Py_CHARMASK((*output++ = table[c])) != c)
changed = 1;
}
- if (changed || !PyBytes_CheckExact(input_obj))
- return result;
- Py_DECREF(result);
- Py_INCREF(input_obj);
- return input_obj;
+ if (!changed && PyBytes_CheckExact(input_obj)) {
+ Py_INCREF(input_obj);
+ Py_DECREF(result);
+ result = input_obj;
+ }
+ PyBuffer_Release(&del_table_view);
+ PyBuffer_Release(&table_view);
+ return result;
}
if (table == NULL) {
@@ -1625,9 +1563,11 @@ bytes_translate(PyBytesObject *self, PyObject *args)
for (i = 0; i < 256; i++)
trans_table[i] = Py_CHARMASK(table[i]);
}
+ PyBuffer_Release(&table_view);
for (i = 0; i < dellen; i++)
trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
+ PyBuffer_Release(&del_table_view);
for (i = inlen; --i >= 0; ) {
c = Py_CHARMASK(*input++);
@@ -2156,31 +2096,21 @@ given, only first count occurances are replaced.");
static PyObject *
bytes_replace(PyBytesObject *self, PyObject *args)
{
+ PyObject *res;
+ Py_buffer old = {NULL, NULL};
+ Py_buffer new = {NULL, NULL};
Py_ssize_t count = -1;
- PyObject *from, *to;
- const char *from_s, *to_s;
- Py_ssize_t from_len, to_len;
- if (!PyArg_ParseTuple(args, "OO|n:replace", &from, &to, &count))
+ if (!PyArg_ParseTuple(args, "y*y*|n:replace", &old, &new, &count))
return NULL;
- if (PyBytes_Check(from)) {
- from_s = PyBytes_AS_STRING(from);
- from_len = PyBytes_GET_SIZE(from);
- }
- else if (PyObject_AsCharBuffer(from, &from_s, &from_len))
- return NULL;
-
- if (PyBytes_Check(to)) {
- to_s = PyBytes_AS_STRING(to);
- to_len = PyBytes_GET_SIZE(to);
- }
- else if (PyObject_AsCharBuffer(to, &to_s, &to_len))
- return NULL;
+ res = (PyObject *)replace((PyBytesObject *) self,
+ (const char *)old.buf, old.len,
+ (const char *)new.buf, new.len, count);
- return (PyObject *)replace((PyBytesObject *) self,
- from_s, from_len,
- to_s, to_len, count);
+ PyBuffer_Release(&old);
+ PyBuffer_Release(&new);
+ return res;
}
/** End DALKE **/
@@ -2195,6 +2125,7 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
{
Py_ssize_t len = PyBytes_GET_SIZE(self);
Py_ssize_t slen;
+ Py_buffer sub_view = {NULL, NULL};
const char* sub;
const char* str;
@@ -2202,8 +2133,12 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
sub = PyBytes_AS_STRING(substr);
slen = PyBytes_GET_SIZE(substr);
}
- else if (PyObject_AsCharBuffer(substr, &sub, &slen))
- return -1;
+ else {
+ if (PyObject_GetBuffer(substr, &sub_view, PyBUF_SIMPLE) != 0)
+ return -1;
+ sub = sub_view.buf;
+ slen = sub_view.len;
+ }
str = PyBytes_AS_STRING(self);
ADJUST_INDICES(start, end, len);
@@ -2211,17 +2146,25 @@ _bytes_tailmatch(PyBytesObject *self, PyObject *substr, Py_ssize_t start,
if (direction < 0) {
/* startswith */
if (start+slen > len)
- return 0;
+ goto notfound;
} else {
/* endswith */
if (end-start < slen || start > len)
- return 0;
+ goto notfound;
if (end-slen > start)
start = end - slen;
}
- if (end-start >= slen)
- return ! memcmp(str+start, sub, slen);
+ if (end-start < slen)
+ goto notfound;
+ if (memcmp(str+start, sub, slen) != 0)
+ goto notfound;
+
+ PyBuffer_Release(&sub_view);
+ return 1;
+
+notfound:
+ PyBuffer_Release(&sub_view);
return 0;
}
@@ -2333,8 +2276,6 @@ bytes_decode(PyObject *self, PyObject *args, PyObject *kwargs)
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss:decode", kwlist, &encoding, &errors))
return NULL;
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
return PyUnicode_FromEncodedObject(self, encoding, errors);
}
@@ -2435,18 +2376,6 @@ bytes_fromhex(PyObject *cls, PyObject *args)
return NULL;
}
-PyDoc_STRVAR(sizeof__doc__,
-"B.__sizeof__() -> size of B in memory, in bytes");
-
-static PyObject *
-bytes_sizeof(PyBytesObject *v)
-{
- Py_ssize_t res;
- res = PyBytesObject_SIZE + Py_SIZE(v) * Py_TYPE(v)->tp_itemsize;
- return PyLong_FromSsize_t(res);
-}
-
-
static PyObject *
bytes_getnewargs(PyBytesObject *v)
{
@@ -2464,7 +2393,7 @@ bytes_methods[] = {
{"decode", (PyCFunction)bytes_decode, METH_VARARGS | METH_KEYWORDS, decode__doc__},
{"endswith", (PyCFunction)bytes_endswith, METH_VARARGS,
endswith__doc__},
- {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS,
+ {"expandtabs", (PyCFunction)stringlib_expandtabs, METH_VARARGS | METH_KEYWORDS,
expandtabs__doc__},
{"find", (PyCFunction)bytes_find, METH_VARARGS, find__doc__},
{"fromhex", (PyCFunction)bytes_fromhex, METH_VARARGS|METH_CLASS,
@@ -2512,13 +2441,11 @@ bytes_methods[] = {
translate__doc__},
{"upper", (PyCFunction)stringlib_upper, METH_NOARGS, _Py_upper__doc__},
{"zfill", (PyCFunction)stringlib_zfill, METH_VARARGS, zfill__doc__},
- {"__sizeof__", (PyCFunction)bytes_sizeof, METH_NOARGS,
- sizeof__doc__},
{NULL, NULL} /* sentinel */
};
static PyObject *
-str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
static PyObject *
bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
@@ -2533,7 +2460,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
_Py_IDENTIFIER(__bytes__);
if (type != &PyBytes_Type)
- return str_subtype_new(type, args, kwds);
+ return bytes_subtype_new(type, args, kwds);
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oss:bytes", kwlist, &x,
&encoding, &errors))
return NULL;
@@ -2561,6 +2488,13 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return new;
}
+ /* If it's not unicode, there can't be encoding or errors */
+ if (encoding != NULL || errors != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "encoding or errors without a string argument");
+ return NULL;
+ }
+
/* We'd like to call PyObject_Bytes here, but we need to check for an
integer argument before deferring to PyBytes_FromObject, something
PyObject_Bytes doesn't do. */
@@ -2602,13 +2536,6 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return new;
}
- /* If it's not unicode, there can't be encoding or errors */
- if (encoding != NULL || errors != NULL) {
- PyErr_SetString(PyExc_TypeError,
- "encoding or errors without a string argument");
- return NULL;
- }
-
return PyBytes_FromObject(x);
}
@@ -2696,7 +2623,7 @@ PyBytes_FromObject(PyObject *x)
}
/* For iterator version, create a string object and resize as needed */
- size = _PyObject_LengthHint(x, 64);
+ size = PyObject_LengthHint(x, 64);
if (size == -1 && PyErr_Occurred())
return NULL;
/* Allocate an extra byte to prevent PyBytes_FromStringAndSize() from
@@ -2754,14 +2681,13 @@ PyBytes_FromObject(PyObject *x)
return new;
error:
- /* Error handling when new != NULL */
Py_XDECREF(it);
- Py_DECREF(new);
+ Py_XDECREF(new);
return NULL;
}
static PyObject *
-str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+bytes_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *tmp, *pnew;
Py_ssize_t n;
@@ -2770,7 +2696,7 @@ str_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
tmp = bytes_new(&PyBytes_Type, args, kwds);
if (tmp == NULL)
return NULL;
- assert(PyBytes_CheckExact(tmp));
+ assert(PyBytes_Check(tmp));
n = PyBytes_GET_SIZE(tmp);
pnew = type->tp_alloc(type, n);
if (pnew != NULL) {
@@ -2842,9 +2768,9 @@ PyTypeObject PyBytes_Type = {
};
void
-PyBytes_Concat(register PyObject **pv, register PyObject *w)
+PyBytes_Concat(PyObject **pv, PyObject *w)
{
- register PyObject *v;
+ PyObject *v;
assert(pv != NULL);
if (*pv == NULL)
return;
@@ -2858,7 +2784,7 @@ PyBytes_Concat(register PyObject **pv, register PyObject *w)
}
void
-PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
+PyBytes_ConcatAndDel(PyObject **pv, PyObject *w)
{
PyBytes_Concat(pv, w);
Py_XDECREF(w);
@@ -2882,8 +2808,8 @@ PyBytes_ConcatAndDel(register PyObject **pv, register PyObject *w)
int
_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
{
- register PyObject *v;
- register PyBytesObject *sv;
+ PyObject *v;
+ PyBytesObject *sv;
v = *pv;
if (!PyBytes_Check(v) || Py_REFCNT(v) != 1 || newsize < 0) {
*pv = 0;