From f3c5faeadd86aa90257f1c42717b741b33c653fc Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Tue, 24 Dec 2013 16:29:36 +0100 Subject: [PATCH] inline bytearray.append() --- Cython/Compiler/Builtin.py | 5 ++++- Cython/Utility/StringTools.c | 33 ++++++++++++++++++++++++++++ tests/run/bytearraymethods.pyx | 49 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index b6c509d..68a8f10 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -280,7 +280,10 @@ builtin_types_table = [ BuiltinMethod("join", "TO", "T", "__Pyx_PyBaseString_Join", utility_code=UtilityCode.load("StringJoin", "StringTools.c")), ]), - ("bytearray", "PyByteArray_Type", []), + ("bytearray", "PyByteArray_Type", [ + BuiltinMethod("append", "Tz", "r", "__Pyx_PyByteArray_Append", + utility_code=UtilityCode.load("ByteArrayAppend", "StringTools.c")), + ]), ("bytes", "PyBytes_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), BuiltinMethod("join", "TO", "O", "__Pyx_PyBytes_Join", utility_code=UtilityCode.load("StringJoin", "StringTools.c")), diff --git a/Cython/Utility/StringTools.c b/Cython/Utility/StringTools.c index 57a0d54..da71ef6 100644 --- a/Cython/Utility/StringTools.c +++ b/Cython/Utility/StringTools.c @@ -678,3 +678,36 @@ static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* value return PyObject_CallMethodObjArgs(sep, PYIDENT("join"), values, NULL) } #endif + + +//////////////////// ByteArrayAppend.proto //////////////////// + +static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, Py_ssize_t value); + +//////////////////// ByteArrayAppend //////////////////// +//@requires: ObjectHandling.c::PyObjectCallMethod + +// signature uses Py_ssize_t to make coercions use PyNumber_Index(), as CPython does +static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, Py_ssize_t value) { + PyObject *pyval, *retval; +#if CYTHON_COMPILING_IN_CPYTHON + Py_ssize_t n = Py_SIZE(bytearray); + if (likely((value >= 0) & (value <= 255))) { + if (likely(n < PY_SSIZE_T_MAX)) { + if (unlikely(PyByteArray_Resize(bytearray, n + 1) < 0)) + return -1; + PyByteArray_AS_STRING(bytearray)[n] = value; + return 0; + } + } +#endif + pyval = PyInt_FromLong(value); + if (unlikely(!pyval)) + return -1; + retval = __Pyx_PyObject_CallMethod1(bytearray, PYIDENT("append"), pyval); + Py_DECREF(pyval); + if (unlikely(!retval)) + return -1; + Py_DECREF(retval); + return 0; +} diff --git a/tests/run/bytearraymethods.pyx b/tests/run/bytearraymethods.pyx index c18c03d..6816972 100644 --- a/tests/run/bytearraymethods.pyx +++ b/tests/run/bytearraymethods.pyx @@ -193,3 +193,52 @@ def bytearray_decode_unbound_method(bytearray s, start=None, stop=None): return bytearray.decode(s[start:], 'utf8') else: return bytearray.decode(s[start:stop], 'utf8') + + +def bytearray_append(bytearray b, char c, int i, object o): + """ + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, ord('x'), ord('y'), ord('z')) + >>> print(b.decode('ascii')) + abcXxyz + + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, -1, ord('y'), ord('z')) # doctest: +ELLIPSIS + Traceback (most recent call last): + ValueError: ... + >>> print(b.decode('ascii')) + abcX + + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, ord('x'), -1, ord('z')) # doctest: +ELLIPSIS + Traceback (most recent call last): + ValueError: ... + >>> print(b.decode('ascii')) + abcXx + + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, ord('x'), 256, ord('z')) # doctest: +ELLIPSIS + Traceback (most recent call last): + ValueError: ... + >>> print(b.decode('ascii')) + abcXx + + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, ord('x'), ord('y'), -1) # doctest: +ELLIPSIS + Traceback (most recent call last): + ValueError: ... + >>> print(b.decode('ascii')) + abcXxy + + >>> b = bytearray('abc'.encode('ascii')) + >>> b = bytearray_append(b, ord('x'), ord('y'), 256) # doctest: +ELLIPSIS + Traceback (most recent call last): + ValueError: ... + >>> print(b.decode('ascii')) + abcXxy + """ + b.append('X') + b.append(c) + b.append(i) + b.append(o) + return b -- 2.7.4