/* PyByteArray (bytearray) implementation */ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() #include "pycore_bytes_methods.h" #include "pycore_bytesobject.h" #include "pycore_ceval.h" // _PyEval_GetBuiltin() #include "pycore_object.h" // _PyObject_GC_UNTRACK() #include "pycore_strhex.h" // _Py_strhex_with_sep() #include "pycore_long.h" // _PyLong_FromUnsignedChar() #include "bytesobject.h" /*[clinic input] class bytearray "PyByteArrayObject *" "&PyByteArray_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/ /* For PyByteArray_AS_STRING(). */ char _PyByteArray_empty_string[] = …; /* Helpers */ static int _getbytevalue(PyObject* arg, int *value) { … } static int bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags) { … } static void bytearray_releasebuffer(PyObject *self, Py_buffer *view) { … } static int _canresize(PyByteArrayObject *self) { … } #include "clinic/bytearrayobject.c.h" /* Direct API functions */ PyObject * PyByteArray_FromObject(PyObject *input) { … } static PyObject * _PyByteArray_FromBufferObject(PyObject *obj) { … } PyObject * PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size) { … } Py_ssize_t PyByteArray_Size(PyObject *self) { … } char * PyByteArray_AsString(PyObject *self) { … } int PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size) { … } PyObject * PyByteArray_Concat(PyObject *a, PyObject *b) { … } /* Functions stuffed into the type object */ static Py_ssize_t bytearray_length(PyObject *op) { … } static PyObject * bytearray_iconcat(PyObject *op, PyObject *other) { … } static PyObject * bytearray_repeat(PyObject *op, Py_ssize_t count) { … } static PyObject * bytearray_irepeat(PyObject *op, Py_ssize_t count) { … } static PyObject * bytearray_getitem(PyObject *op, Py_ssize_t i) { … } static PyObject * bytearray_subscript(PyObject *op, PyObject *index) { … } static int bytearray_setslice_linear(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, char *bytes, Py_ssize_t bytes_len) { … } static int bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, PyObject *values) { … } static int bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value) { … } static int bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values) { … } /*[clinic input] bytearray.__init__ source as arg: object = NULL encoding: str = NULL errors: str = NULL [clinic start generated code]*/ static int bytearray___init___impl(PyByteArrayObject *self, PyObject *arg, const char *encoding, const char *errors) /*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/ { … } /* Mostly copied from string_repr, but without the "smart quote" functionality. */ static PyObject * bytearray_repr(PyObject *op) { … } static PyObject * bytearray_str(PyObject *op) { … } static PyObject * bytearray_richcompare(PyObject *self, PyObject *other, int op) { … } static void bytearray_dealloc(PyObject *op) { … } /* -------------------------------------------------------------------- */ /* Methods */ #define STRINGLIB_IS_UNICODE … #define FASTSEARCH … #define STRINGLIB(F) … #define STRINGLIB_CHAR … #define STRINGLIB_SIZEOF_CHAR … #define STRINGLIB_LEN … #define STRINGLIB_STR … #define STRINGLIB_NEW … #define STRINGLIB_ISSPACE … #define STRINGLIB_ISLINEBREAK(x) … #define STRINGLIB_CHECK_EXACT … #define STRINGLIB_FAST_MEMCHR … #define STRINGLIB_MUTABLE … #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" #include "stringlib/transmogrify.h" /*[clinic input] @text_signature "($self, sub[, start[, end]], /)" bytearray.find sub: object start: slice_index(accept={int, NoneType}, c_default='0') = None Optional start position. Default: start of the bytes. end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None Optional stop position. Default: end of the bytes. / Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end]. Return -1 on failure. [clinic start generated code]*/ static PyObject * bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=413e1cab2ae87da0 input=793dfad803e2952f]*/ { … } /*[clinic input] bytearray.count = bytearray.find Return the number of non-overlapping occurrences of subsection 'sub' in bytes B[start:end]. [clinic start generated code]*/ static PyObject * bytearray_count_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=a21ee2692e4f1233 input=4deb529db38deda8]*/ { … } /*[clinic input] bytearray.clear Remove all items from the bytearray. [clinic start generated code]*/ static PyObject * bytearray_clear_impl(PyByteArrayObject *self) /*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/ { … } /*[clinic input] bytearray.copy Return a copy of B. [clinic start generated code]*/ static PyObject * bytearray_copy_impl(PyByteArrayObject *self) /*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/ { … } /*[clinic input] bytearray.index = bytearray.find Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end]. Raise ValueError if the subsection is not found. [clinic start generated code]*/ static PyObject * bytearray_index_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=067a1e78efc672a7 input=8cbaf6836dbd2a9a]*/ { … } /*[clinic input] bytearray.rfind = bytearray.find Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end]. Return -1 on failure. [clinic start generated code]*/ static PyObject * bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=51bf886f932b283c input=eaa107468a158423]*/ { … } /*[clinic input] bytearray.rindex = bytearray.find Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end]. Raise ValueError if the subsection is not found. [clinic start generated code]*/ static PyObject * bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=38e1cf66bafb08b9 input=81cf49d0af4d5bd0]*/ { … } static int bytearray_contains(PyObject *self, PyObject *arg) { … } /*[clinic input] @text_signature "($self, prefix[, start[, end]], /)" bytearray.startswith prefix as subobj: object A bytes or a tuple of bytes to try. start: slice_index(accept={int, NoneType}, c_default='0') = None Optional start position. Default: start of the bytearray. end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None Optional stop position. Default: end of the bytearray. / Return True if the bytearray starts with the specified prefix, False otherwise. [clinic start generated code]*/ static PyObject * bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=a3d9b6d44d3662a6 input=76385e0b376b45c1]*/ { … } /*[clinic input] @text_signature "($self, suffix[, start[, end]], /)" bytearray.endswith suffix as subobj: object A bytes or a tuple of bytes to try. start: slice_index(accept={int, NoneType}, c_default='0') = None Optional start position. Default: start of the bytearray. end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None Optional stop position. Default: end of the bytearray. / Return True if the bytearray ends with the specified suffix, False otherwise. [clinic start generated code]*/ static PyObject * bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj, Py_ssize_t start, Py_ssize_t end) /*[clinic end generated code: output=e75ea8c227954caa input=9b8baa879aa3d74b]*/ { … } /*[clinic input] bytearray.removeprefix as bytearray_removeprefix prefix: Py_buffer / Return a bytearray with the given prefix string removed if present. If the bytearray starts with the prefix string, return bytearray[len(prefix):]. Otherwise, return a copy of the original bytearray. [clinic start generated code]*/ static PyObject * bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix) /*[clinic end generated code: output=6cabc585e7f502e0 input=968aada38aedd262]*/ { … } /*[clinic input] bytearray.removesuffix as bytearray_removesuffix suffix: Py_buffer / Return a bytearray with the given suffix string removed if present. If the bytearray ends with the suffix string and that suffix is not empty, return bytearray[:-len(suffix)]. Otherwise, return a copy of the original bytearray. [clinic start generated code]*/ static PyObject * bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix) /*[clinic end generated code: output=2bc8cfb79de793d3 input=c1827e810b2f6b99]*/ { … } /*[clinic input] bytearray.translate table: object Translation table, which must be a bytes object of length 256. / delete as deletechars: object(c_default="NULL") = b'' Return a copy with each character mapped by the given translation table. All characters occurring in the optional argument delete are removed. The remaining characters are mapped through the given translation table. [clinic start generated code]*/ static PyObject * bytearray_translate_impl(PyByteArrayObject *self, PyObject *table, PyObject *deletechars) /*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/ { … } /*[clinic input] @staticmethod bytearray.maketrans frm: Py_buffer to: Py_buffer / Return a translation table usable for the bytes or bytearray translate method. The returned table will be one where each byte in frm is mapped to the byte at the same position in to. The bytes objects frm and to must be of the same length. [clinic start generated code]*/ static PyObject * bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to) /*[clinic end generated code: output=1df267d99f56b15e input=b10de38c85950a63]*/ { … } /*[clinic input] bytearray.replace old: Py_buffer new: Py_buffer count: Py_ssize_t = -1 Maximum number of occurrences to replace. -1 (the default value) means replace all occurrences. / Return a copy with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. [clinic start generated code]*/ static PyObject * bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old, Py_buffer *new, Py_ssize_t count) /*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/ { … } /*[clinic input] bytearray.split sep: object = None The delimiter according which to split the bytearray. None (the default value) means split on ASCII whitespace characters (space, tab, return, newline, formfeed, vertical tab). maxsplit: Py_ssize_t = -1 Maximum number of splits to do. -1 (the default value) means no limit. Return a list of the sections in the bytearray, using sep as the delimiter. [clinic start generated code]*/ static PyObject * bytearray_split_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit) /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/ { … } /*[clinic input] bytearray.partition sep: object / Partition the bytearray into three parts using the given separator. This will search for the separator sep in the bytearray. If the separator is found, returns a 3-tuple containing the part before the separator, the separator itself, and the part after it as new bytearray objects. If the separator is not found, returns a 3-tuple containing the copy of the original bytearray object and two empty bytearray objects. [clinic start generated code]*/ static PyObject * bytearray_partition(PyByteArrayObject *self, PyObject *sep) /*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/ { … } /*[clinic input] bytearray.rpartition sep: object / Partition the bytearray into three parts using the given separator. This will search for the separator sep in the bytearray, starting at the end. If the separator is found, returns a 3-tuple containing the part before the separator, the separator itself, and the part after it as new bytearray objects. If the separator is not found, returns a 3-tuple containing two empty bytearray objects and the copy of the original bytearray object. [clinic start generated code]*/ static PyObject * bytearray_rpartition(PyByteArrayObject *self, PyObject *sep) /*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/ { … } /*[clinic input] bytearray.rsplit = bytearray.split Return a list of the sections in the bytearray, using sep as the delimiter. Splitting is done starting at the end of the bytearray and working to the front. [clinic start generated code]*/ static PyObject * bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep, Py_ssize_t maxsplit) /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/ { … } /*[clinic input] bytearray.reverse Reverse the order of the values in B in place. [clinic start generated code]*/ static PyObject * bytearray_reverse_impl(PyByteArrayObject *self) /*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/ { … } /*[python input] class bytesvalue_converter(CConverter): type = 'int' converter = '_getbytevalue' [python start generated code]*/ /*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/ /*[clinic input] bytearray.insert index: Py_ssize_t The index where the value is to be inserted. item: bytesvalue The item to be inserted. / Insert a single item into the bytearray before the given index. [clinic start generated code]*/ static PyObject * bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item) /*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/ { … } /*[clinic input] bytearray.append item: bytesvalue The item to be appended. / Append a single item to the end of the bytearray. [clinic start generated code]*/ static PyObject * bytearray_append_impl(PyByteArrayObject *self, int item) /*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/ { … } /*[clinic input] bytearray.extend iterable_of_ints: object The iterable of items to append. / Append all the items from the iterator or sequence to the end of the bytearray. [clinic start generated code]*/ static PyObject * bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints) /*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/ { … } /*[clinic input] bytearray.pop index: Py_ssize_t = -1 The index from where to remove the item. -1 (the default value) means remove the last item. / Remove and return a single item from B. If no index argument is given, will pop the last item. [clinic start generated code]*/ static PyObject * bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index) /*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/ { … } /*[clinic input] bytearray.remove value: bytesvalue The value to remove. / Remove the first occurrence of a value in the bytearray. [clinic start generated code]*/ static PyObject * bytearray_remove_impl(PyByteArrayObject *self, int value) /*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/ { … } #define LEFTSTRIP … #define RIGHTSTRIP … #define BOTHSTRIP … static PyObject* bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype) { … } /*[clinic input] bytearray.strip bytes: object = None / Strip leading and trailing bytes contained in the argument. If the argument is omitted or None, strip leading and trailing ASCII whitespace. [clinic start generated code]*/ static PyObject * bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/ { … } /*[clinic input] bytearray.lstrip bytes: object = None / Strip leading bytes contained in the argument. If the argument is omitted or None, strip leading ASCII whitespace. [clinic start generated code]*/ static PyObject * bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/ { … } /*[clinic input] bytearray.rstrip bytes: object = None / Strip trailing bytes contained in the argument. If the argument is omitted or None, strip trailing ASCII whitespace. [clinic start generated code]*/ static PyObject * bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes) /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/ { … } /*[clinic input] bytearray.decode encoding: str(c_default="NULL") = 'utf-8' The encoding with which to decode the bytearray. errors: str(c_default="NULL") = 'strict' The error handling scheme to use for the handling of decoding errors. The default is 'strict' meaning that decoding errors raise a UnicodeDecodeError. Other possible values are 'ignore' and 'replace' as well as any other name registered with codecs.register_error that can handle UnicodeDecodeErrors. Decode the bytearray using the codec registered for encoding. [clinic start generated code]*/ static PyObject * bytearray_decode_impl(PyByteArrayObject *self, const char *encoding, const char *errors) /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/ { … } PyDoc_STRVAR(alloc_doc, "B.__alloc__() -> int\n\ \n\ Return the number of bytes actually allocated."); static PyObject * bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored)) { … } /*[clinic input] bytearray.join iterable_of_bytes: object / Concatenate any number of bytes/bytearray objects. The bytearray whose method is called is inserted in between each pair. The result is returned as a new bytearray object. [clinic start generated code]*/ static PyObject * bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes) /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/ { … } /*[clinic input] bytearray.splitlines keepends: bool = False Return a list of the lines in the bytearray, breaking at line boundaries. Line breaks are not included in the resulting list unless keepends is given and true. [clinic start generated code]*/ static PyObject * bytearray_splitlines_impl(PyByteArrayObject *self, int keepends) /*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/ { … } /*[clinic input] @classmethod bytearray.fromhex string: unicode / Create a bytearray object from a string of hexadecimal numbers. Spaces between two numbers are accepted. Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef') [clinic start generated code]*/ static PyObject * bytearray_fromhex_impl(PyTypeObject *type, PyObject *string) /*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/ { … } /*[clinic input] bytearray.hex sep: object = NULL An optional single character or byte to separate hex bytes. bytes_per_sep: int = 1 How many bytes between separators. Positive values count from the right, negative values count from the left. Create a string of hexadecimal numbers from a bytearray object. Example: >>> value = bytearray([0xb9, 0x01, 0xef]) >>> value.hex() 'b901ef' >>> value.hex(':') 'b9:01:ef' >>> value.hex(':', 2) 'b9:01ef' >>> value.hex(':', -2) 'b901:ef' [clinic start generated code]*/ static PyObject * bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep) /*[clinic end generated code: output=29c4e5ef72c565a0 input=808667e49bcccb54]*/ { … } static PyObject * _common_reduce(PyByteArrayObject *self, int proto) { … } /*[clinic input] bytearray.__reduce__ as bytearray_reduce Return state information for pickling. [clinic start generated code]*/ static PyObject * bytearray_reduce_impl(PyByteArrayObject *self) /*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/ { … } /*[clinic input] bytearray.__reduce_ex__ as bytearray_reduce_ex proto: int = 0 / Return state information for pickling. [clinic start generated code]*/ static PyObject * bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto) /*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/ { … } /*[clinic input] bytearray.__sizeof__ as bytearray_sizeof Returns the size of the bytearray object in memory, in bytes. [clinic start generated code]*/ static PyObject * bytearray_sizeof_impl(PyByteArrayObject *self) /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/ { … } static PySequenceMethods bytearray_as_sequence = …; static PyMappingMethods bytearray_as_mapping = …; static PyBufferProcs bytearray_as_buffer = …; static PyMethodDef bytearray_methods[] = …; static PyObject * bytearray_mod(PyObject *v, PyObject *w) { … } static PyNumberMethods bytearray_as_number = …; PyDoc_STRVAR(bytearray_doc, "bytearray(iterable_of_ints) -> bytearray\n\ bytearray(string, encoding[, errors]) -> bytearray\n\ bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\ bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\ bytearray() -> empty bytes array\n\ \n\ Construct a mutable bytearray object from:\n\ - an iterable yielding integers in range(256)\n\ - a text string encoded using the specified encoding\n\ - a bytes or a buffer object\n\ - any object implementing the buffer API.\n\ - an integer"); static PyObject *bytearray_iter(PyObject *seq); PyTypeObject PyByteArray_Type = …; /*********************** Bytearray Iterator ****************************/ bytesiterobject; static void bytearrayiter_dealloc(bytesiterobject *it) { … } static int bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg) { … } static PyObject * bytearrayiter_next(bytesiterobject *it) { … } static PyObject * bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { … } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); static PyObject * bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored)) { … } static PyObject * bytearrayiter_setstate(bytesiterobject *it, PyObject *state) { … } PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); static PyMethodDef bytearrayiter_methods[] = …; PyTypeObject PyByteArrayIter_Type = …; static PyObject * bytearray_iter(PyObject *seq) { … }