diff options
Diffstat (limited to 'Objects/bytesobject.c')
-rw-r--r-- | Objects/bytesobject.c | 470 |
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; |