17db96d56Sopenharmony_ci/* bytes object implementation */ 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#define PY_SSIZE_T_CLEAN 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci#include "Python.h" 67db96d56Sopenharmony_ci#include "pycore_abstract.h" // _PyIndex_Check() 77db96d56Sopenharmony_ci#include "pycore_bytesobject.h" // _PyBytes_Find(), _PyBytes_Repeat() 87db96d56Sopenharmony_ci#include "pycore_bytes_methods.h" // _Py_bytes_startswith() 97db96d56Sopenharmony_ci#include "pycore_call.h" // _PyObject_CallNoArgs() 107db96d56Sopenharmony_ci#include "pycore_format.h" // F_LJUST 117db96d56Sopenharmony_ci#include "pycore_global_objects.h" // _Py_GET_GLOBAL_OBJECT() 127db96d56Sopenharmony_ci#include "pycore_initconfig.h" // _PyStatus_OK() 137db96d56Sopenharmony_ci#include "pycore_long.h" // _PyLong_DigitValue 147db96d56Sopenharmony_ci#include "pycore_object.h" // _PyObject_GC_TRACK 157db96d56Sopenharmony_ci#include "pycore_pymem.h" // PYMEM_CLEANBYTE 167db96d56Sopenharmony_ci#include "pycore_strhex.h" // _Py_strhex_with_sep() 177db96d56Sopenharmony_ci 187db96d56Sopenharmony_ci#include <stddef.h> 197db96d56Sopenharmony_ci 207db96d56Sopenharmony_ci/*[clinic input] 217db96d56Sopenharmony_ciclass bytes "PyBytesObject *" "&PyBytes_Type" 227db96d56Sopenharmony_ci[clinic start generated code]*/ 237db96d56Sopenharmony_ci/*[clinic end generated code: output=da39a3ee5e6b4b0d input=7a238f965d64892b]*/ 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci#include "clinic/bytesobject.c.h" 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci/* PyBytesObject_SIZE gives the basic size of a bytes object; any memory allocation 287db96d56Sopenharmony_ci for a bytes object of length n should request PyBytesObject_SIZE + n bytes. 297db96d56Sopenharmony_ci 307db96d56Sopenharmony_ci Using PyBytesObject_SIZE instead of sizeof(PyBytesObject) saves 317db96d56Sopenharmony_ci 3 or 7 bytes per bytes object allocation on a typical system. 327db96d56Sopenharmony_ci*/ 337db96d56Sopenharmony_ci#define PyBytesObject_SIZE (offsetof(PyBytesObject, ob_sval) + 1) 347db96d56Sopenharmony_ci 357db96d56Sopenharmony_ci/* Forward declaration */ 367db96d56Sopenharmony_ciPy_LOCAL_INLINE(Py_ssize_t) _PyBytesWriter_GetSize(_PyBytesWriter *writer, 377db96d56Sopenharmony_ci char *str); 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_ci#define CHARACTERS _Py_SINGLETON(bytes_characters) 417db96d56Sopenharmony_ci#define CHARACTER(ch) \ 427db96d56Sopenharmony_ci ((PyBytesObject *)&(CHARACTERS[ch])); 437db96d56Sopenharmony_ci#define EMPTY (&_Py_SINGLETON(bytes_empty)) 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci// Return a borrowed reference to the empty bytes string singleton. 477db96d56Sopenharmony_cistatic inline PyObject* bytes_get_empty(void) 487db96d56Sopenharmony_ci{ 497db96d56Sopenharmony_ci return &EMPTY->ob_base.ob_base; 507db96d56Sopenharmony_ci} 517db96d56Sopenharmony_ci 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci// Return a strong reference to the empty bytes string singleton. 547db96d56Sopenharmony_cistatic inline PyObject* bytes_new_empty(void) 557db96d56Sopenharmony_ci{ 567db96d56Sopenharmony_ci Py_INCREF(EMPTY); 577db96d56Sopenharmony_ci return (PyObject *)EMPTY; 587db96d56Sopenharmony_ci} 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci 617db96d56Sopenharmony_ci/* 627db96d56Sopenharmony_ci For PyBytes_FromString(), the parameter `str' points to a null-terminated 637db96d56Sopenharmony_ci string containing exactly `size' bytes. 647db96d56Sopenharmony_ci 657db96d56Sopenharmony_ci For PyBytes_FromStringAndSize(), the parameter `str' is 667db96d56Sopenharmony_ci either NULL or else points to a string containing at least `size' bytes. 677db96d56Sopenharmony_ci For PyBytes_FromStringAndSize(), the string in the `str' parameter does 687db96d56Sopenharmony_ci not have to be null-terminated. (Therefore it is safe to construct a 697db96d56Sopenharmony_ci substring by calling `PyBytes_FromStringAndSize(origstring, substrlen)'.) 707db96d56Sopenharmony_ci If `str' is NULL then PyBytes_FromStringAndSize() will allocate `size+1' 717db96d56Sopenharmony_ci bytes (setting the last byte to the null terminating character) and you can 727db96d56Sopenharmony_ci fill in the data yourself. If `str' is non-NULL then the resulting 737db96d56Sopenharmony_ci PyBytes object must be treated as immutable and you must not fill in nor 747db96d56Sopenharmony_ci alter the data yourself, since the strings may be shared. 757db96d56Sopenharmony_ci 767db96d56Sopenharmony_ci The PyObject member `op->ob_size', which denotes the number of "extra 777db96d56Sopenharmony_ci items" in a variable-size object, will contain the number of bytes 787db96d56Sopenharmony_ci allocated for string data, not counting the null terminating character. 797db96d56Sopenharmony_ci It is therefore equal to the `size' parameter (for 807db96d56Sopenharmony_ci PyBytes_FromStringAndSize()) or the length of the string in the `str' 817db96d56Sopenharmony_ci parameter (for PyBytes_FromString()). 827db96d56Sopenharmony_ci*/ 837db96d56Sopenharmony_cistatic PyObject * 847db96d56Sopenharmony_ci_PyBytes_FromSize(Py_ssize_t size, int use_calloc) 857db96d56Sopenharmony_ci{ 867db96d56Sopenharmony_ci PyBytesObject *op; 877db96d56Sopenharmony_ci assert(size >= 0); 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ci if (size == 0) { 907db96d56Sopenharmony_ci return bytes_new_empty(); 917db96d56Sopenharmony_ci } 927db96d56Sopenharmony_ci 937db96d56Sopenharmony_ci if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) { 947db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 957db96d56Sopenharmony_ci "byte string is too large"); 967db96d56Sopenharmony_ci return NULL; 977db96d56Sopenharmony_ci } 987db96d56Sopenharmony_ci 997db96d56Sopenharmony_ci /* Inline PyObject_NewVar */ 1007db96d56Sopenharmony_ci if (use_calloc) 1017db96d56Sopenharmony_ci op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); 1027db96d56Sopenharmony_ci else 1037db96d56Sopenharmony_ci op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); 1047db96d56Sopenharmony_ci if (op == NULL) { 1057db96d56Sopenharmony_ci return PyErr_NoMemory(); 1067db96d56Sopenharmony_ci } 1077db96d56Sopenharmony_ci _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); 1087db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 1097db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 1107db96d56Sopenharmony_ci op->ob_shash = -1; 1117db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 1127db96d56Sopenharmony_ci if (!use_calloc) { 1137db96d56Sopenharmony_ci op->ob_sval[size] = '\0'; 1147db96d56Sopenharmony_ci } 1157db96d56Sopenharmony_ci return (PyObject *) op; 1167db96d56Sopenharmony_ci} 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ciPyObject * 1197db96d56Sopenharmony_ciPyBytes_FromStringAndSize(const char *str, Py_ssize_t size) 1207db96d56Sopenharmony_ci{ 1217db96d56Sopenharmony_ci PyBytesObject *op; 1227db96d56Sopenharmony_ci if (size < 0) { 1237db96d56Sopenharmony_ci PyErr_SetString(PyExc_SystemError, 1247db96d56Sopenharmony_ci "Negative size passed to PyBytes_FromStringAndSize"); 1257db96d56Sopenharmony_ci return NULL; 1267db96d56Sopenharmony_ci } 1277db96d56Sopenharmony_ci if (size == 1 && str != NULL) { 1287db96d56Sopenharmony_ci op = CHARACTER(*str & 255); 1297db96d56Sopenharmony_ci Py_INCREF(op); 1307db96d56Sopenharmony_ci return (PyObject *)op; 1317db96d56Sopenharmony_ci } 1327db96d56Sopenharmony_ci if (size == 0) { 1337db96d56Sopenharmony_ci return bytes_new_empty(); 1347db96d56Sopenharmony_ci } 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_ci op = (PyBytesObject *)_PyBytes_FromSize(size, 0); 1377db96d56Sopenharmony_ci if (op == NULL) 1387db96d56Sopenharmony_ci return NULL; 1397db96d56Sopenharmony_ci if (str == NULL) 1407db96d56Sopenharmony_ci return (PyObject *) op; 1417db96d56Sopenharmony_ci 1427db96d56Sopenharmony_ci memcpy(op->ob_sval, str, size); 1437db96d56Sopenharmony_ci return (PyObject *) op; 1447db96d56Sopenharmony_ci} 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ciPyObject * 1477db96d56Sopenharmony_ciPyBytes_FromString(const char *str) 1487db96d56Sopenharmony_ci{ 1497db96d56Sopenharmony_ci size_t size; 1507db96d56Sopenharmony_ci PyBytesObject *op; 1517db96d56Sopenharmony_ci 1527db96d56Sopenharmony_ci assert(str != NULL); 1537db96d56Sopenharmony_ci size = strlen(str); 1547db96d56Sopenharmony_ci if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) { 1557db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 1567db96d56Sopenharmony_ci "byte string is too long"); 1577db96d56Sopenharmony_ci return NULL; 1587db96d56Sopenharmony_ci } 1597db96d56Sopenharmony_ci 1607db96d56Sopenharmony_ci if (size == 0) { 1617db96d56Sopenharmony_ci return bytes_new_empty(); 1627db96d56Sopenharmony_ci } 1637db96d56Sopenharmony_ci else if (size == 1) { 1647db96d56Sopenharmony_ci op = CHARACTER(*str & 255); 1657db96d56Sopenharmony_ci Py_INCREF(op); 1667db96d56Sopenharmony_ci return (PyObject *)op; 1677db96d56Sopenharmony_ci } 1687db96d56Sopenharmony_ci 1697db96d56Sopenharmony_ci /* Inline PyObject_NewVar */ 1707db96d56Sopenharmony_ci op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size); 1717db96d56Sopenharmony_ci if (op == NULL) { 1727db96d56Sopenharmony_ci return PyErr_NoMemory(); 1737db96d56Sopenharmony_ci } 1747db96d56Sopenharmony_ci _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); 1757db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 1767db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 1777db96d56Sopenharmony_ci op->ob_shash = -1; 1787db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 1797db96d56Sopenharmony_ci memcpy(op->ob_sval, str, size+1); 1807db96d56Sopenharmony_ci return (PyObject *) op; 1817db96d56Sopenharmony_ci} 1827db96d56Sopenharmony_ci 1837db96d56Sopenharmony_ciPyObject * 1847db96d56Sopenharmony_ciPyBytes_FromFormatV(const char *format, va_list vargs) 1857db96d56Sopenharmony_ci{ 1867db96d56Sopenharmony_ci char *s; 1877db96d56Sopenharmony_ci const char *f; 1887db96d56Sopenharmony_ci const char *p; 1897db96d56Sopenharmony_ci Py_ssize_t prec; 1907db96d56Sopenharmony_ci int longflag; 1917db96d56Sopenharmony_ci int size_tflag; 1927db96d56Sopenharmony_ci /* Longest 64-bit formatted numbers: 1937db96d56Sopenharmony_ci - "18446744073709551615\0" (21 bytes) 1947db96d56Sopenharmony_ci - "-9223372036854775808\0" (21 bytes) 1957db96d56Sopenharmony_ci Decimal takes the most space (it isn't enough for octal.) 1967db96d56Sopenharmony_ci 1977db96d56Sopenharmony_ci Longest 64-bit pointer representation: 1987db96d56Sopenharmony_ci "0xffffffffffffffff\0" (19 bytes). */ 1997db96d56Sopenharmony_ci char buffer[21]; 2007db96d56Sopenharmony_ci _PyBytesWriter writer; 2017db96d56Sopenharmony_ci 2027db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_ci s = _PyBytesWriter_Alloc(&writer, strlen(format)); 2057db96d56Sopenharmony_ci if (s == NULL) 2067db96d56Sopenharmony_ci return NULL; 2077db96d56Sopenharmony_ci writer.overallocate = 1; 2087db96d56Sopenharmony_ci 2097db96d56Sopenharmony_ci#define WRITE_BYTES(str) \ 2107db96d56Sopenharmony_ci do { \ 2117db96d56Sopenharmony_ci s = _PyBytesWriter_WriteBytes(&writer, s, (str), strlen(str)); \ 2127db96d56Sopenharmony_ci if (s == NULL) \ 2137db96d56Sopenharmony_ci goto error; \ 2147db96d56Sopenharmony_ci } while (0) 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci for (f = format; *f; f++) { 2177db96d56Sopenharmony_ci if (*f != '%') { 2187db96d56Sopenharmony_ci *s++ = *f; 2197db96d56Sopenharmony_ci continue; 2207db96d56Sopenharmony_ci } 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci p = f++; 2237db96d56Sopenharmony_ci 2247db96d56Sopenharmony_ci /* ignore the width (ex: 10 in "%10s") */ 2257db96d56Sopenharmony_ci while (Py_ISDIGIT(*f)) 2267db96d56Sopenharmony_ci f++; 2277db96d56Sopenharmony_ci 2287db96d56Sopenharmony_ci /* parse the precision (ex: 10 in "%.10s") */ 2297db96d56Sopenharmony_ci prec = 0; 2307db96d56Sopenharmony_ci if (*f == '.') { 2317db96d56Sopenharmony_ci f++; 2327db96d56Sopenharmony_ci for (; Py_ISDIGIT(*f); f++) { 2337db96d56Sopenharmony_ci prec = (prec * 10) + (*f - '0'); 2347db96d56Sopenharmony_ci } 2357db96d56Sopenharmony_ci } 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci while (*f && *f != '%' && !Py_ISALPHA(*f)) 2387db96d56Sopenharmony_ci f++; 2397db96d56Sopenharmony_ci 2407db96d56Sopenharmony_ci /* handle the long flag ('l'), but only for %ld and %lu. 2417db96d56Sopenharmony_ci others can be added when necessary. */ 2427db96d56Sopenharmony_ci longflag = 0; 2437db96d56Sopenharmony_ci if (*f == 'l' && (f[1] == 'd' || f[1] == 'u')) { 2447db96d56Sopenharmony_ci longflag = 1; 2457db96d56Sopenharmony_ci ++f; 2467db96d56Sopenharmony_ci } 2477db96d56Sopenharmony_ci 2487db96d56Sopenharmony_ci /* handle the size_t flag ('z'). */ 2497db96d56Sopenharmony_ci size_tflag = 0; 2507db96d56Sopenharmony_ci if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) { 2517db96d56Sopenharmony_ci size_tflag = 1; 2527db96d56Sopenharmony_ci ++f; 2537db96d56Sopenharmony_ci } 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci /* subtract bytes preallocated for the format string 2567db96d56Sopenharmony_ci (ex: 2 for "%s") */ 2577db96d56Sopenharmony_ci writer.min_size -= (f - p + 1); 2587db96d56Sopenharmony_ci 2597db96d56Sopenharmony_ci switch (*f) { 2607db96d56Sopenharmony_ci case 'c': 2617db96d56Sopenharmony_ci { 2627db96d56Sopenharmony_ci int c = va_arg(vargs, int); 2637db96d56Sopenharmony_ci if (c < 0 || c > 255) { 2647db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 2657db96d56Sopenharmony_ci "PyBytes_FromFormatV(): %c format " 2667db96d56Sopenharmony_ci "expects an integer in range [0; 255]"); 2677db96d56Sopenharmony_ci goto error; 2687db96d56Sopenharmony_ci } 2697db96d56Sopenharmony_ci writer.min_size++; 2707db96d56Sopenharmony_ci *s++ = (unsigned char)c; 2717db96d56Sopenharmony_ci break; 2727db96d56Sopenharmony_ci } 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_ci case 'd': 2757db96d56Sopenharmony_ci if (longflag) { 2767db96d56Sopenharmony_ci sprintf(buffer, "%ld", va_arg(vargs, long)); 2777db96d56Sopenharmony_ci } 2787db96d56Sopenharmony_ci else if (size_tflag) { 2797db96d56Sopenharmony_ci sprintf(buffer, "%zd", va_arg(vargs, Py_ssize_t)); 2807db96d56Sopenharmony_ci } 2817db96d56Sopenharmony_ci else { 2827db96d56Sopenharmony_ci sprintf(buffer, "%d", va_arg(vargs, int)); 2837db96d56Sopenharmony_ci } 2847db96d56Sopenharmony_ci assert(strlen(buffer) < sizeof(buffer)); 2857db96d56Sopenharmony_ci WRITE_BYTES(buffer); 2867db96d56Sopenharmony_ci break; 2877db96d56Sopenharmony_ci 2887db96d56Sopenharmony_ci case 'u': 2897db96d56Sopenharmony_ci if (longflag) { 2907db96d56Sopenharmony_ci sprintf(buffer, "%lu", va_arg(vargs, unsigned long)); 2917db96d56Sopenharmony_ci } 2927db96d56Sopenharmony_ci else if (size_tflag) { 2937db96d56Sopenharmony_ci sprintf(buffer, "%zu", va_arg(vargs, size_t)); 2947db96d56Sopenharmony_ci } 2957db96d56Sopenharmony_ci else { 2967db96d56Sopenharmony_ci sprintf(buffer, "%u", va_arg(vargs, unsigned int)); 2977db96d56Sopenharmony_ci } 2987db96d56Sopenharmony_ci assert(strlen(buffer) < sizeof(buffer)); 2997db96d56Sopenharmony_ci WRITE_BYTES(buffer); 3007db96d56Sopenharmony_ci break; 3017db96d56Sopenharmony_ci 3027db96d56Sopenharmony_ci case 'i': 3037db96d56Sopenharmony_ci sprintf(buffer, "%i", va_arg(vargs, int)); 3047db96d56Sopenharmony_ci assert(strlen(buffer) < sizeof(buffer)); 3057db96d56Sopenharmony_ci WRITE_BYTES(buffer); 3067db96d56Sopenharmony_ci break; 3077db96d56Sopenharmony_ci 3087db96d56Sopenharmony_ci case 'x': 3097db96d56Sopenharmony_ci sprintf(buffer, "%x", va_arg(vargs, int)); 3107db96d56Sopenharmony_ci assert(strlen(buffer) < sizeof(buffer)); 3117db96d56Sopenharmony_ci WRITE_BYTES(buffer); 3127db96d56Sopenharmony_ci break; 3137db96d56Sopenharmony_ci 3147db96d56Sopenharmony_ci case 's': 3157db96d56Sopenharmony_ci { 3167db96d56Sopenharmony_ci Py_ssize_t i; 3177db96d56Sopenharmony_ci 3187db96d56Sopenharmony_ci p = va_arg(vargs, const char*); 3197db96d56Sopenharmony_ci if (prec <= 0) { 3207db96d56Sopenharmony_ci i = strlen(p); 3217db96d56Sopenharmony_ci } 3227db96d56Sopenharmony_ci else { 3237db96d56Sopenharmony_ci i = 0; 3247db96d56Sopenharmony_ci while (i < prec && p[i]) { 3257db96d56Sopenharmony_ci i++; 3267db96d56Sopenharmony_ci } 3277db96d56Sopenharmony_ci } 3287db96d56Sopenharmony_ci s = _PyBytesWriter_WriteBytes(&writer, s, p, i); 3297db96d56Sopenharmony_ci if (s == NULL) 3307db96d56Sopenharmony_ci goto error; 3317db96d56Sopenharmony_ci break; 3327db96d56Sopenharmony_ci } 3337db96d56Sopenharmony_ci 3347db96d56Sopenharmony_ci case 'p': 3357db96d56Sopenharmony_ci sprintf(buffer, "%p", va_arg(vargs, void*)); 3367db96d56Sopenharmony_ci assert(strlen(buffer) < sizeof(buffer)); 3377db96d56Sopenharmony_ci /* %p is ill-defined: ensure leading 0x. */ 3387db96d56Sopenharmony_ci if (buffer[1] == 'X') 3397db96d56Sopenharmony_ci buffer[1] = 'x'; 3407db96d56Sopenharmony_ci else if (buffer[1] != 'x') { 3417db96d56Sopenharmony_ci memmove(buffer+2, buffer, strlen(buffer)+1); 3427db96d56Sopenharmony_ci buffer[0] = '0'; 3437db96d56Sopenharmony_ci buffer[1] = 'x'; 3447db96d56Sopenharmony_ci } 3457db96d56Sopenharmony_ci WRITE_BYTES(buffer); 3467db96d56Sopenharmony_ci break; 3477db96d56Sopenharmony_ci 3487db96d56Sopenharmony_ci case '%': 3497db96d56Sopenharmony_ci writer.min_size++; 3507db96d56Sopenharmony_ci *s++ = '%'; 3517db96d56Sopenharmony_ci break; 3527db96d56Sopenharmony_ci 3537db96d56Sopenharmony_ci default: 3547db96d56Sopenharmony_ci if (*f == 0) { 3557db96d56Sopenharmony_ci /* fix min_size if we reached the end of the format string */ 3567db96d56Sopenharmony_ci writer.min_size++; 3577db96d56Sopenharmony_ci } 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci /* invalid format string: copy unformatted string and exit */ 3607db96d56Sopenharmony_ci WRITE_BYTES(p); 3617db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, s); 3627db96d56Sopenharmony_ci } 3637db96d56Sopenharmony_ci } 3647db96d56Sopenharmony_ci 3657db96d56Sopenharmony_ci#undef WRITE_BYTES 3667db96d56Sopenharmony_ci 3677db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, s); 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ci error: 3707db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 3717db96d56Sopenharmony_ci return NULL; 3727db96d56Sopenharmony_ci} 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ciPyObject * 3757db96d56Sopenharmony_ciPyBytes_FromFormat(const char *format, ...) 3767db96d56Sopenharmony_ci{ 3777db96d56Sopenharmony_ci PyObject* ret; 3787db96d56Sopenharmony_ci va_list vargs; 3797db96d56Sopenharmony_ci 3807db96d56Sopenharmony_ci#ifdef HAVE_STDARG_PROTOTYPES 3817db96d56Sopenharmony_ci va_start(vargs, format); 3827db96d56Sopenharmony_ci#else 3837db96d56Sopenharmony_ci va_start(vargs); 3847db96d56Sopenharmony_ci#endif 3857db96d56Sopenharmony_ci ret = PyBytes_FromFormatV(format, vargs); 3867db96d56Sopenharmony_ci va_end(vargs); 3877db96d56Sopenharmony_ci return ret; 3887db96d56Sopenharmony_ci} 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci/* Helpers for formatstring */ 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ciPy_LOCAL_INLINE(PyObject *) 3937db96d56Sopenharmony_cigetnextarg(PyObject *args, Py_ssize_t arglen, Py_ssize_t *p_argidx) 3947db96d56Sopenharmony_ci{ 3957db96d56Sopenharmony_ci Py_ssize_t argidx = *p_argidx; 3967db96d56Sopenharmony_ci if (argidx < arglen) { 3977db96d56Sopenharmony_ci (*p_argidx)++; 3987db96d56Sopenharmony_ci if (arglen < 0) 3997db96d56Sopenharmony_ci return args; 4007db96d56Sopenharmony_ci else 4017db96d56Sopenharmony_ci return PyTuple_GetItem(args, argidx); 4027db96d56Sopenharmony_ci } 4037db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 4047db96d56Sopenharmony_ci "not enough arguments for format string"); 4057db96d56Sopenharmony_ci return NULL; 4067db96d56Sopenharmony_ci} 4077db96d56Sopenharmony_ci 4087db96d56Sopenharmony_ci/* Returns a new reference to a PyBytes object, or NULL on failure. */ 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_cistatic char* 4117db96d56Sopenharmony_ciformatfloat(PyObject *v, int flags, int prec, int type, 4127db96d56Sopenharmony_ci PyObject **p_result, _PyBytesWriter *writer, char *str) 4137db96d56Sopenharmony_ci{ 4147db96d56Sopenharmony_ci char *p; 4157db96d56Sopenharmony_ci PyObject *result; 4167db96d56Sopenharmony_ci double x; 4177db96d56Sopenharmony_ci size_t len; 4187db96d56Sopenharmony_ci int dtoa_flags = 0; 4197db96d56Sopenharmony_ci 4207db96d56Sopenharmony_ci x = PyFloat_AsDouble(v); 4217db96d56Sopenharmony_ci if (x == -1.0 && PyErr_Occurred()) { 4227db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "float argument required, " 4237db96d56Sopenharmony_ci "not %.200s", Py_TYPE(v)->tp_name); 4247db96d56Sopenharmony_ci return NULL; 4257db96d56Sopenharmony_ci } 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci if (prec < 0) 4287db96d56Sopenharmony_ci prec = 6; 4297db96d56Sopenharmony_ci 4307db96d56Sopenharmony_ci if (flags & F_ALT) { 4317db96d56Sopenharmony_ci dtoa_flags |= Py_DTSF_ALT; 4327db96d56Sopenharmony_ci } 4337db96d56Sopenharmony_ci p = PyOS_double_to_string(x, type, prec, dtoa_flags, NULL); 4347db96d56Sopenharmony_ci 4357db96d56Sopenharmony_ci if (p == NULL) 4367db96d56Sopenharmony_ci return NULL; 4377db96d56Sopenharmony_ci 4387db96d56Sopenharmony_ci len = strlen(p); 4397db96d56Sopenharmony_ci if (writer != NULL) { 4407db96d56Sopenharmony_ci str = _PyBytesWriter_Prepare(writer, str, len); 4417db96d56Sopenharmony_ci if (str == NULL) { 4427db96d56Sopenharmony_ci PyMem_Free(p); 4437db96d56Sopenharmony_ci return NULL; 4447db96d56Sopenharmony_ci } 4457db96d56Sopenharmony_ci memcpy(str, p, len); 4467db96d56Sopenharmony_ci PyMem_Free(p); 4477db96d56Sopenharmony_ci str += len; 4487db96d56Sopenharmony_ci return str; 4497db96d56Sopenharmony_ci } 4507db96d56Sopenharmony_ci 4517db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(p, len); 4527db96d56Sopenharmony_ci PyMem_Free(p); 4537db96d56Sopenharmony_ci *p_result = result; 4547db96d56Sopenharmony_ci return result != NULL ? str : NULL; 4557db96d56Sopenharmony_ci} 4567db96d56Sopenharmony_ci 4577db96d56Sopenharmony_cistatic PyObject * 4587db96d56Sopenharmony_ciformatlong(PyObject *v, int flags, int prec, int type) 4597db96d56Sopenharmony_ci{ 4607db96d56Sopenharmony_ci PyObject *result, *iobj; 4617db96d56Sopenharmony_ci if (type == 'i') 4627db96d56Sopenharmony_ci type = 'd'; 4637db96d56Sopenharmony_ci if (PyLong_Check(v)) 4647db96d56Sopenharmony_ci return _PyUnicode_FormatLong(v, flags & F_ALT, prec, type); 4657db96d56Sopenharmony_ci if (PyNumber_Check(v)) { 4667db96d56Sopenharmony_ci /* make sure number is a type of integer for o, x, and X */ 4677db96d56Sopenharmony_ci if (type == 'o' || type == 'x' || type == 'X') 4687db96d56Sopenharmony_ci iobj = _PyNumber_Index(v); 4697db96d56Sopenharmony_ci else 4707db96d56Sopenharmony_ci iobj = PyNumber_Long(v); 4717db96d56Sopenharmony_ci if (iobj != NULL) { 4727db96d56Sopenharmony_ci assert(PyLong_Check(iobj)); 4737db96d56Sopenharmony_ci result = _PyUnicode_FormatLong(iobj, flags & F_ALT, prec, type); 4747db96d56Sopenharmony_ci Py_DECREF(iobj); 4757db96d56Sopenharmony_ci return result; 4767db96d56Sopenharmony_ci } 4777db96d56Sopenharmony_ci if (!PyErr_ExceptionMatches(PyExc_TypeError)) 4787db96d56Sopenharmony_ci return NULL; 4797db96d56Sopenharmony_ci } 4807db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 4817db96d56Sopenharmony_ci "%%%c format: %s is required, not %.200s", type, 4827db96d56Sopenharmony_ci (type == 'o' || type == 'x' || type == 'X') ? "an integer" 4837db96d56Sopenharmony_ci : "a real number", 4847db96d56Sopenharmony_ci Py_TYPE(v)->tp_name); 4857db96d56Sopenharmony_ci return NULL; 4867db96d56Sopenharmony_ci} 4877db96d56Sopenharmony_ci 4887db96d56Sopenharmony_cistatic int 4897db96d56Sopenharmony_cibyte_converter(PyObject *arg, char *p) 4907db96d56Sopenharmony_ci{ 4917db96d56Sopenharmony_ci if (PyBytes_Check(arg) && PyBytes_GET_SIZE(arg) == 1) { 4927db96d56Sopenharmony_ci *p = PyBytes_AS_STRING(arg)[0]; 4937db96d56Sopenharmony_ci return 1; 4947db96d56Sopenharmony_ci } 4957db96d56Sopenharmony_ci else if (PyByteArray_Check(arg) && PyByteArray_GET_SIZE(arg) == 1) { 4967db96d56Sopenharmony_ci *p = PyByteArray_AS_STRING(arg)[0]; 4977db96d56Sopenharmony_ci return 1; 4987db96d56Sopenharmony_ci } 4997db96d56Sopenharmony_ci else { 5007db96d56Sopenharmony_ci int overflow; 5017db96d56Sopenharmony_ci long ival = PyLong_AsLongAndOverflow(arg, &overflow); 5027db96d56Sopenharmony_ci if (ival == -1 && PyErr_Occurred()) { 5037db96d56Sopenharmony_ci if (PyErr_ExceptionMatches(PyExc_TypeError)) { 5047db96d56Sopenharmony_ci goto onError; 5057db96d56Sopenharmony_ci } 5067db96d56Sopenharmony_ci return 0; 5077db96d56Sopenharmony_ci } 5087db96d56Sopenharmony_ci if (!(0 <= ival && ival <= 255)) { 5097db96d56Sopenharmony_ci /* this includes an overflow in converting to C long */ 5107db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 5117db96d56Sopenharmony_ci "%c arg not in range(256)"); 5127db96d56Sopenharmony_ci return 0; 5137db96d56Sopenharmony_ci } 5147db96d56Sopenharmony_ci *p = (char)ival; 5157db96d56Sopenharmony_ci return 1; 5167db96d56Sopenharmony_ci } 5177db96d56Sopenharmony_ci onError: 5187db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 5197db96d56Sopenharmony_ci "%c requires an integer in range(256) or a single byte"); 5207db96d56Sopenharmony_ci return 0; 5217db96d56Sopenharmony_ci} 5227db96d56Sopenharmony_ci 5237db96d56Sopenharmony_cistatic PyObject *_PyBytes_FromBuffer(PyObject *x); 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_cistatic PyObject * 5267db96d56Sopenharmony_ciformat_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) 5277db96d56Sopenharmony_ci{ 5287db96d56Sopenharmony_ci PyObject *func, *result; 5297db96d56Sopenharmony_ci /* is it a bytes object? */ 5307db96d56Sopenharmony_ci if (PyBytes_Check(v)) { 5317db96d56Sopenharmony_ci *pbuf = PyBytes_AS_STRING(v); 5327db96d56Sopenharmony_ci *plen = PyBytes_GET_SIZE(v); 5337db96d56Sopenharmony_ci Py_INCREF(v); 5347db96d56Sopenharmony_ci return v; 5357db96d56Sopenharmony_ci } 5367db96d56Sopenharmony_ci if (PyByteArray_Check(v)) { 5377db96d56Sopenharmony_ci *pbuf = PyByteArray_AS_STRING(v); 5387db96d56Sopenharmony_ci *plen = PyByteArray_GET_SIZE(v); 5397db96d56Sopenharmony_ci Py_INCREF(v); 5407db96d56Sopenharmony_ci return v; 5417db96d56Sopenharmony_ci } 5427db96d56Sopenharmony_ci /* does it support __bytes__? */ 5437db96d56Sopenharmony_ci func = _PyObject_LookupSpecial(v, &_Py_ID(__bytes__)); 5447db96d56Sopenharmony_ci if (func != NULL) { 5457db96d56Sopenharmony_ci result = _PyObject_CallNoArgs(func); 5467db96d56Sopenharmony_ci Py_DECREF(func); 5477db96d56Sopenharmony_ci if (result == NULL) 5487db96d56Sopenharmony_ci return NULL; 5497db96d56Sopenharmony_ci if (!PyBytes_Check(result)) { 5507db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 5517db96d56Sopenharmony_ci "__bytes__ returned non-bytes (type %.200s)", 5527db96d56Sopenharmony_ci Py_TYPE(result)->tp_name); 5537db96d56Sopenharmony_ci Py_DECREF(result); 5547db96d56Sopenharmony_ci return NULL; 5557db96d56Sopenharmony_ci } 5567db96d56Sopenharmony_ci *pbuf = PyBytes_AS_STRING(result); 5577db96d56Sopenharmony_ci *plen = PyBytes_GET_SIZE(result); 5587db96d56Sopenharmony_ci return result; 5597db96d56Sopenharmony_ci } 5607db96d56Sopenharmony_ci /* does it support buffer protocol? */ 5617db96d56Sopenharmony_ci if (PyObject_CheckBuffer(v)) { 5627db96d56Sopenharmony_ci /* maybe we can avoid making a copy of the buffer object here? */ 5637db96d56Sopenharmony_ci result = _PyBytes_FromBuffer(v); 5647db96d56Sopenharmony_ci if (result == NULL) 5657db96d56Sopenharmony_ci return NULL; 5667db96d56Sopenharmony_ci *pbuf = PyBytes_AS_STRING(result); 5677db96d56Sopenharmony_ci *plen = PyBytes_GET_SIZE(result); 5687db96d56Sopenharmony_ci return result; 5697db96d56Sopenharmony_ci } 5707db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 5717db96d56Sopenharmony_ci "%%b requires a bytes-like object, " 5727db96d56Sopenharmony_ci "or an object that implements __bytes__, not '%.100s'", 5737db96d56Sopenharmony_ci Py_TYPE(v)->tp_name); 5747db96d56Sopenharmony_ci return NULL; 5757db96d56Sopenharmony_ci} 5767db96d56Sopenharmony_ci 5777db96d56Sopenharmony_ci/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */ 5787db96d56Sopenharmony_ci 5797db96d56Sopenharmony_ciPyObject * 5807db96d56Sopenharmony_ci_PyBytes_FormatEx(const char *format, Py_ssize_t format_len, 5817db96d56Sopenharmony_ci PyObject *args, int use_bytearray) 5827db96d56Sopenharmony_ci{ 5837db96d56Sopenharmony_ci const char *fmt; 5847db96d56Sopenharmony_ci char *res; 5857db96d56Sopenharmony_ci Py_ssize_t arglen, argidx; 5867db96d56Sopenharmony_ci Py_ssize_t fmtcnt; 5877db96d56Sopenharmony_ci int args_owned = 0; 5887db96d56Sopenharmony_ci PyObject *dict = NULL; 5897db96d56Sopenharmony_ci _PyBytesWriter writer; 5907db96d56Sopenharmony_ci 5917db96d56Sopenharmony_ci if (args == NULL) { 5927db96d56Sopenharmony_ci PyErr_BadInternalCall(); 5937db96d56Sopenharmony_ci return NULL; 5947db96d56Sopenharmony_ci } 5957db96d56Sopenharmony_ci fmt = format; 5967db96d56Sopenharmony_ci fmtcnt = format_len; 5977db96d56Sopenharmony_ci 5987db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 5997db96d56Sopenharmony_ci writer.use_bytearray = use_bytearray; 6007db96d56Sopenharmony_ci 6017db96d56Sopenharmony_ci res = _PyBytesWriter_Alloc(&writer, fmtcnt); 6027db96d56Sopenharmony_ci if (res == NULL) 6037db96d56Sopenharmony_ci return NULL; 6047db96d56Sopenharmony_ci if (!use_bytearray) 6057db96d56Sopenharmony_ci writer.overallocate = 1; 6067db96d56Sopenharmony_ci 6077db96d56Sopenharmony_ci if (PyTuple_Check(args)) { 6087db96d56Sopenharmony_ci arglen = PyTuple_GET_SIZE(args); 6097db96d56Sopenharmony_ci argidx = 0; 6107db96d56Sopenharmony_ci } 6117db96d56Sopenharmony_ci else { 6127db96d56Sopenharmony_ci arglen = -1; 6137db96d56Sopenharmony_ci argidx = -2; 6147db96d56Sopenharmony_ci } 6157db96d56Sopenharmony_ci if (Py_TYPE(args)->tp_as_mapping && Py_TYPE(args)->tp_as_mapping->mp_subscript && 6167db96d56Sopenharmony_ci !PyTuple_Check(args) && !PyBytes_Check(args) && !PyUnicode_Check(args) && 6177db96d56Sopenharmony_ci !PyByteArray_Check(args)) { 6187db96d56Sopenharmony_ci dict = args; 6197db96d56Sopenharmony_ci } 6207db96d56Sopenharmony_ci 6217db96d56Sopenharmony_ci while (--fmtcnt >= 0) { 6227db96d56Sopenharmony_ci if (*fmt != '%') { 6237db96d56Sopenharmony_ci Py_ssize_t len; 6247db96d56Sopenharmony_ci char *pos; 6257db96d56Sopenharmony_ci 6267db96d56Sopenharmony_ci pos = (char *)memchr(fmt + 1, '%', fmtcnt); 6277db96d56Sopenharmony_ci if (pos != NULL) 6287db96d56Sopenharmony_ci len = pos - fmt; 6297db96d56Sopenharmony_ci else 6307db96d56Sopenharmony_ci len = fmtcnt + 1; 6317db96d56Sopenharmony_ci assert(len != 0); 6327db96d56Sopenharmony_ci 6337db96d56Sopenharmony_ci memcpy(res, fmt, len); 6347db96d56Sopenharmony_ci res += len; 6357db96d56Sopenharmony_ci fmt += len; 6367db96d56Sopenharmony_ci fmtcnt -= (len - 1); 6377db96d56Sopenharmony_ci } 6387db96d56Sopenharmony_ci else { 6397db96d56Sopenharmony_ci /* Got a format specifier */ 6407db96d56Sopenharmony_ci int flags = 0; 6417db96d56Sopenharmony_ci Py_ssize_t width = -1; 6427db96d56Sopenharmony_ci int prec = -1; 6437db96d56Sopenharmony_ci int c = '\0'; 6447db96d56Sopenharmony_ci int fill; 6457db96d56Sopenharmony_ci PyObject *v = NULL; 6467db96d56Sopenharmony_ci PyObject *temp = NULL; 6477db96d56Sopenharmony_ci const char *pbuf = NULL; 6487db96d56Sopenharmony_ci int sign; 6497db96d56Sopenharmony_ci Py_ssize_t len = 0; 6507db96d56Sopenharmony_ci char onechar; /* For byte_converter() */ 6517db96d56Sopenharmony_ci Py_ssize_t alloc; 6527db96d56Sopenharmony_ci 6537db96d56Sopenharmony_ci fmt++; 6547db96d56Sopenharmony_ci if (*fmt == '%') { 6557db96d56Sopenharmony_ci *res++ = '%'; 6567db96d56Sopenharmony_ci fmt++; 6577db96d56Sopenharmony_ci fmtcnt--; 6587db96d56Sopenharmony_ci continue; 6597db96d56Sopenharmony_ci } 6607db96d56Sopenharmony_ci if (*fmt == '(') { 6617db96d56Sopenharmony_ci const char *keystart; 6627db96d56Sopenharmony_ci Py_ssize_t keylen; 6637db96d56Sopenharmony_ci PyObject *key; 6647db96d56Sopenharmony_ci int pcount = 1; 6657db96d56Sopenharmony_ci 6667db96d56Sopenharmony_ci if (dict == NULL) { 6677db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6687db96d56Sopenharmony_ci "format requires a mapping"); 6697db96d56Sopenharmony_ci goto error; 6707db96d56Sopenharmony_ci } 6717db96d56Sopenharmony_ci ++fmt; 6727db96d56Sopenharmony_ci --fmtcnt; 6737db96d56Sopenharmony_ci keystart = fmt; 6747db96d56Sopenharmony_ci /* Skip over balanced parentheses */ 6757db96d56Sopenharmony_ci while (pcount > 0 && --fmtcnt >= 0) { 6767db96d56Sopenharmony_ci if (*fmt == ')') 6777db96d56Sopenharmony_ci --pcount; 6787db96d56Sopenharmony_ci else if (*fmt == '(') 6797db96d56Sopenharmony_ci ++pcount; 6807db96d56Sopenharmony_ci fmt++; 6817db96d56Sopenharmony_ci } 6827db96d56Sopenharmony_ci keylen = fmt - keystart - 1; 6837db96d56Sopenharmony_ci if (fmtcnt < 0 || pcount > 0) { 6847db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 6857db96d56Sopenharmony_ci "incomplete format key"); 6867db96d56Sopenharmony_ci goto error; 6877db96d56Sopenharmony_ci } 6887db96d56Sopenharmony_ci key = PyBytes_FromStringAndSize(keystart, 6897db96d56Sopenharmony_ci keylen); 6907db96d56Sopenharmony_ci if (key == NULL) 6917db96d56Sopenharmony_ci goto error; 6927db96d56Sopenharmony_ci if (args_owned) { 6937db96d56Sopenharmony_ci Py_DECREF(args); 6947db96d56Sopenharmony_ci args_owned = 0; 6957db96d56Sopenharmony_ci } 6967db96d56Sopenharmony_ci args = PyObject_GetItem(dict, key); 6977db96d56Sopenharmony_ci Py_DECREF(key); 6987db96d56Sopenharmony_ci if (args == NULL) { 6997db96d56Sopenharmony_ci goto error; 7007db96d56Sopenharmony_ci } 7017db96d56Sopenharmony_ci args_owned = 1; 7027db96d56Sopenharmony_ci arglen = -1; 7037db96d56Sopenharmony_ci argidx = -2; 7047db96d56Sopenharmony_ci } 7057db96d56Sopenharmony_ci 7067db96d56Sopenharmony_ci /* Parse flags. Example: "%+i" => flags=F_SIGN. */ 7077db96d56Sopenharmony_ci while (--fmtcnt >= 0) { 7087db96d56Sopenharmony_ci switch (c = *fmt++) { 7097db96d56Sopenharmony_ci case '-': flags |= F_LJUST; continue; 7107db96d56Sopenharmony_ci case '+': flags |= F_SIGN; continue; 7117db96d56Sopenharmony_ci case ' ': flags |= F_BLANK; continue; 7127db96d56Sopenharmony_ci case '#': flags |= F_ALT; continue; 7137db96d56Sopenharmony_ci case '0': flags |= F_ZERO; continue; 7147db96d56Sopenharmony_ci } 7157db96d56Sopenharmony_ci break; 7167db96d56Sopenharmony_ci } 7177db96d56Sopenharmony_ci 7187db96d56Sopenharmony_ci /* Parse width. Example: "%10s" => width=10 */ 7197db96d56Sopenharmony_ci if (c == '*') { 7207db96d56Sopenharmony_ci v = getnextarg(args, arglen, &argidx); 7217db96d56Sopenharmony_ci if (v == NULL) 7227db96d56Sopenharmony_ci goto error; 7237db96d56Sopenharmony_ci if (!PyLong_Check(v)) { 7247db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 7257db96d56Sopenharmony_ci "* wants int"); 7267db96d56Sopenharmony_ci goto error; 7277db96d56Sopenharmony_ci } 7287db96d56Sopenharmony_ci width = PyLong_AsSsize_t(v); 7297db96d56Sopenharmony_ci if (width == -1 && PyErr_Occurred()) 7307db96d56Sopenharmony_ci goto error; 7317db96d56Sopenharmony_ci if (width < 0) { 7327db96d56Sopenharmony_ci flags |= F_LJUST; 7337db96d56Sopenharmony_ci width = -width; 7347db96d56Sopenharmony_ci } 7357db96d56Sopenharmony_ci if (--fmtcnt >= 0) 7367db96d56Sopenharmony_ci c = *fmt++; 7377db96d56Sopenharmony_ci } 7387db96d56Sopenharmony_ci else if (c >= 0 && isdigit(c)) { 7397db96d56Sopenharmony_ci width = c - '0'; 7407db96d56Sopenharmony_ci while (--fmtcnt >= 0) { 7417db96d56Sopenharmony_ci c = Py_CHARMASK(*fmt++); 7427db96d56Sopenharmony_ci if (!isdigit(c)) 7437db96d56Sopenharmony_ci break; 7447db96d56Sopenharmony_ci if (width > (PY_SSIZE_T_MAX - ((int)c - '0')) / 10) { 7457db96d56Sopenharmony_ci PyErr_SetString( 7467db96d56Sopenharmony_ci PyExc_ValueError, 7477db96d56Sopenharmony_ci "width too big"); 7487db96d56Sopenharmony_ci goto error; 7497db96d56Sopenharmony_ci } 7507db96d56Sopenharmony_ci width = width*10 + (c - '0'); 7517db96d56Sopenharmony_ci } 7527db96d56Sopenharmony_ci } 7537db96d56Sopenharmony_ci 7547db96d56Sopenharmony_ci /* Parse precision. Example: "%.3f" => prec=3 */ 7557db96d56Sopenharmony_ci if (c == '.') { 7567db96d56Sopenharmony_ci prec = 0; 7577db96d56Sopenharmony_ci if (--fmtcnt >= 0) 7587db96d56Sopenharmony_ci c = *fmt++; 7597db96d56Sopenharmony_ci if (c == '*') { 7607db96d56Sopenharmony_ci v = getnextarg(args, arglen, &argidx); 7617db96d56Sopenharmony_ci if (v == NULL) 7627db96d56Sopenharmony_ci goto error; 7637db96d56Sopenharmony_ci if (!PyLong_Check(v)) { 7647db96d56Sopenharmony_ci PyErr_SetString( 7657db96d56Sopenharmony_ci PyExc_TypeError, 7667db96d56Sopenharmony_ci "* wants int"); 7677db96d56Sopenharmony_ci goto error; 7687db96d56Sopenharmony_ci } 7697db96d56Sopenharmony_ci prec = _PyLong_AsInt(v); 7707db96d56Sopenharmony_ci if (prec == -1 && PyErr_Occurred()) 7717db96d56Sopenharmony_ci goto error; 7727db96d56Sopenharmony_ci if (prec < 0) 7737db96d56Sopenharmony_ci prec = 0; 7747db96d56Sopenharmony_ci if (--fmtcnt >= 0) 7757db96d56Sopenharmony_ci c = *fmt++; 7767db96d56Sopenharmony_ci } 7777db96d56Sopenharmony_ci else if (c >= 0 && isdigit(c)) { 7787db96d56Sopenharmony_ci prec = c - '0'; 7797db96d56Sopenharmony_ci while (--fmtcnt >= 0) { 7807db96d56Sopenharmony_ci c = Py_CHARMASK(*fmt++); 7817db96d56Sopenharmony_ci if (!isdigit(c)) 7827db96d56Sopenharmony_ci break; 7837db96d56Sopenharmony_ci if (prec > (INT_MAX - ((int)c - '0')) / 10) { 7847db96d56Sopenharmony_ci PyErr_SetString( 7857db96d56Sopenharmony_ci PyExc_ValueError, 7867db96d56Sopenharmony_ci "prec too big"); 7877db96d56Sopenharmony_ci goto error; 7887db96d56Sopenharmony_ci } 7897db96d56Sopenharmony_ci prec = prec*10 + (c - '0'); 7907db96d56Sopenharmony_ci } 7917db96d56Sopenharmony_ci } 7927db96d56Sopenharmony_ci } /* prec */ 7937db96d56Sopenharmony_ci if (fmtcnt >= 0) { 7947db96d56Sopenharmony_ci if (c == 'h' || c == 'l' || c == 'L') { 7957db96d56Sopenharmony_ci if (--fmtcnt >= 0) 7967db96d56Sopenharmony_ci c = *fmt++; 7977db96d56Sopenharmony_ci } 7987db96d56Sopenharmony_ci } 7997db96d56Sopenharmony_ci if (fmtcnt < 0) { 8007db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 8017db96d56Sopenharmony_ci "incomplete format"); 8027db96d56Sopenharmony_ci goto error; 8037db96d56Sopenharmony_ci } 8047db96d56Sopenharmony_ci v = getnextarg(args, arglen, &argidx); 8057db96d56Sopenharmony_ci if (v == NULL) 8067db96d56Sopenharmony_ci goto error; 8077db96d56Sopenharmony_ci 8087db96d56Sopenharmony_ci if (fmtcnt == 0) { 8097db96d56Sopenharmony_ci /* last write: disable writer overallocation */ 8107db96d56Sopenharmony_ci writer.overallocate = 0; 8117db96d56Sopenharmony_ci } 8127db96d56Sopenharmony_ci 8137db96d56Sopenharmony_ci sign = 0; 8147db96d56Sopenharmony_ci fill = ' '; 8157db96d56Sopenharmony_ci switch (c) { 8167db96d56Sopenharmony_ci case 'r': 8177db96d56Sopenharmony_ci // %r is only for 2/3 code; 3 only code should use %a 8187db96d56Sopenharmony_ci case 'a': 8197db96d56Sopenharmony_ci temp = PyObject_ASCII(v); 8207db96d56Sopenharmony_ci if (temp == NULL) 8217db96d56Sopenharmony_ci goto error; 8227db96d56Sopenharmony_ci assert(PyUnicode_IS_ASCII(temp)); 8237db96d56Sopenharmony_ci pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); 8247db96d56Sopenharmony_ci len = PyUnicode_GET_LENGTH(temp); 8257db96d56Sopenharmony_ci if (prec >= 0 && len > prec) 8267db96d56Sopenharmony_ci len = prec; 8277db96d56Sopenharmony_ci break; 8287db96d56Sopenharmony_ci 8297db96d56Sopenharmony_ci case 's': 8307db96d56Sopenharmony_ci // %s is only for 2/3 code; 3 only code should use %b 8317db96d56Sopenharmony_ci case 'b': 8327db96d56Sopenharmony_ci temp = format_obj(v, &pbuf, &len); 8337db96d56Sopenharmony_ci if (temp == NULL) 8347db96d56Sopenharmony_ci goto error; 8357db96d56Sopenharmony_ci if (prec >= 0 && len > prec) 8367db96d56Sopenharmony_ci len = prec; 8377db96d56Sopenharmony_ci break; 8387db96d56Sopenharmony_ci 8397db96d56Sopenharmony_ci case 'i': 8407db96d56Sopenharmony_ci case 'd': 8417db96d56Sopenharmony_ci case 'u': 8427db96d56Sopenharmony_ci case 'o': 8437db96d56Sopenharmony_ci case 'x': 8447db96d56Sopenharmony_ci case 'X': 8457db96d56Sopenharmony_ci if (PyLong_CheckExact(v) 8467db96d56Sopenharmony_ci && width == -1 && prec == -1 8477db96d56Sopenharmony_ci && !(flags & (F_SIGN | F_BLANK)) 8487db96d56Sopenharmony_ci && c != 'X') 8497db96d56Sopenharmony_ci { 8507db96d56Sopenharmony_ci /* Fast path */ 8517db96d56Sopenharmony_ci int alternate = flags & F_ALT; 8527db96d56Sopenharmony_ci int base; 8537db96d56Sopenharmony_ci 8547db96d56Sopenharmony_ci switch(c) 8557db96d56Sopenharmony_ci { 8567db96d56Sopenharmony_ci default: 8577db96d56Sopenharmony_ci Py_UNREACHABLE(); 8587db96d56Sopenharmony_ci case 'd': 8597db96d56Sopenharmony_ci case 'i': 8607db96d56Sopenharmony_ci case 'u': 8617db96d56Sopenharmony_ci base = 10; 8627db96d56Sopenharmony_ci break; 8637db96d56Sopenharmony_ci case 'o': 8647db96d56Sopenharmony_ci base = 8; 8657db96d56Sopenharmony_ci break; 8667db96d56Sopenharmony_ci case 'x': 8677db96d56Sopenharmony_ci case 'X': 8687db96d56Sopenharmony_ci base = 16; 8697db96d56Sopenharmony_ci break; 8707db96d56Sopenharmony_ci } 8717db96d56Sopenharmony_ci 8727db96d56Sopenharmony_ci /* Fast path */ 8737db96d56Sopenharmony_ci writer.min_size -= 2; /* size preallocated for "%d" */ 8747db96d56Sopenharmony_ci res = _PyLong_FormatBytesWriter(&writer, res, 8757db96d56Sopenharmony_ci v, base, alternate); 8767db96d56Sopenharmony_ci if (res == NULL) 8777db96d56Sopenharmony_ci goto error; 8787db96d56Sopenharmony_ci continue; 8797db96d56Sopenharmony_ci } 8807db96d56Sopenharmony_ci 8817db96d56Sopenharmony_ci temp = formatlong(v, flags, prec, c); 8827db96d56Sopenharmony_ci if (!temp) 8837db96d56Sopenharmony_ci goto error; 8847db96d56Sopenharmony_ci assert(PyUnicode_IS_ASCII(temp)); 8857db96d56Sopenharmony_ci pbuf = (const char *)PyUnicode_1BYTE_DATA(temp); 8867db96d56Sopenharmony_ci len = PyUnicode_GET_LENGTH(temp); 8877db96d56Sopenharmony_ci sign = 1; 8887db96d56Sopenharmony_ci if (flags & F_ZERO) 8897db96d56Sopenharmony_ci fill = '0'; 8907db96d56Sopenharmony_ci break; 8917db96d56Sopenharmony_ci 8927db96d56Sopenharmony_ci case 'e': 8937db96d56Sopenharmony_ci case 'E': 8947db96d56Sopenharmony_ci case 'f': 8957db96d56Sopenharmony_ci case 'F': 8967db96d56Sopenharmony_ci case 'g': 8977db96d56Sopenharmony_ci case 'G': 8987db96d56Sopenharmony_ci if (width == -1 && prec == -1 8997db96d56Sopenharmony_ci && !(flags & (F_SIGN | F_BLANK))) 9007db96d56Sopenharmony_ci { 9017db96d56Sopenharmony_ci /* Fast path */ 9027db96d56Sopenharmony_ci writer.min_size -= 2; /* size preallocated for "%f" */ 9037db96d56Sopenharmony_ci res = formatfloat(v, flags, prec, c, NULL, &writer, res); 9047db96d56Sopenharmony_ci if (res == NULL) 9057db96d56Sopenharmony_ci goto error; 9067db96d56Sopenharmony_ci continue; 9077db96d56Sopenharmony_ci } 9087db96d56Sopenharmony_ci 9097db96d56Sopenharmony_ci if (!formatfloat(v, flags, prec, c, &temp, NULL, res)) 9107db96d56Sopenharmony_ci goto error; 9117db96d56Sopenharmony_ci pbuf = PyBytes_AS_STRING(temp); 9127db96d56Sopenharmony_ci len = PyBytes_GET_SIZE(temp); 9137db96d56Sopenharmony_ci sign = 1; 9147db96d56Sopenharmony_ci if (flags & F_ZERO) 9157db96d56Sopenharmony_ci fill = '0'; 9167db96d56Sopenharmony_ci break; 9177db96d56Sopenharmony_ci 9187db96d56Sopenharmony_ci case 'c': 9197db96d56Sopenharmony_ci pbuf = &onechar; 9207db96d56Sopenharmony_ci len = byte_converter(v, &onechar); 9217db96d56Sopenharmony_ci if (!len) 9227db96d56Sopenharmony_ci goto error; 9237db96d56Sopenharmony_ci if (width == -1) { 9247db96d56Sopenharmony_ci /* Fast path */ 9257db96d56Sopenharmony_ci *res++ = onechar; 9267db96d56Sopenharmony_ci continue; 9277db96d56Sopenharmony_ci } 9287db96d56Sopenharmony_ci break; 9297db96d56Sopenharmony_ci 9307db96d56Sopenharmony_ci default: 9317db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 9327db96d56Sopenharmony_ci "unsupported format character '%c' (0x%x) " 9337db96d56Sopenharmony_ci "at index %zd", 9347db96d56Sopenharmony_ci c, c, 9357db96d56Sopenharmony_ci (Py_ssize_t)(fmt - 1 - format)); 9367db96d56Sopenharmony_ci goto error; 9377db96d56Sopenharmony_ci } 9387db96d56Sopenharmony_ci 9397db96d56Sopenharmony_ci if (sign) { 9407db96d56Sopenharmony_ci if (*pbuf == '-' || *pbuf == '+') { 9417db96d56Sopenharmony_ci sign = *pbuf++; 9427db96d56Sopenharmony_ci len--; 9437db96d56Sopenharmony_ci } 9447db96d56Sopenharmony_ci else if (flags & F_SIGN) 9457db96d56Sopenharmony_ci sign = '+'; 9467db96d56Sopenharmony_ci else if (flags & F_BLANK) 9477db96d56Sopenharmony_ci sign = ' '; 9487db96d56Sopenharmony_ci else 9497db96d56Sopenharmony_ci sign = 0; 9507db96d56Sopenharmony_ci } 9517db96d56Sopenharmony_ci if (width < len) 9527db96d56Sopenharmony_ci width = len; 9537db96d56Sopenharmony_ci 9547db96d56Sopenharmony_ci alloc = width; 9557db96d56Sopenharmony_ci if (sign != 0 && len == width) 9567db96d56Sopenharmony_ci alloc++; 9577db96d56Sopenharmony_ci /* 2: size preallocated for %s */ 9587db96d56Sopenharmony_ci if (alloc > 2) { 9597db96d56Sopenharmony_ci res = _PyBytesWriter_Prepare(&writer, res, alloc - 2); 9607db96d56Sopenharmony_ci if (res == NULL) 9617db96d56Sopenharmony_ci goto error; 9627db96d56Sopenharmony_ci } 9637db96d56Sopenharmony_ci#ifndef NDEBUG 9647db96d56Sopenharmony_ci char *before = res; 9657db96d56Sopenharmony_ci#endif 9667db96d56Sopenharmony_ci 9677db96d56Sopenharmony_ci /* Write the sign if needed */ 9687db96d56Sopenharmony_ci if (sign) { 9697db96d56Sopenharmony_ci if (fill != ' ') 9707db96d56Sopenharmony_ci *res++ = sign; 9717db96d56Sopenharmony_ci if (width > len) 9727db96d56Sopenharmony_ci width--; 9737db96d56Sopenharmony_ci } 9747db96d56Sopenharmony_ci 9757db96d56Sopenharmony_ci /* Write the numeric prefix for "x", "X" and "o" formats 9767db96d56Sopenharmony_ci if the alternate form is used. 9777db96d56Sopenharmony_ci For example, write "0x" for the "%#x" format. */ 9787db96d56Sopenharmony_ci if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { 9797db96d56Sopenharmony_ci assert(pbuf[0] == '0'); 9807db96d56Sopenharmony_ci assert(pbuf[1] == c); 9817db96d56Sopenharmony_ci if (fill != ' ') { 9827db96d56Sopenharmony_ci *res++ = *pbuf++; 9837db96d56Sopenharmony_ci *res++ = *pbuf++; 9847db96d56Sopenharmony_ci } 9857db96d56Sopenharmony_ci width -= 2; 9867db96d56Sopenharmony_ci if (width < 0) 9877db96d56Sopenharmony_ci width = 0; 9887db96d56Sopenharmony_ci len -= 2; 9897db96d56Sopenharmony_ci } 9907db96d56Sopenharmony_ci 9917db96d56Sopenharmony_ci /* Pad left with the fill character if needed */ 9927db96d56Sopenharmony_ci if (width > len && !(flags & F_LJUST)) { 9937db96d56Sopenharmony_ci memset(res, fill, width - len); 9947db96d56Sopenharmony_ci res += (width - len); 9957db96d56Sopenharmony_ci width = len; 9967db96d56Sopenharmony_ci } 9977db96d56Sopenharmony_ci 9987db96d56Sopenharmony_ci /* If padding with spaces: write sign if needed and/or numeric 9997db96d56Sopenharmony_ci prefix if the alternate form is used */ 10007db96d56Sopenharmony_ci if (fill == ' ') { 10017db96d56Sopenharmony_ci if (sign) 10027db96d56Sopenharmony_ci *res++ = sign; 10037db96d56Sopenharmony_ci if ((flags & F_ALT) && (c == 'o' || c == 'x' || c == 'X')) { 10047db96d56Sopenharmony_ci assert(pbuf[0] == '0'); 10057db96d56Sopenharmony_ci assert(pbuf[1] == c); 10067db96d56Sopenharmony_ci *res++ = *pbuf++; 10077db96d56Sopenharmony_ci *res++ = *pbuf++; 10087db96d56Sopenharmony_ci } 10097db96d56Sopenharmony_ci } 10107db96d56Sopenharmony_ci 10117db96d56Sopenharmony_ci /* Copy bytes */ 10127db96d56Sopenharmony_ci memcpy(res, pbuf, len); 10137db96d56Sopenharmony_ci res += len; 10147db96d56Sopenharmony_ci 10157db96d56Sopenharmony_ci /* Pad right with the fill character if needed */ 10167db96d56Sopenharmony_ci if (width > len) { 10177db96d56Sopenharmony_ci memset(res, ' ', width - len); 10187db96d56Sopenharmony_ci res += (width - len); 10197db96d56Sopenharmony_ci } 10207db96d56Sopenharmony_ci 10217db96d56Sopenharmony_ci if (dict && (argidx < arglen)) { 10227db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 10237db96d56Sopenharmony_ci "not all arguments converted during bytes formatting"); 10247db96d56Sopenharmony_ci Py_XDECREF(temp); 10257db96d56Sopenharmony_ci goto error; 10267db96d56Sopenharmony_ci } 10277db96d56Sopenharmony_ci Py_XDECREF(temp); 10287db96d56Sopenharmony_ci 10297db96d56Sopenharmony_ci#ifndef NDEBUG 10307db96d56Sopenharmony_ci /* check that we computed the exact size for this write */ 10317db96d56Sopenharmony_ci assert((res - before) == alloc); 10327db96d56Sopenharmony_ci#endif 10337db96d56Sopenharmony_ci } /* '%' */ 10347db96d56Sopenharmony_ci 10357db96d56Sopenharmony_ci /* If overallocation was disabled, ensure that it was the last 10367db96d56Sopenharmony_ci write. Otherwise, we missed an optimization */ 10377db96d56Sopenharmony_ci assert(writer.overallocate || fmtcnt == 0 || use_bytearray); 10387db96d56Sopenharmony_ci } /* until end */ 10397db96d56Sopenharmony_ci 10407db96d56Sopenharmony_ci if (argidx < arglen && !dict) { 10417db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 10427db96d56Sopenharmony_ci "not all arguments converted during bytes formatting"); 10437db96d56Sopenharmony_ci goto error; 10447db96d56Sopenharmony_ci } 10457db96d56Sopenharmony_ci 10467db96d56Sopenharmony_ci if (args_owned) { 10477db96d56Sopenharmony_ci Py_DECREF(args); 10487db96d56Sopenharmony_ci } 10497db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, res); 10507db96d56Sopenharmony_ci 10517db96d56Sopenharmony_ci error: 10527db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 10537db96d56Sopenharmony_ci if (args_owned) { 10547db96d56Sopenharmony_ci Py_DECREF(args); 10557db96d56Sopenharmony_ci } 10567db96d56Sopenharmony_ci return NULL; 10577db96d56Sopenharmony_ci} 10587db96d56Sopenharmony_ci 10597db96d56Sopenharmony_ci/* Unescape a backslash-escaped string. */ 10607db96d56Sopenharmony_ciPyObject *_PyBytes_DecodeEscape(const char *s, 10617db96d56Sopenharmony_ci Py_ssize_t len, 10627db96d56Sopenharmony_ci const char *errors, 10637db96d56Sopenharmony_ci const char **first_invalid_escape) 10647db96d56Sopenharmony_ci{ 10657db96d56Sopenharmony_ci int c; 10667db96d56Sopenharmony_ci char *p; 10677db96d56Sopenharmony_ci const char *end; 10687db96d56Sopenharmony_ci _PyBytesWriter writer; 10697db96d56Sopenharmony_ci 10707db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 10717db96d56Sopenharmony_ci 10727db96d56Sopenharmony_ci p = _PyBytesWriter_Alloc(&writer, len); 10737db96d56Sopenharmony_ci if (p == NULL) 10747db96d56Sopenharmony_ci return NULL; 10757db96d56Sopenharmony_ci writer.overallocate = 1; 10767db96d56Sopenharmony_ci 10777db96d56Sopenharmony_ci *first_invalid_escape = NULL; 10787db96d56Sopenharmony_ci 10797db96d56Sopenharmony_ci end = s + len; 10807db96d56Sopenharmony_ci while (s < end) { 10817db96d56Sopenharmony_ci if (*s != '\\') { 10827db96d56Sopenharmony_ci *p++ = *s++; 10837db96d56Sopenharmony_ci continue; 10847db96d56Sopenharmony_ci } 10857db96d56Sopenharmony_ci 10867db96d56Sopenharmony_ci s++; 10877db96d56Sopenharmony_ci if (s == end) { 10887db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 10897db96d56Sopenharmony_ci "Trailing \\ in string"); 10907db96d56Sopenharmony_ci goto failed; 10917db96d56Sopenharmony_ci } 10927db96d56Sopenharmony_ci 10937db96d56Sopenharmony_ci switch (*s++) { 10947db96d56Sopenharmony_ci /* XXX This assumes ASCII! */ 10957db96d56Sopenharmony_ci case '\n': break; 10967db96d56Sopenharmony_ci case '\\': *p++ = '\\'; break; 10977db96d56Sopenharmony_ci case '\'': *p++ = '\''; break; 10987db96d56Sopenharmony_ci case '\"': *p++ = '\"'; break; 10997db96d56Sopenharmony_ci case 'b': *p++ = '\b'; break; 11007db96d56Sopenharmony_ci case 'f': *p++ = '\014'; break; /* FF */ 11017db96d56Sopenharmony_ci case 't': *p++ = '\t'; break; 11027db96d56Sopenharmony_ci case 'n': *p++ = '\n'; break; 11037db96d56Sopenharmony_ci case 'r': *p++ = '\r'; break; 11047db96d56Sopenharmony_ci case 'v': *p++ = '\013'; break; /* VT */ 11057db96d56Sopenharmony_ci case 'a': *p++ = '\007'; break; /* BEL, not classic C */ 11067db96d56Sopenharmony_ci case '0': case '1': case '2': case '3': 11077db96d56Sopenharmony_ci case '4': case '5': case '6': case '7': 11087db96d56Sopenharmony_ci c = s[-1] - '0'; 11097db96d56Sopenharmony_ci if (s < end && '0' <= *s && *s <= '7') { 11107db96d56Sopenharmony_ci c = (c<<3) + *s++ - '0'; 11117db96d56Sopenharmony_ci if (s < end && '0' <= *s && *s <= '7') 11127db96d56Sopenharmony_ci c = (c<<3) + *s++ - '0'; 11137db96d56Sopenharmony_ci } 11147db96d56Sopenharmony_ci if (c > 0377) { 11157db96d56Sopenharmony_ci if (*first_invalid_escape == NULL) { 11167db96d56Sopenharmony_ci *first_invalid_escape = s-3; /* Back up 3 chars, since we've 11177db96d56Sopenharmony_ci already incremented s. */ 11187db96d56Sopenharmony_ci } 11197db96d56Sopenharmony_ci } 11207db96d56Sopenharmony_ci *p++ = c; 11217db96d56Sopenharmony_ci break; 11227db96d56Sopenharmony_ci case 'x': 11237db96d56Sopenharmony_ci if (s+1 < end) { 11247db96d56Sopenharmony_ci int digit1, digit2; 11257db96d56Sopenharmony_ci digit1 = _PyLong_DigitValue[Py_CHARMASK(s[0])]; 11267db96d56Sopenharmony_ci digit2 = _PyLong_DigitValue[Py_CHARMASK(s[1])]; 11277db96d56Sopenharmony_ci if (digit1 < 16 && digit2 < 16) { 11287db96d56Sopenharmony_ci *p++ = (unsigned char)((digit1 << 4) + digit2); 11297db96d56Sopenharmony_ci s += 2; 11307db96d56Sopenharmony_ci break; 11317db96d56Sopenharmony_ci } 11327db96d56Sopenharmony_ci } 11337db96d56Sopenharmony_ci /* invalid hexadecimal digits */ 11347db96d56Sopenharmony_ci 11357db96d56Sopenharmony_ci if (!errors || strcmp(errors, "strict") == 0) { 11367db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 11377db96d56Sopenharmony_ci "invalid \\x escape at position %zd", 11387db96d56Sopenharmony_ci s - 2 - (end - len)); 11397db96d56Sopenharmony_ci goto failed; 11407db96d56Sopenharmony_ci } 11417db96d56Sopenharmony_ci if (strcmp(errors, "replace") == 0) { 11427db96d56Sopenharmony_ci *p++ = '?'; 11437db96d56Sopenharmony_ci } else if (strcmp(errors, "ignore") == 0) 11447db96d56Sopenharmony_ci /* do nothing */; 11457db96d56Sopenharmony_ci else { 11467db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 11477db96d56Sopenharmony_ci "decoding error; unknown " 11487db96d56Sopenharmony_ci "error handling code: %.400s", 11497db96d56Sopenharmony_ci errors); 11507db96d56Sopenharmony_ci goto failed; 11517db96d56Sopenharmony_ci } 11527db96d56Sopenharmony_ci /* skip \x */ 11537db96d56Sopenharmony_ci if (s < end && Py_ISXDIGIT(s[0])) 11547db96d56Sopenharmony_ci s++; /* and a hexdigit */ 11557db96d56Sopenharmony_ci break; 11567db96d56Sopenharmony_ci 11577db96d56Sopenharmony_ci default: 11587db96d56Sopenharmony_ci if (*first_invalid_escape == NULL) { 11597db96d56Sopenharmony_ci *first_invalid_escape = s-1; /* Back up one char, since we've 11607db96d56Sopenharmony_ci already incremented s. */ 11617db96d56Sopenharmony_ci } 11627db96d56Sopenharmony_ci *p++ = '\\'; 11637db96d56Sopenharmony_ci s--; 11647db96d56Sopenharmony_ci } 11657db96d56Sopenharmony_ci } 11667db96d56Sopenharmony_ci 11677db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, p); 11687db96d56Sopenharmony_ci 11697db96d56Sopenharmony_ci failed: 11707db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 11717db96d56Sopenharmony_ci return NULL; 11727db96d56Sopenharmony_ci} 11737db96d56Sopenharmony_ci 11747db96d56Sopenharmony_ciPyObject *PyBytes_DecodeEscape(const char *s, 11757db96d56Sopenharmony_ci Py_ssize_t len, 11767db96d56Sopenharmony_ci const char *errors, 11777db96d56Sopenharmony_ci Py_ssize_t Py_UNUSED(unicode), 11787db96d56Sopenharmony_ci const char *Py_UNUSED(recode_encoding)) 11797db96d56Sopenharmony_ci{ 11807db96d56Sopenharmony_ci const char* first_invalid_escape; 11817db96d56Sopenharmony_ci PyObject *result = _PyBytes_DecodeEscape(s, len, errors, 11827db96d56Sopenharmony_ci &first_invalid_escape); 11837db96d56Sopenharmony_ci if (result == NULL) 11847db96d56Sopenharmony_ci return NULL; 11857db96d56Sopenharmony_ci if (first_invalid_escape != NULL) { 11867db96d56Sopenharmony_ci unsigned char c = *first_invalid_escape; 11877db96d56Sopenharmony_ci if ('4' <= c && c <= '7') { 11887db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 11897db96d56Sopenharmony_ci "invalid octal escape sequence '\\%.3s'", 11907db96d56Sopenharmony_ci first_invalid_escape) < 0) 11917db96d56Sopenharmony_ci { 11927db96d56Sopenharmony_ci Py_DECREF(result); 11937db96d56Sopenharmony_ci return NULL; 11947db96d56Sopenharmony_ci } 11957db96d56Sopenharmony_ci } 11967db96d56Sopenharmony_ci else { 11977db96d56Sopenharmony_ci if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, 11987db96d56Sopenharmony_ci "invalid escape sequence '\\%c'", 11997db96d56Sopenharmony_ci c) < 0) 12007db96d56Sopenharmony_ci { 12017db96d56Sopenharmony_ci Py_DECREF(result); 12027db96d56Sopenharmony_ci return NULL; 12037db96d56Sopenharmony_ci } 12047db96d56Sopenharmony_ci } 12057db96d56Sopenharmony_ci } 12067db96d56Sopenharmony_ci return result; 12077db96d56Sopenharmony_ci 12087db96d56Sopenharmony_ci} 12097db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */ 12107db96d56Sopenharmony_ci/* object api */ 12117db96d56Sopenharmony_ci 12127db96d56Sopenharmony_ciPy_ssize_t 12137db96d56Sopenharmony_ciPyBytes_Size(PyObject *op) 12147db96d56Sopenharmony_ci{ 12157db96d56Sopenharmony_ci if (!PyBytes_Check(op)) { 12167db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 12177db96d56Sopenharmony_ci "expected bytes, %.200s found", Py_TYPE(op)->tp_name); 12187db96d56Sopenharmony_ci return -1; 12197db96d56Sopenharmony_ci } 12207db96d56Sopenharmony_ci return Py_SIZE(op); 12217db96d56Sopenharmony_ci} 12227db96d56Sopenharmony_ci 12237db96d56Sopenharmony_cichar * 12247db96d56Sopenharmony_ciPyBytes_AsString(PyObject *op) 12257db96d56Sopenharmony_ci{ 12267db96d56Sopenharmony_ci if (!PyBytes_Check(op)) { 12277db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 12287db96d56Sopenharmony_ci "expected bytes, %.200s found", Py_TYPE(op)->tp_name); 12297db96d56Sopenharmony_ci return NULL; 12307db96d56Sopenharmony_ci } 12317db96d56Sopenharmony_ci return ((PyBytesObject *)op)->ob_sval; 12327db96d56Sopenharmony_ci} 12337db96d56Sopenharmony_ci 12347db96d56Sopenharmony_ciint 12357db96d56Sopenharmony_ciPyBytes_AsStringAndSize(PyObject *obj, 12367db96d56Sopenharmony_ci char **s, 12377db96d56Sopenharmony_ci Py_ssize_t *len) 12387db96d56Sopenharmony_ci{ 12397db96d56Sopenharmony_ci if (s == NULL) { 12407db96d56Sopenharmony_ci PyErr_BadInternalCall(); 12417db96d56Sopenharmony_ci return -1; 12427db96d56Sopenharmony_ci } 12437db96d56Sopenharmony_ci 12447db96d56Sopenharmony_ci if (!PyBytes_Check(obj)) { 12457db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 12467db96d56Sopenharmony_ci "expected bytes, %.200s found", Py_TYPE(obj)->tp_name); 12477db96d56Sopenharmony_ci return -1; 12487db96d56Sopenharmony_ci } 12497db96d56Sopenharmony_ci 12507db96d56Sopenharmony_ci *s = PyBytes_AS_STRING(obj); 12517db96d56Sopenharmony_ci if (len != NULL) 12527db96d56Sopenharmony_ci *len = PyBytes_GET_SIZE(obj); 12537db96d56Sopenharmony_ci else if (strlen(*s) != (size_t)PyBytes_GET_SIZE(obj)) { 12547db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 12557db96d56Sopenharmony_ci "embedded null byte"); 12567db96d56Sopenharmony_ci return -1; 12577db96d56Sopenharmony_ci } 12587db96d56Sopenharmony_ci return 0; 12597db96d56Sopenharmony_ci} 12607db96d56Sopenharmony_ci 12617db96d56Sopenharmony_ci/* -------------------------------------------------------------------- */ 12627db96d56Sopenharmony_ci/* Methods */ 12637db96d56Sopenharmony_ci 12647db96d56Sopenharmony_ci#define STRINGLIB_GET_EMPTY() bytes_get_empty() 12657db96d56Sopenharmony_ci 12667db96d56Sopenharmony_ci#include "stringlib/stringdefs.h" 12677db96d56Sopenharmony_ci#define STRINGLIB_MUTABLE 0 12687db96d56Sopenharmony_ci 12697db96d56Sopenharmony_ci#include "stringlib/fastsearch.h" 12707db96d56Sopenharmony_ci#include "stringlib/count.h" 12717db96d56Sopenharmony_ci#include "stringlib/find.h" 12727db96d56Sopenharmony_ci#include "stringlib/join.h" 12737db96d56Sopenharmony_ci#include "stringlib/partition.h" 12747db96d56Sopenharmony_ci#include "stringlib/split.h" 12757db96d56Sopenharmony_ci#include "stringlib/ctype.h" 12767db96d56Sopenharmony_ci 12777db96d56Sopenharmony_ci#include "stringlib/transmogrify.h" 12787db96d56Sopenharmony_ci 12797db96d56Sopenharmony_ci#undef STRINGLIB_GET_EMPTY 12807db96d56Sopenharmony_ci 12817db96d56Sopenharmony_ciPy_ssize_t 12827db96d56Sopenharmony_ci_PyBytes_Find(const char *haystack, Py_ssize_t len_haystack, 12837db96d56Sopenharmony_ci const char *needle, Py_ssize_t len_needle, 12847db96d56Sopenharmony_ci Py_ssize_t offset) 12857db96d56Sopenharmony_ci{ 12867db96d56Sopenharmony_ci return stringlib_find(haystack, len_haystack, 12877db96d56Sopenharmony_ci needle, len_needle, offset); 12887db96d56Sopenharmony_ci} 12897db96d56Sopenharmony_ci 12907db96d56Sopenharmony_ciPy_ssize_t 12917db96d56Sopenharmony_ci_PyBytes_ReverseFind(const char *haystack, Py_ssize_t len_haystack, 12927db96d56Sopenharmony_ci const char *needle, Py_ssize_t len_needle, 12937db96d56Sopenharmony_ci Py_ssize_t offset) 12947db96d56Sopenharmony_ci{ 12957db96d56Sopenharmony_ci return stringlib_rfind(haystack, len_haystack, 12967db96d56Sopenharmony_ci needle, len_needle, offset); 12977db96d56Sopenharmony_ci} 12987db96d56Sopenharmony_ci 12997db96d56Sopenharmony_ciPyObject * 13007db96d56Sopenharmony_ciPyBytes_Repr(PyObject *obj, int smartquotes) 13017db96d56Sopenharmony_ci{ 13027db96d56Sopenharmony_ci PyBytesObject* op = (PyBytesObject*) obj; 13037db96d56Sopenharmony_ci Py_ssize_t i, length = Py_SIZE(op); 13047db96d56Sopenharmony_ci Py_ssize_t newsize, squotes, dquotes; 13057db96d56Sopenharmony_ci PyObject *v; 13067db96d56Sopenharmony_ci unsigned char quote; 13077db96d56Sopenharmony_ci const unsigned char *s; 13087db96d56Sopenharmony_ci Py_UCS1 *p; 13097db96d56Sopenharmony_ci 13107db96d56Sopenharmony_ci /* Compute size of output string */ 13117db96d56Sopenharmony_ci squotes = dquotes = 0; 13127db96d56Sopenharmony_ci newsize = 3; /* b'' */ 13137db96d56Sopenharmony_ci s = (const unsigned char*)op->ob_sval; 13147db96d56Sopenharmony_ci for (i = 0; i < length; i++) { 13157db96d56Sopenharmony_ci Py_ssize_t incr = 1; 13167db96d56Sopenharmony_ci switch(s[i]) { 13177db96d56Sopenharmony_ci case '\'': squotes++; break; 13187db96d56Sopenharmony_ci case '"': dquotes++; break; 13197db96d56Sopenharmony_ci case '\\': case '\t': case '\n': case '\r': 13207db96d56Sopenharmony_ci incr = 2; break; /* \C */ 13217db96d56Sopenharmony_ci default: 13227db96d56Sopenharmony_ci if (s[i] < ' ' || s[i] >= 0x7f) 13237db96d56Sopenharmony_ci incr = 4; /* \xHH */ 13247db96d56Sopenharmony_ci } 13257db96d56Sopenharmony_ci if (newsize > PY_SSIZE_T_MAX - incr) 13267db96d56Sopenharmony_ci goto overflow; 13277db96d56Sopenharmony_ci newsize += incr; 13287db96d56Sopenharmony_ci } 13297db96d56Sopenharmony_ci quote = '\''; 13307db96d56Sopenharmony_ci if (smartquotes && squotes && !dquotes) 13317db96d56Sopenharmony_ci quote = '"'; 13327db96d56Sopenharmony_ci if (squotes && quote == '\'') { 13337db96d56Sopenharmony_ci if (newsize > PY_SSIZE_T_MAX - squotes) 13347db96d56Sopenharmony_ci goto overflow; 13357db96d56Sopenharmony_ci newsize += squotes; 13367db96d56Sopenharmony_ci } 13377db96d56Sopenharmony_ci 13387db96d56Sopenharmony_ci v = PyUnicode_New(newsize, 127); 13397db96d56Sopenharmony_ci if (v == NULL) { 13407db96d56Sopenharmony_ci return NULL; 13417db96d56Sopenharmony_ci } 13427db96d56Sopenharmony_ci p = PyUnicode_1BYTE_DATA(v); 13437db96d56Sopenharmony_ci 13447db96d56Sopenharmony_ci *p++ = 'b', *p++ = quote; 13457db96d56Sopenharmony_ci for (i = 0; i < length; i++) { 13467db96d56Sopenharmony_ci unsigned char c = op->ob_sval[i]; 13477db96d56Sopenharmony_ci if (c == quote || c == '\\') 13487db96d56Sopenharmony_ci *p++ = '\\', *p++ = c; 13497db96d56Sopenharmony_ci else if (c == '\t') 13507db96d56Sopenharmony_ci *p++ = '\\', *p++ = 't'; 13517db96d56Sopenharmony_ci else if (c == '\n') 13527db96d56Sopenharmony_ci *p++ = '\\', *p++ = 'n'; 13537db96d56Sopenharmony_ci else if (c == '\r') 13547db96d56Sopenharmony_ci *p++ = '\\', *p++ = 'r'; 13557db96d56Sopenharmony_ci else if (c < ' ' || c >= 0x7f) { 13567db96d56Sopenharmony_ci *p++ = '\\'; 13577db96d56Sopenharmony_ci *p++ = 'x'; 13587db96d56Sopenharmony_ci *p++ = Py_hexdigits[(c & 0xf0) >> 4]; 13597db96d56Sopenharmony_ci *p++ = Py_hexdigits[c & 0xf]; 13607db96d56Sopenharmony_ci } 13617db96d56Sopenharmony_ci else 13627db96d56Sopenharmony_ci *p++ = c; 13637db96d56Sopenharmony_ci } 13647db96d56Sopenharmony_ci *p++ = quote; 13657db96d56Sopenharmony_ci assert(_PyUnicode_CheckConsistency(v, 1)); 13667db96d56Sopenharmony_ci return v; 13677db96d56Sopenharmony_ci 13687db96d56Sopenharmony_ci overflow: 13697db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 13707db96d56Sopenharmony_ci "bytes object is too large to make repr"); 13717db96d56Sopenharmony_ci return NULL; 13727db96d56Sopenharmony_ci} 13737db96d56Sopenharmony_ci 13747db96d56Sopenharmony_cistatic PyObject * 13757db96d56Sopenharmony_cibytes_repr(PyObject *op) 13767db96d56Sopenharmony_ci{ 13777db96d56Sopenharmony_ci return PyBytes_Repr(op, 1); 13787db96d56Sopenharmony_ci} 13797db96d56Sopenharmony_ci 13807db96d56Sopenharmony_cistatic PyObject * 13817db96d56Sopenharmony_cibytes_str(PyObject *op) 13827db96d56Sopenharmony_ci{ 13837db96d56Sopenharmony_ci if (_Py_GetConfig()->bytes_warning) { 13847db96d56Sopenharmony_ci if (PyErr_WarnEx(PyExc_BytesWarning, 13857db96d56Sopenharmony_ci "str() on a bytes instance", 1)) { 13867db96d56Sopenharmony_ci return NULL; 13877db96d56Sopenharmony_ci } 13887db96d56Sopenharmony_ci } 13897db96d56Sopenharmony_ci return bytes_repr(op); 13907db96d56Sopenharmony_ci} 13917db96d56Sopenharmony_ci 13927db96d56Sopenharmony_cistatic Py_ssize_t 13937db96d56Sopenharmony_cibytes_length(PyBytesObject *a) 13947db96d56Sopenharmony_ci{ 13957db96d56Sopenharmony_ci return Py_SIZE(a); 13967db96d56Sopenharmony_ci} 13977db96d56Sopenharmony_ci 13987db96d56Sopenharmony_ci/* This is also used by PyBytes_Concat() */ 13997db96d56Sopenharmony_cistatic PyObject * 14007db96d56Sopenharmony_cibytes_concat(PyObject *a, PyObject *b) 14017db96d56Sopenharmony_ci{ 14027db96d56Sopenharmony_ci Py_buffer va, vb; 14037db96d56Sopenharmony_ci PyObject *result = NULL; 14047db96d56Sopenharmony_ci 14057db96d56Sopenharmony_ci va.len = -1; 14067db96d56Sopenharmony_ci vb.len = -1; 14077db96d56Sopenharmony_ci if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 || 14087db96d56Sopenharmony_ci PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) { 14097db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", 14107db96d56Sopenharmony_ci Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name); 14117db96d56Sopenharmony_ci goto done; 14127db96d56Sopenharmony_ci } 14137db96d56Sopenharmony_ci 14147db96d56Sopenharmony_ci /* Optimize end cases */ 14157db96d56Sopenharmony_ci if (va.len == 0 && PyBytes_CheckExact(b)) { 14167db96d56Sopenharmony_ci result = b; 14177db96d56Sopenharmony_ci Py_INCREF(result); 14187db96d56Sopenharmony_ci goto done; 14197db96d56Sopenharmony_ci } 14207db96d56Sopenharmony_ci if (vb.len == 0 && PyBytes_CheckExact(a)) { 14217db96d56Sopenharmony_ci result = a; 14227db96d56Sopenharmony_ci Py_INCREF(result); 14237db96d56Sopenharmony_ci goto done; 14247db96d56Sopenharmony_ci } 14257db96d56Sopenharmony_ci 14267db96d56Sopenharmony_ci if (va.len > PY_SSIZE_T_MAX - vb.len) { 14277db96d56Sopenharmony_ci PyErr_NoMemory(); 14287db96d56Sopenharmony_ci goto done; 14297db96d56Sopenharmony_ci } 14307db96d56Sopenharmony_ci 14317db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(NULL, va.len + vb.len); 14327db96d56Sopenharmony_ci if (result != NULL) { 14337db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(result), va.buf, va.len); 14347db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(result) + va.len, vb.buf, vb.len); 14357db96d56Sopenharmony_ci } 14367db96d56Sopenharmony_ci 14377db96d56Sopenharmony_ci done: 14387db96d56Sopenharmony_ci if (va.len != -1) 14397db96d56Sopenharmony_ci PyBuffer_Release(&va); 14407db96d56Sopenharmony_ci if (vb.len != -1) 14417db96d56Sopenharmony_ci PyBuffer_Release(&vb); 14427db96d56Sopenharmony_ci return result; 14437db96d56Sopenharmony_ci} 14447db96d56Sopenharmony_ci 14457db96d56Sopenharmony_cistatic PyObject * 14467db96d56Sopenharmony_cibytes_repeat(PyBytesObject *a, Py_ssize_t n) 14477db96d56Sopenharmony_ci{ 14487db96d56Sopenharmony_ci Py_ssize_t size; 14497db96d56Sopenharmony_ci PyBytesObject *op; 14507db96d56Sopenharmony_ci size_t nbytes; 14517db96d56Sopenharmony_ci if (n < 0) 14527db96d56Sopenharmony_ci n = 0; 14537db96d56Sopenharmony_ci /* watch out for overflows: the size can overflow int, 14547db96d56Sopenharmony_ci * and the # of bytes needed can overflow size_t 14557db96d56Sopenharmony_ci */ 14567db96d56Sopenharmony_ci if (n > 0 && Py_SIZE(a) > PY_SSIZE_T_MAX / n) { 14577db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 14587db96d56Sopenharmony_ci "repeated bytes are too long"); 14597db96d56Sopenharmony_ci return NULL; 14607db96d56Sopenharmony_ci } 14617db96d56Sopenharmony_ci size = Py_SIZE(a) * n; 14627db96d56Sopenharmony_ci if (size == Py_SIZE(a) && PyBytes_CheckExact(a)) { 14637db96d56Sopenharmony_ci Py_INCREF(a); 14647db96d56Sopenharmony_ci return (PyObject *)a; 14657db96d56Sopenharmony_ci } 14667db96d56Sopenharmony_ci nbytes = (size_t)size; 14677db96d56Sopenharmony_ci if (nbytes + PyBytesObject_SIZE <= nbytes) { 14687db96d56Sopenharmony_ci PyErr_SetString(PyExc_OverflowError, 14697db96d56Sopenharmony_ci "repeated bytes are too long"); 14707db96d56Sopenharmony_ci return NULL; 14717db96d56Sopenharmony_ci } 14727db96d56Sopenharmony_ci op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + nbytes); 14737db96d56Sopenharmony_ci if (op == NULL) { 14747db96d56Sopenharmony_ci return PyErr_NoMemory(); 14757db96d56Sopenharmony_ci } 14767db96d56Sopenharmony_ci _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size); 14777db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 14787db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 14797db96d56Sopenharmony_ci op->ob_shash = -1; 14807db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 14817db96d56Sopenharmony_ci op->ob_sval[size] = '\0'; 14827db96d56Sopenharmony_ci 14837db96d56Sopenharmony_ci _PyBytes_Repeat(op->ob_sval, size, a->ob_sval, Py_SIZE(a)); 14847db96d56Sopenharmony_ci 14857db96d56Sopenharmony_ci return (PyObject *) op; 14867db96d56Sopenharmony_ci} 14877db96d56Sopenharmony_ci 14887db96d56Sopenharmony_cistatic int 14897db96d56Sopenharmony_cibytes_contains(PyObject *self, PyObject *arg) 14907db96d56Sopenharmony_ci{ 14917db96d56Sopenharmony_ci return _Py_bytes_contains(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), arg); 14927db96d56Sopenharmony_ci} 14937db96d56Sopenharmony_ci 14947db96d56Sopenharmony_cistatic PyObject * 14957db96d56Sopenharmony_cibytes_item(PyBytesObject *a, Py_ssize_t i) 14967db96d56Sopenharmony_ci{ 14977db96d56Sopenharmony_ci if (i < 0 || i >= Py_SIZE(a)) { 14987db96d56Sopenharmony_ci PyErr_SetString(PyExc_IndexError, "index out of range"); 14997db96d56Sopenharmony_ci return NULL; 15007db96d56Sopenharmony_ci } 15017db96d56Sopenharmony_ci return _PyLong_FromUnsignedChar((unsigned char)a->ob_sval[i]); 15027db96d56Sopenharmony_ci} 15037db96d56Sopenharmony_ci 15047db96d56Sopenharmony_cistatic int 15057db96d56Sopenharmony_cibytes_compare_eq(PyBytesObject *a, PyBytesObject *b) 15067db96d56Sopenharmony_ci{ 15077db96d56Sopenharmony_ci int cmp; 15087db96d56Sopenharmony_ci Py_ssize_t len; 15097db96d56Sopenharmony_ci 15107db96d56Sopenharmony_ci len = Py_SIZE(a); 15117db96d56Sopenharmony_ci if (Py_SIZE(b) != len) 15127db96d56Sopenharmony_ci return 0; 15137db96d56Sopenharmony_ci 15147db96d56Sopenharmony_ci if (a->ob_sval[0] != b->ob_sval[0]) 15157db96d56Sopenharmony_ci return 0; 15167db96d56Sopenharmony_ci 15177db96d56Sopenharmony_ci cmp = memcmp(a->ob_sval, b->ob_sval, len); 15187db96d56Sopenharmony_ci return (cmp == 0); 15197db96d56Sopenharmony_ci} 15207db96d56Sopenharmony_ci 15217db96d56Sopenharmony_cistatic PyObject* 15227db96d56Sopenharmony_cibytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) 15237db96d56Sopenharmony_ci{ 15247db96d56Sopenharmony_ci int c; 15257db96d56Sopenharmony_ci Py_ssize_t len_a, len_b; 15267db96d56Sopenharmony_ci Py_ssize_t min_len; 15277db96d56Sopenharmony_ci 15287db96d56Sopenharmony_ci /* Make sure both arguments are strings. */ 15297db96d56Sopenharmony_ci if (!(PyBytes_Check(a) && PyBytes_Check(b))) { 15307db96d56Sopenharmony_ci if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { 15317db96d56Sopenharmony_ci if (PyUnicode_Check(a) || PyUnicode_Check(b)) { 15327db96d56Sopenharmony_ci if (PyErr_WarnEx(PyExc_BytesWarning, 15337db96d56Sopenharmony_ci "Comparison between bytes and string", 1)) 15347db96d56Sopenharmony_ci return NULL; 15357db96d56Sopenharmony_ci } 15367db96d56Sopenharmony_ci if (PyLong_Check(a) || PyLong_Check(b)) { 15377db96d56Sopenharmony_ci if (PyErr_WarnEx(PyExc_BytesWarning, 15387db96d56Sopenharmony_ci "Comparison between bytes and int", 1)) 15397db96d56Sopenharmony_ci return NULL; 15407db96d56Sopenharmony_ci } 15417db96d56Sopenharmony_ci } 15427db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 15437db96d56Sopenharmony_ci } 15447db96d56Sopenharmony_ci else if (a == b) { 15457db96d56Sopenharmony_ci switch (op) { 15467db96d56Sopenharmony_ci case Py_EQ: 15477db96d56Sopenharmony_ci case Py_LE: 15487db96d56Sopenharmony_ci case Py_GE: 15497db96d56Sopenharmony_ci /* a byte string is equal to itself */ 15507db96d56Sopenharmony_ci Py_RETURN_TRUE; 15517db96d56Sopenharmony_ci case Py_NE: 15527db96d56Sopenharmony_ci case Py_LT: 15537db96d56Sopenharmony_ci case Py_GT: 15547db96d56Sopenharmony_ci Py_RETURN_FALSE; 15557db96d56Sopenharmony_ci default: 15567db96d56Sopenharmony_ci PyErr_BadArgument(); 15577db96d56Sopenharmony_ci return NULL; 15587db96d56Sopenharmony_ci } 15597db96d56Sopenharmony_ci } 15607db96d56Sopenharmony_ci else if (op == Py_EQ || op == Py_NE) { 15617db96d56Sopenharmony_ci int eq = bytes_compare_eq(a, b); 15627db96d56Sopenharmony_ci eq ^= (op == Py_NE); 15637db96d56Sopenharmony_ci return PyBool_FromLong(eq); 15647db96d56Sopenharmony_ci } 15657db96d56Sopenharmony_ci else { 15667db96d56Sopenharmony_ci len_a = Py_SIZE(a); 15677db96d56Sopenharmony_ci len_b = Py_SIZE(b); 15687db96d56Sopenharmony_ci min_len = Py_MIN(len_a, len_b); 15697db96d56Sopenharmony_ci if (min_len > 0) { 15707db96d56Sopenharmony_ci c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); 15717db96d56Sopenharmony_ci if (c == 0) 15727db96d56Sopenharmony_ci c = memcmp(a->ob_sval, b->ob_sval, min_len); 15737db96d56Sopenharmony_ci } 15747db96d56Sopenharmony_ci else 15757db96d56Sopenharmony_ci c = 0; 15767db96d56Sopenharmony_ci if (c != 0) 15777db96d56Sopenharmony_ci Py_RETURN_RICHCOMPARE(c, 0, op); 15787db96d56Sopenharmony_ci Py_RETURN_RICHCOMPARE(len_a, len_b, op); 15797db96d56Sopenharmony_ci } 15807db96d56Sopenharmony_ci} 15817db96d56Sopenharmony_ci 15827db96d56Sopenharmony_cistatic Py_hash_t 15837db96d56Sopenharmony_cibytes_hash(PyBytesObject *a) 15847db96d56Sopenharmony_ci{ 15857db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 15867db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 15877db96d56Sopenharmony_ci if (a->ob_shash == -1) { 15887db96d56Sopenharmony_ci /* Can't fail */ 15897db96d56Sopenharmony_ci a->ob_shash = _Py_HashBytes(a->ob_sval, Py_SIZE(a)); 15907db96d56Sopenharmony_ci } 15917db96d56Sopenharmony_ci return a->ob_shash; 15927db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 15937db96d56Sopenharmony_ci} 15947db96d56Sopenharmony_ci 15957db96d56Sopenharmony_cistatic PyObject* 15967db96d56Sopenharmony_cibytes_subscript(PyBytesObject* self, PyObject* item) 15977db96d56Sopenharmony_ci{ 15987db96d56Sopenharmony_ci if (_PyIndex_Check(item)) { 15997db96d56Sopenharmony_ci Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError); 16007db96d56Sopenharmony_ci if (i == -1 && PyErr_Occurred()) 16017db96d56Sopenharmony_ci return NULL; 16027db96d56Sopenharmony_ci if (i < 0) 16037db96d56Sopenharmony_ci i += PyBytes_GET_SIZE(self); 16047db96d56Sopenharmony_ci if (i < 0 || i >= PyBytes_GET_SIZE(self)) { 16057db96d56Sopenharmony_ci PyErr_SetString(PyExc_IndexError, 16067db96d56Sopenharmony_ci "index out of range"); 16077db96d56Sopenharmony_ci return NULL; 16087db96d56Sopenharmony_ci } 16097db96d56Sopenharmony_ci return _PyLong_FromUnsignedChar((unsigned char)self->ob_sval[i]); 16107db96d56Sopenharmony_ci } 16117db96d56Sopenharmony_ci else if (PySlice_Check(item)) { 16127db96d56Sopenharmony_ci Py_ssize_t start, stop, step, slicelength, i; 16137db96d56Sopenharmony_ci size_t cur; 16147db96d56Sopenharmony_ci const char* source_buf; 16157db96d56Sopenharmony_ci char* result_buf; 16167db96d56Sopenharmony_ci PyObject* result; 16177db96d56Sopenharmony_ci 16187db96d56Sopenharmony_ci if (PySlice_Unpack(item, &start, &stop, &step) < 0) { 16197db96d56Sopenharmony_ci return NULL; 16207db96d56Sopenharmony_ci } 16217db96d56Sopenharmony_ci slicelength = PySlice_AdjustIndices(PyBytes_GET_SIZE(self), &start, 16227db96d56Sopenharmony_ci &stop, step); 16237db96d56Sopenharmony_ci 16247db96d56Sopenharmony_ci if (slicelength <= 0) { 16257db96d56Sopenharmony_ci return PyBytes_FromStringAndSize("", 0); 16267db96d56Sopenharmony_ci } 16277db96d56Sopenharmony_ci else if (start == 0 && step == 1 && 16287db96d56Sopenharmony_ci slicelength == PyBytes_GET_SIZE(self) && 16297db96d56Sopenharmony_ci PyBytes_CheckExact(self)) { 16307db96d56Sopenharmony_ci Py_INCREF(self); 16317db96d56Sopenharmony_ci return (PyObject *)self; 16327db96d56Sopenharmony_ci } 16337db96d56Sopenharmony_ci else if (step == 1) { 16347db96d56Sopenharmony_ci return PyBytes_FromStringAndSize( 16357db96d56Sopenharmony_ci PyBytes_AS_STRING(self) + start, 16367db96d56Sopenharmony_ci slicelength); 16377db96d56Sopenharmony_ci } 16387db96d56Sopenharmony_ci else { 16397db96d56Sopenharmony_ci source_buf = PyBytes_AS_STRING(self); 16407db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(NULL, slicelength); 16417db96d56Sopenharmony_ci if (result == NULL) 16427db96d56Sopenharmony_ci return NULL; 16437db96d56Sopenharmony_ci 16447db96d56Sopenharmony_ci result_buf = PyBytes_AS_STRING(result); 16457db96d56Sopenharmony_ci for (cur = start, i = 0; i < slicelength; 16467db96d56Sopenharmony_ci cur += step, i++) { 16477db96d56Sopenharmony_ci result_buf[i] = source_buf[cur]; 16487db96d56Sopenharmony_ci } 16497db96d56Sopenharmony_ci 16507db96d56Sopenharmony_ci return result; 16517db96d56Sopenharmony_ci } 16527db96d56Sopenharmony_ci } 16537db96d56Sopenharmony_ci else { 16547db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 16557db96d56Sopenharmony_ci "byte indices must be integers or slices, not %.200s", 16567db96d56Sopenharmony_ci Py_TYPE(item)->tp_name); 16577db96d56Sopenharmony_ci return NULL; 16587db96d56Sopenharmony_ci } 16597db96d56Sopenharmony_ci} 16607db96d56Sopenharmony_ci 16617db96d56Sopenharmony_cistatic int 16627db96d56Sopenharmony_cibytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) 16637db96d56Sopenharmony_ci{ 16647db96d56Sopenharmony_ci return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), 16657db96d56Sopenharmony_ci 1, flags); 16667db96d56Sopenharmony_ci} 16677db96d56Sopenharmony_ci 16687db96d56Sopenharmony_cistatic PySequenceMethods bytes_as_sequence = { 16697db96d56Sopenharmony_ci (lenfunc)bytes_length, /*sq_length*/ 16707db96d56Sopenharmony_ci (binaryfunc)bytes_concat, /*sq_concat*/ 16717db96d56Sopenharmony_ci (ssizeargfunc)bytes_repeat, /*sq_repeat*/ 16727db96d56Sopenharmony_ci (ssizeargfunc)bytes_item, /*sq_item*/ 16737db96d56Sopenharmony_ci 0, /*sq_slice*/ 16747db96d56Sopenharmony_ci 0, /*sq_ass_item*/ 16757db96d56Sopenharmony_ci 0, /*sq_ass_slice*/ 16767db96d56Sopenharmony_ci (objobjproc)bytes_contains /*sq_contains*/ 16777db96d56Sopenharmony_ci}; 16787db96d56Sopenharmony_ci 16797db96d56Sopenharmony_cistatic PyMappingMethods bytes_as_mapping = { 16807db96d56Sopenharmony_ci (lenfunc)bytes_length, 16817db96d56Sopenharmony_ci (binaryfunc)bytes_subscript, 16827db96d56Sopenharmony_ci 0, 16837db96d56Sopenharmony_ci}; 16847db96d56Sopenharmony_ci 16857db96d56Sopenharmony_cistatic PyBufferProcs bytes_as_buffer = { 16867db96d56Sopenharmony_ci (getbufferproc)bytes_buffer_getbuffer, 16877db96d56Sopenharmony_ci NULL, 16887db96d56Sopenharmony_ci}; 16897db96d56Sopenharmony_ci 16907db96d56Sopenharmony_ci 16917db96d56Sopenharmony_ci/*[clinic input] 16927db96d56Sopenharmony_cibytes.__bytes__ 16937db96d56Sopenharmony_ciConvert this value to exact type bytes. 16947db96d56Sopenharmony_ci[clinic start generated code]*/ 16957db96d56Sopenharmony_ci 16967db96d56Sopenharmony_cistatic PyObject * 16977db96d56Sopenharmony_cibytes___bytes___impl(PyBytesObject *self) 16987db96d56Sopenharmony_ci/*[clinic end generated code: output=63a306a9bc0caac5 input=34ec5ddba98bd6bb]*/ 16997db96d56Sopenharmony_ci{ 17007db96d56Sopenharmony_ci if (PyBytes_CheckExact(self)) { 17017db96d56Sopenharmony_ci Py_INCREF(self); 17027db96d56Sopenharmony_ci return (PyObject *)self; 17037db96d56Sopenharmony_ci } 17047db96d56Sopenharmony_ci else { 17057db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(self->ob_sval, Py_SIZE(self)); 17067db96d56Sopenharmony_ci } 17077db96d56Sopenharmony_ci} 17087db96d56Sopenharmony_ci 17097db96d56Sopenharmony_ci 17107db96d56Sopenharmony_ci#define LEFTSTRIP 0 17117db96d56Sopenharmony_ci#define RIGHTSTRIP 1 17127db96d56Sopenharmony_ci#define BOTHSTRIP 2 17137db96d56Sopenharmony_ci 17147db96d56Sopenharmony_ci/*[clinic input] 17157db96d56Sopenharmony_cibytes.split 17167db96d56Sopenharmony_ci 17177db96d56Sopenharmony_ci sep: object = None 17187db96d56Sopenharmony_ci The delimiter according which to split the bytes. 17197db96d56Sopenharmony_ci None (the default value) means split on ASCII whitespace characters 17207db96d56Sopenharmony_ci (space, tab, return, newline, formfeed, vertical tab). 17217db96d56Sopenharmony_ci maxsplit: Py_ssize_t = -1 17227db96d56Sopenharmony_ci Maximum number of splits to do. 17237db96d56Sopenharmony_ci -1 (the default value) means no limit. 17247db96d56Sopenharmony_ci 17257db96d56Sopenharmony_ciReturn a list of the sections in the bytes, using sep as the delimiter. 17267db96d56Sopenharmony_ci[clinic start generated code]*/ 17277db96d56Sopenharmony_ci 17287db96d56Sopenharmony_cistatic PyObject * 17297db96d56Sopenharmony_cibytes_split_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit) 17307db96d56Sopenharmony_ci/*[clinic end generated code: output=52126b5844c1d8ef input=8b809b39074abbfa]*/ 17317db96d56Sopenharmony_ci{ 17327db96d56Sopenharmony_ci Py_ssize_t len = PyBytes_GET_SIZE(self), n; 17337db96d56Sopenharmony_ci const char *s = PyBytes_AS_STRING(self), *sub; 17347db96d56Sopenharmony_ci Py_buffer vsub; 17357db96d56Sopenharmony_ci PyObject *list; 17367db96d56Sopenharmony_ci 17377db96d56Sopenharmony_ci if (maxsplit < 0) 17387db96d56Sopenharmony_ci maxsplit = PY_SSIZE_T_MAX; 17397db96d56Sopenharmony_ci if (sep == Py_None) 17407db96d56Sopenharmony_ci return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit); 17417db96d56Sopenharmony_ci if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) 17427db96d56Sopenharmony_ci return NULL; 17437db96d56Sopenharmony_ci sub = vsub.buf; 17447db96d56Sopenharmony_ci n = vsub.len; 17457db96d56Sopenharmony_ci 17467db96d56Sopenharmony_ci list = stringlib_split((PyObject*) self, s, len, sub, n, maxsplit); 17477db96d56Sopenharmony_ci PyBuffer_Release(&vsub); 17487db96d56Sopenharmony_ci return list; 17497db96d56Sopenharmony_ci} 17507db96d56Sopenharmony_ci 17517db96d56Sopenharmony_ci/*[clinic input] 17527db96d56Sopenharmony_cibytes.partition 17537db96d56Sopenharmony_ci 17547db96d56Sopenharmony_ci sep: Py_buffer 17557db96d56Sopenharmony_ci / 17567db96d56Sopenharmony_ci 17577db96d56Sopenharmony_ciPartition the bytes into three parts using the given separator. 17587db96d56Sopenharmony_ci 17597db96d56Sopenharmony_ciThis will search for the separator sep in the bytes. If the separator is found, 17607db96d56Sopenharmony_cireturns a 3-tuple containing the part before the separator, the separator 17617db96d56Sopenharmony_ciitself, and the part after it. 17627db96d56Sopenharmony_ci 17637db96d56Sopenharmony_ciIf the separator is not found, returns a 3-tuple containing the original bytes 17647db96d56Sopenharmony_ciobject and two empty bytes objects. 17657db96d56Sopenharmony_ci[clinic start generated code]*/ 17667db96d56Sopenharmony_ci 17677db96d56Sopenharmony_cistatic PyObject * 17687db96d56Sopenharmony_cibytes_partition_impl(PyBytesObject *self, Py_buffer *sep) 17697db96d56Sopenharmony_ci/*[clinic end generated code: output=f532b392a17ff695 input=61cca95519406099]*/ 17707db96d56Sopenharmony_ci{ 17717db96d56Sopenharmony_ci return stringlib_partition( 17727db96d56Sopenharmony_ci (PyObject*) self, 17737db96d56Sopenharmony_ci PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), 17747db96d56Sopenharmony_ci sep->obj, (const char *)sep->buf, sep->len 17757db96d56Sopenharmony_ci ); 17767db96d56Sopenharmony_ci} 17777db96d56Sopenharmony_ci 17787db96d56Sopenharmony_ci/*[clinic input] 17797db96d56Sopenharmony_cibytes.rpartition 17807db96d56Sopenharmony_ci 17817db96d56Sopenharmony_ci sep: Py_buffer 17827db96d56Sopenharmony_ci / 17837db96d56Sopenharmony_ci 17847db96d56Sopenharmony_ciPartition the bytes into three parts using the given separator. 17857db96d56Sopenharmony_ci 17867db96d56Sopenharmony_ciThis will search for the separator sep in the bytes, starting at the end. If 17877db96d56Sopenharmony_cithe separator is found, returns a 3-tuple containing the part before the 17887db96d56Sopenharmony_ciseparator, the separator itself, and the part after it. 17897db96d56Sopenharmony_ci 17907db96d56Sopenharmony_ciIf the separator is not found, returns a 3-tuple containing two empty bytes 17917db96d56Sopenharmony_ciobjects and the original bytes object. 17927db96d56Sopenharmony_ci[clinic start generated code]*/ 17937db96d56Sopenharmony_ci 17947db96d56Sopenharmony_cistatic PyObject * 17957db96d56Sopenharmony_cibytes_rpartition_impl(PyBytesObject *self, Py_buffer *sep) 17967db96d56Sopenharmony_ci/*[clinic end generated code: output=191b114cbb028e50 input=d78db010c8cfdbe1]*/ 17977db96d56Sopenharmony_ci{ 17987db96d56Sopenharmony_ci return stringlib_rpartition( 17997db96d56Sopenharmony_ci (PyObject*) self, 18007db96d56Sopenharmony_ci PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), 18017db96d56Sopenharmony_ci sep->obj, (const char *)sep->buf, sep->len 18027db96d56Sopenharmony_ci ); 18037db96d56Sopenharmony_ci} 18047db96d56Sopenharmony_ci 18057db96d56Sopenharmony_ci/*[clinic input] 18067db96d56Sopenharmony_cibytes.rsplit = bytes.split 18077db96d56Sopenharmony_ci 18087db96d56Sopenharmony_ciReturn a list of the sections in the bytes, using sep as the delimiter. 18097db96d56Sopenharmony_ci 18107db96d56Sopenharmony_ciSplitting is done starting at the end of the bytes and working to the front. 18117db96d56Sopenharmony_ci[clinic start generated code]*/ 18127db96d56Sopenharmony_ci 18137db96d56Sopenharmony_cistatic PyObject * 18147db96d56Sopenharmony_cibytes_rsplit_impl(PyBytesObject *self, PyObject *sep, Py_ssize_t maxsplit) 18157db96d56Sopenharmony_ci/*[clinic end generated code: output=ba698d9ea01e1c8f input=0f86c9f28f7d7b7b]*/ 18167db96d56Sopenharmony_ci{ 18177db96d56Sopenharmony_ci Py_ssize_t len = PyBytes_GET_SIZE(self), n; 18187db96d56Sopenharmony_ci const char *s = PyBytes_AS_STRING(self), *sub; 18197db96d56Sopenharmony_ci Py_buffer vsub; 18207db96d56Sopenharmony_ci PyObject *list; 18217db96d56Sopenharmony_ci 18227db96d56Sopenharmony_ci if (maxsplit < 0) 18237db96d56Sopenharmony_ci maxsplit = PY_SSIZE_T_MAX; 18247db96d56Sopenharmony_ci if (sep == Py_None) 18257db96d56Sopenharmony_ci return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit); 18267db96d56Sopenharmony_ci if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) 18277db96d56Sopenharmony_ci return NULL; 18287db96d56Sopenharmony_ci sub = vsub.buf; 18297db96d56Sopenharmony_ci n = vsub.len; 18307db96d56Sopenharmony_ci 18317db96d56Sopenharmony_ci list = stringlib_rsplit((PyObject*) self, s, len, sub, n, maxsplit); 18327db96d56Sopenharmony_ci PyBuffer_Release(&vsub); 18337db96d56Sopenharmony_ci return list; 18347db96d56Sopenharmony_ci} 18357db96d56Sopenharmony_ci 18367db96d56Sopenharmony_ci 18377db96d56Sopenharmony_ci/*[clinic input] 18387db96d56Sopenharmony_cibytes.join 18397db96d56Sopenharmony_ci 18407db96d56Sopenharmony_ci iterable_of_bytes: object 18417db96d56Sopenharmony_ci / 18427db96d56Sopenharmony_ci 18437db96d56Sopenharmony_ciConcatenate any number of bytes objects. 18447db96d56Sopenharmony_ci 18457db96d56Sopenharmony_ciThe bytes whose method is called is inserted in between each pair. 18467db96d56Sopenharmony_ci 18477db96d56Sopenharmony_ciThe result is returned as a new bytes object. 18487db96d56Sopenharmony_ci 18497db96d56Sopenharmony_ciExample: b'.'.join([b'ab', b'pq', b'rs']) -> b'ab.pq.rs'. 18507db96d56Sopenharmony_ci[clinic start generated code]*/ 18517db96d56Sopenharmony_ci 18527db96d56Sopenharmony_cistatic PyObject * 18537db96d56Sopenharmony_cibytes_join(PyBytesObject *self, PyObject *iterable_of_bytes) 18547db96d56Sopenharmony_ci/*[clinic end generated code: output=a046f379f626f6f8 input=7fe377b95bd549d2]*/ 18557db96d56Sopenharmony_ci{ 18567db96d56Sopenharmony_ci return stringlib_bytes_join((PyObject*)self, iterable_of_bytes); 18577db96d56Sopenharmony_ci} 18587db96d56Sopenharmony_ci 18597db96d56Sopenharmony_ciPyObject * 18607db96d56Sopenharmony_ci_PyBytes_Join(PyObject *sep, PyObject *x) 18617db96d56Sopenharmony_ci{ 18627db96d56Sopenharmony_ci assert(sep != NULL && PyBytes_Check(sep)); 18637db96d56Sopenharmony_ci assert(x != NULL); 18647db96d56Sopenharmony_ci return bytes_join((PyBytesObject*)sep, x); 18657db96d56Sopenharmony_ci} 18667db96d56Sopenharmony_ci 18677db96d56Sopenharmony_cistatic PyObject * 18687db96d56Sopenharmony_cibytes_find(PyBytesObject *self, PyObject *args) 18697db96d56Sopenharmony_ci{ 18707db96d56Sopenharmony_ci return _Py_bytes_find(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 18717db96d56Sopenharmony_ci} 18727db96d56Sopenharmony_ci 18737db96d56Sopenharmony_cistatic PyObject * 18747db96d56Sopenharmony_cibytes_index(PyBytesObject *self, PyObject *args) 18757db96d56Sopenharmony_ci{ 18767db96d56Sopenharmony_ci return _Py_bytes_index(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 18777db96d56Sopenharmony_ci} 18787db96d56Sopenharmony_ci 18797db96d56Sopenharmony_ci 18807db96d56Sopenharmony_cistatic PyObject * 18817db96d56Sopenharmony_cibytes_rfind(PyBytesObject *self, PyObject *args) 18827db96d56Sopenharmony_ci{ 18837db96d56Sopenharmony_ci return _Py_bytes_rfind(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 18847db96d56Sopenharmony_ci} 18857db96d56Sopenharmony_ci 18867db96d56Sopenharmony_ci 18877db96d56Sopenharmony_cistatic PyObject * 18887db96d56Sopenharmony_cibytes_rindex(PyBytesObject *self, PyObject *args) 18897db96d56Sopenharmony_ci{ 18907db96d56Sopenharmony_ci return _Py_bytes_rindex(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 18917db96d56Sopenharmony_ci} 18927db96d56Sopenharmony_ci 18937db96d56Sopenharmony_ci 18947db96d56Sopenharmony_ciPy_LOCAL_INLINE(PyObject *) 18957db96d56Sopenharmony_cido_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) 18967db96d56Sopenharmony_ci{ 18977db96d56Sopenharmony_ci Py_buffer vsep; 18987db96d56Sopenharmony_ci const char *s = PyBytes_AS_STRING(self); 18997db96d56Sopenharmony_ci Py_ssize_t len = PyBytes_GET_SIZE(self); 19007db96d56Sopenharmony_ci char *sep; 19017db96d56Sopenharmony_ci Py_ssize_t seplen; 19027db96d56Sopenharmony_ci Py_ssize_t i, j; 19037db96d56Sopenharmony_ci 19047db96d56Sopenharmony_ci if (PyObject_GetBuffer(sepobj, &vsep, PyBUF_SIMPLE) != 0) 19057db96d56Sopenharmony_ci return NULL; 19067db96d56Sopenharmony_ci sep = vsep.buf; 19077db96d56Sopenharmony_ci seplen = vsep.len; 19087db96d56Sopenharmony_ci 19097db96d56Sopenharmony_ci i = 0; 19107db96d56Sopenharmony_ci if (striptype != RIGHTSTRIP) { 19117db96d56Sopenharmony_ci while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) { 19127db96d56Sopenharmony_ci i++; 19137db96d56Sopenharmony_ci } 19147db96d56Sopenharmony_ci } 19157db96d56Sopenharmony_ci 19167db96d56Sopenharmony_ci j = len; 19177db96d56Sopenharmony_ci if (striptype != LEFTSTRIP) { 19187db96d56Sopenharmony_ci do { 19197db96d56Sopenharmony_ci j--; 19207db96d56Sopenharmony_ci } while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen)); 19217db96d56Sopenharmony_ci j++; 19227db96d56Sopenharmony_ci } 19237db96d56Sopenharmony_ci 19247db96d56Sopenharmony_ci PyBuffer_Release(&vsep); 19257db96d56Sopenharmony_ci 19267db96d56Sopenharmony_ci if (i == 0 && j == len && PyBytes_CheckExact(self)) { 19277db96d56Sopenharmony_ci Py_INCREF(self); 19287db96d56Sopenharmony_ci return (PyObject*)self; 19297db96d56Sopenharmony_ci } 19307db96d56Sopenharmony_ci else 19317db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(s+i, j-i); 19327db96d56Sopenharmony_ci} 19337db96d56Sopenharmony_ci 19347db96d56Sopenharmony_ci 19357db96d56Sopenharmony_ciPy_LOCAL_INLINE(PyObject *) 19367db96d56Sopenharmony_cido_strip(PyBytesObject *self, int striptype) 19377db96d56Sopenharmony_ci{ 19387db96d56Sopenharmony_ci const char *s = PyBytes_AS_STRING(self); 19397db96d56Sopenharmony_ci Py_ssize_t len = PyBytes_GET_SIZE(self), i, j; 19407db96d56Sopenharmony_ci 19417db96d56Sopenharmony_ci i = 0; 19427db96d56Sopenharmony_ci if (striptype != RIGHTSTRIP) { 19437db96d56Sopenharmony_ci while (i < len && Py_ISSPACE(s[i])) { 19447db96d56Sopenharmony_ci i++; 19457db96d56Sopenharmony_ci } 19467db96d56Sopenharmony_ci } 19477db96d56Sopenharmony_ci 19487db96d56Sopenharmony_ci j = len; 19497db96d56Sopenharmony_ci if (striptype != LEFTSTRIP) { 19507db96d56Sopenharmony_ci do { 19517db96d56Sopenharmony_ci j--; 19527db96d56Sopenharmony_ci } while (j >= i && Py_ISSPACE(s[j])); 19537db96d56Sopenharmony_ci j++; 19547db96d56Sopenharmony_ci } 19557db96d56Sopenharmony_ci 19567db96d56Sopenharmony_ci if (i == 0 && j == len && PyBytes_CheckExact(self)) { 19577db96d56Sopenharmony_ci Py_INCREF(self); 19587db96d56Sopenharmony_ci return (PyObject*)self; 19597db96d56Sopenharmony_ci } 19607db96d56Sopenharmony_ci else 19617db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(s+i, j-i); 19627db96d56Sopenharmony_ci} 19637db96d56Sopenharmony_ci 19647db96d56Sopenharmony_ci 19657db96d56Sopenharmony_ciPy_LOCAL_INLINE(PyObject *) 19667db96d56Sopenharmony_cido_argstrip(PyBytesObject *self, int striptype, PyObject *bytes) 19677db96d56Sopenharmony_ci{ 19687db96d56Sopenharmony_ci if (bytes != Py_None) { 19697db96d56Sopenharmony_ci return do_xstrip(self, striptype, bytes); 19707db96d56Sopenharmony_ci } 19717db96d56Sopenharmony_ci return do_strip(self, striptype); 19727db96d56Sopenharmony_ci} 19737db96d56Sopenharmony_ci 19747db96d56Sopenharmony_ci/*[clinic input] 19757db96d56Sopenharmony_cibytes.strip 19767db96d56Sopenharmony_ci 19777db96d56Sopenharmony_ci bytes: object = None 19787db96d56Sopenharmony_ci / 19797db96d56Sopenharmony_ci 19807db96d56Sopenharmony_ciStrip leading and trailing bytes contained in the argument. 19817db96d56Sopenharmony_ci 19827db96d56Sopenharmony_ciIf the argument is omitted or None, strip leading and trailing ASCII whitespace. 19837db96d56Sopenharmony_ci[clinic start generated code]*/ 19847db96d56Sopenharmony_ci 19857db96d56Sopenharmony_cistatic PyObject * 19867db96d56Sopenharmony_cibytes_strip_impl(PyBytesObject *self, PyObject *bytes) 19877db96d56Sopenharmony_ci/*[clinic end generated code: output=c7c228d3bd104a1b input=8a354640e4e0b3ef]*/ 19887db96d56Sopenharmony_ci{ 19897db96d56Sopenharmony_ci return do_argstrip(self, BOTHSTRIP, bytes); 19907db96d56Sopenharmony_ci} 19917db96d56Sopenharmony_ci 19927db96d56Sopenharmony_ci/*[clinic input] 19937db96d56Sopenharmony_cibytes.lstrip 19947db96d56Sopenharmony_ci 19957db96d56Sopenharmony_ci bytes: object = None 19967db96d56Sopenharmony_ci / 19977db96d56Sopenharmony_ci 19987db96d56Sopenharmony_ciStrip leading bytes contained in the argument. 19997db96d56Sopenharmony_ci 20007db96d56Sopenharmony_ciIf the argument is omitted or None, strip leading ASCII whitespace. 20017db96d56Sopenharmony_ci[clinic start generated code]*/ 20027db96d56Sopenharmony_ci 20037db96d56Sopenharmony_cistatic PyObject * 20047db96d56Sopenharmony_cibytes_lstrip_impl(PyBytesObject *self, PyObject *bytes) 20057db96d56Sopenharmony_ci/*[clinic end generated code: output=28602e586f524e82 input=9baff4398c3f6857]*/ 20067db96d56Sopenharmony_ci{ 20077db96d56Sopenharmony_ci return do_argstrip(self, LEFTSTRIP, bytes); 20087db96d56Sopenharmony_ci} 20097db96d56Sopenharmony_ci 20107db96d56Sopenharmony_ci/*[clinic input] 20117db96d56Sopenharmony_cibytes.rstrip 20127db96d56Sopenharmony_ci 20137db96d56Sopenharmony_ci bytes: object = None 20147db96d56Sopenharmony_ci / 20157db96d56Sopenharmony_ci 20167db96d56Sopenharmony_ciStrip trailing bytes contained in the argument. 20177db96d56Sopenharmony_ci 20187db96d56Sopenharmony_ciIf the argument is omitted or None, strip trailing ASCII whitespace. 20197db96d56Sopenharmony_ci[clinic start generated code]*/ 20207db96d56Sopenharmony_ci 20217db96d56Sopenharmony_cistatic PyObject * 20227db96d56Sopenharmony_cibytes_rstrip_impl(PyBytesObject *self, PyObject *bytes) 20237db96d56Sopenharmony_ci/*[clinic end generated code: output=547e3815c95447da input=b78af445c727e32b]*/ 20247db96d56Sopenharmony_ci{ 20257db96d56Sopenharmony_ci return do_argstrip(self, RIGHTSTRIP, bytes); 20267db96d56Sopenharmony_ci} 20277db96d56Sopenharmony_ci 20287db96d56Sopenharmony_ci 20297db96d56Sopenharmony_cistatic PyObject * 20307db96d56Sopenharmony_cibytes_count(PyBytesObject *self, PyObject *args) 20317db96d56Sopenharmony_ci{ 20327db96d56Sopenharmony_ci return _Py_bytes_count(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 20337db96d56Sopenharmony_ci} 20347db96d56Sopenharmony_ci 20357db96d56Sopenharmony_ci 20367db96d56Sopenharmony_ci/*[clinic input] 20377db96d56Sopenharmony_cibytes.translate 20387db96d56Sopenharmony_ci 20397db96d56Sopenharmony_ci table: object 20407db96d56Sopenharmony_ci Translation table, which must be a bytes object of length 256. 20417db96d56Sopenharmony_ci / 20427db96d56Sopenharmony_ci delete as deletechars: object(c_default="NULL") = b'' 20437db96d56Sopenharmony_ci 20447db96d56Sopenharmony_ciReturn a copy with each character mapped by the given translation table. 20457db96d56Sopenharmony_ci 20467db96d56Sopenharmony_ciAll characters occurring in the optional argument delete are removed. 20477db96d56Sopenharmony_ciThe remaining characters are mapped through the given translation table. 20487db96d56Sopenharmony_ci[clinic start generated code]*/ 20497db96d56Sopenharmony_ci 20507db96d56Sopenharmony_cistatic PyObject * 20517db96d56Sopenharmony_cibytes_translate_impl(PyBytesObject *self, PyObject *table, 20527db96d56Sopenharmony_ci PyObject *deletechars) 20537db96d56Sopenharmony_ci/*[clinic end generated code: output=43be3437f1956211 input=0ecdf159f654233c]*/ 20547db96d56Sopenharmony_ci{ 20557db96d56Sopenharmony_ci const char *input; 20567db96d56Sopenharmony_ci char *output; 20577db96d56Sopenharmony_ci Py_buffer table_view = {NULL, NULL}; 20587db96d56Sopenharmony_ci Py_buffer del_table_view = {NULL, NULL}; 20597db96d56Sopenharmony_ci const char *table_chars; 20607db96d56Sopenharmony_ci Py_ssize_t i, c, changed = 0; 20617db96d56Sopenharmony_ci PyObject *input_obj = (PyObject*)self; 20627db96d56Sopenharmony_ci const char *output_start, *del_table_chars=NULL; 20637db96d56Sopenharmony_ci Py_ssize_t inlen, tablen, dellen = 0; 20647db96d56Sopenharmony_ci PyObject *result; 20657db96d56Sopenharmony_ci int trans_table[256]; 20667db96d56Sopenharmony_ci 20677db96d56Sopenharmony_ci if (PyBytes_Check(table)) { 20687db96d56Sopenharmony_ci table_chars = PyBytes_AS_STRING(table); 20697db96d56Sopenharmony_ci tablen = PyBytes_GET_SIZE(table); 20707db96d56Sopenharmony_ci } 20717db96d56Sopenharmony_ci else if (table == Py_None) { 20727db96d56Sopenharmony_ci table_chars = NULL; 20737db96d56Sopenharmony_ci tablen = 256; 20747db96d56Sopenharmony_ci } 20757db96d56Sopenharmony_ci else { 20767db96d56Sopenharmony_ci if (PyObject_GetBuffer(table, &table_view, PyBUF_SIMPLE) != 0) 20777db96d56Sopenharmony_ci return NULL; 20787db96d56Sopenharmony_ci table_chars = table_view.buf; 20797db96d56Sopenharmony_ci tablen = table_view.len; 20807db96d56Sopenharmony_ci } 20817db96d56Sopenharmony_ci 20827db96d56Sopenharmony_ci if (tablen != 256) { 20837db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 20847db96d56Sopenharmony_ci "translation table must be 256 characters long"); 20857db96d56Sopenharmony_ci PyBuffer_Release(&table_view); 20867db96d56Sopenharmony_ci return NULL; 20877db96d56Sopenharmony_ci } 20887db96d56Sopenharmony_ci 20897db96d56Sopenharmony_ci if (deletechars != NULL) { 20907db96d56Sopenharmony_ci if (PyBytes_Check(deletechars)) { 20917db96d56Sopenharmony_ci del_table_chars = PyBytes_AS_STRING(deletechars); 20927db96d56Sopenharmony_ci dellen = PyBytes_GET_SIZE(deletechars); 20937db96d56Sopenharmony_ci } 20947db96d56Sopenharmony_ci else { 20957db96d56Sopenharmony_ci if (PyObject_GetBuffer(deletechars, &del_table_view, PyBUF_SIMPLE) != 0) { 20967db96d56Sopenharmony_ci PyBuffer_Release(&table_view); 20977db96d56Sopenharmony_ci return NULL; 20987db96d56Sopenharmony_ci } 20997db96d56Sopenharmony_ci del_table_chars = del_table_view.buf; 21007db96d56Sopenharmony_ci dellen = del_table_view.len; 21017db96d56Sopenharmony_ci } 21027db96d56Sopenharmony_ci } 21037db96d56Sopenharmony_ci else { 21047db96d56Sopenharmony_ci del_table_chars = NULL; 21057db96d56Sopenharmony_ci dellen = 0; 21067db96d56Sopenharmony_ci } 21077db96d56Sopenharmony_ci 21087db96d56Sopenharmony_ci inlen = PyBytes_GET_SIZE(input_obj); 21097db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize((char *)NULL, inlen); 21107db96d56Sopenharmony_ci if (result == NULL) { 21117db96d56Sopenharmony_ci PyBuffer_Release(&del_table_view); 21127db96d56Sopenharmony_ci PyBuffer_Release(&table_view); 21137db96d56Sopenharmony_ci return NULL; 21147db96d56Sopenharmony_ci } 21157db96d56Sopenharmony_ci output_start = output = PyBytes_AS_STRING(result); 21167db96d56Sopenharmony_ci input = PyBytes_AS_STRING(input_obj); 21177db96d56Sopenharmony_ci 21187db96d56Sopenharmony_ci if (dellen == 0 && table_chars != NULL) { 21197db96d56Sopenharmony_ci /* If no deletions are required, use faster code */ 21207db96d56Sopenharmony_ci for (i = inlen; --i >= 0; ) { 21217db96d56Sopenharmony_ci c = Py_CHARMASK(*input++); 21227db96d56Sopenharmony_ci if (Py_CHARMASK((*output++ = table_chars[c])) != c) 21237db96d56Sopenharmony_ci changed = 1; 21247db96d56Sopenharmony_ci } 21257db96d56Sopenharmony_ci if (!changed && PyBytes_CheckExact(input_obj)) { 21267db96d56Sopenharmony_ci Py_INCREF(input_obj); 21277db96d56Sopenharmony_ci Py_DECREF(result); 21287db96d56Sopenharmony_ci result = input_obj; 21297db96d56Sopenharmony_ci } 21307db96d56Sopenharmony_ci PyBuffer_Release(&del_table_view); 21317db96d56Sopenharmony_ci PyBuffer_Release(&table_view); 21327db96d56Sopenharmony_ci return result; 21337db96d56Sopenharmony_ci } 21347db96d56Sopenharmony_ci 21357db96d56Sopenharmony_ci if (table_chars == NULL) { 21367db96d56Sopenharmony_ci for (i = 0; i < 256; i++) 21377db96d56Sopenharmony_ci trans_table[i] = Py_CHARMASK(i); 21387db96d56Sopenharmony_ci } else { 21397db96d56Sopenharmony_ci for (i = 0; i < 256; i++) 21407db96d56Sopenharmony_ci trans_table[i] = Py_CHARMASK(table_chars[i]); 21417db96d56Sopenharmony_ci } 21427db96d56Sopenharmony_ci PyBuffer_Release(&table_view); 21437db96d56Sopenharmony_ci 21447db96d56Sopenharmony_ci for (i = 0; i < dellen; i++) 21457db96d56Sopenharmony_ci trans_table[(int) Py_CHARMASK(del_table_chars[i])] = -1; 21467db96d56Sopenharmony_ci PyBuffer_Release(&del_table_view); 21477db96d56Sopenharmony_ci 21487db96d56Sopenharmony_ci for (i = inlen; --i >= 0; ) { 21497db96d56Sopenharmony_ci c = Py_CHARMASK(*input++); 21507db96d56Sopenharmony_ci if (trans_table[c] != -1) 21517db96d56Sopenharmony_ci if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c) 21527db96d56Sopenharmony_ci continue; 21537db96d56Sopenharmony_ci changed = 1; 21547db96d56Sopenharmony_ci } 21557db96d56Sopenharmony_ci if (!changed && PyBytes_CheckExact(input_obj)) { 21567db96d56Sopenharmony_ci Py_DECREF(result); 21577db96d56Sopenharmony_ci Py_INCREF(input_obj); 21587db96d56Sopenharmony_ci return input_obj; 21597db96d56Sopenharmony_ci } 21607db96d56Sopenharmony_ci /* Fix the size of the resulting byte string */ 21617db96d56Sopenharmony_ci if (inlen > 0) 21627db96d56Sopenharmony_ci _PyBytes_Resize(&result, output - output_start); 21637db96d56Sopenharmony_ci return result; 21647db96d56Sopenharmony_ci} 21657db96d56Sopenharmony_ci 21667db96d56Sopenharmony_ci 21677db96d56Sopenharmony_ci/*[clinic input] 21687db96d56Sopenharmony_ci 21697db96d56Sopenharmony_ci@staticmethod 21707db96d56Sopenharmony_cibytes.maketrans 21717db96d56Sopenharmony_ci 21727db96d56Sopenharmony_ci frm: Py_buffer 21737db96d56Sopenharmony_ci to: Py_buffer 21747db96d56Sopenharmony_ci / 21757db96d56Sopenharmony_ci 21767db96d56Sopenharmony_ciReturn a translation table useable for the bytes or bytearray translate method. 21777db96d56Sopenharmony_ci 21787db96d56Sopenharmony_ciThe returned table will be one where each byte in frm is mapped to the byte at 21797db96d56Sopenharmony_cithe same position in to. 21807db96d56Sopenharmony_ci 21817db96d56Sopenharmony_ciThe bytes objects frm and to must be of the same length. 21827db96d56Sopenharmony_ci[clinic start generated code]*/ 21837db96d56Sopenharmony_ci 21847db96d56Sopenharmony_cistatic PyObject * 21857db96d56Sopenharmony_cibytes_maketrans_impl(Py_buffer *frm, Py_buffer *to) 21867db96d56Sopenharmony_ci/*[clinic end generated code: output=a36f6399d4b77f6f input=de7a8fc5632bb8f1]*/ 21877db96d56Sopenharmony_ci{ 21887db96d56Sopenharmony_ci return _Py_bytes_maketrans(frm, to); 21897db96d56Sopenharmony_ci} 21907db96d56Sopenharmony_ci 21917db96d56Sopenharmony_ci 21927db96d56Sopenharmony_ci/*[clinic input] 21937db96d56Sopenharmony_cibytes.replace 21947db96d56Sopenharmony_ci 21957db96d56Sopenharmony_ci old: Py_buffer 21967db96d56Sopenharmony_ci new: Py_buffer 21977db96d56Sopenharmony_ci count: Py_ssize_t = -1 21987db96d56Sopenharmony_ci Maximum number of occurrences to replace. 21997db96d56Sopenharmony_ci -1 (the default value) means replace all occurrences. 22007db96d56Sopenharmony_ci / 22017db96d56Sopenharmony_ci 22027db96d56Sopenharmony_ciReturn a copy with all occurrences of substring old replaced by new. 22037db96d56Sopenharmony_ci 22047db96d56Sopenharmony_ciIf the optional argument count is given, only the first count occurrences are 22057db96d56Sopenharmony_cireplaced. 22067db96d56Sopenharmony_ci[clinic start generated code]*/ 22077db96d56Sopenharmony_ci 22087db96d56Sopenharmony_cistatic PyObject * 22097db96d56Sopenharmony_cibytes_replace_impl(PyBytesObject *self, Py_buffer *old, Py_buffer *new, 22107db96d56Sopenharmony_ci Py_ssize_t count) 22117db96d56Sopenharmony_ci/*[clinic end generated code: output=994fa588b6b9c104 input=b2fbbf0bf04de8e5]*/ 22127db96d56Sopenharmony_ci{ 22137db96d56Sopenharmony_ci return stringlib_replace((PyObject *)self, 22147db96d56Sopenharmony_ci (const char *)old->buf, old->len, 22157db96d56Sopenharmony_ci (const char *)new->buf, new->len, count); 22167db96d56Sopenharmony_ci} 22177db96d56Sopenharmony_ci 22187db96d56Sopenharmony_ci/** End DALKE **/ 22197db96d56Sopenharmony_ci 22207db96d56Sopenharmony_ci/*[clinic input] 22217db96d56Sopenharmony_cibytes.removeprefix as bytes_removeprefix 22227db96d56Sopenharmony_ci 22237db96d56Sopenharmony_ci prefix: Py_buffer 22247db96d56Sopenharmony_ci / 22257db96d56Sopenharmony_ci 22267db96d56Sopenharmony_ciReturn a bytes object with the given prefix string removed if present. 22277db96d56Sopenharmony_ci 22287db96d56Sopenharmony_ciIf the bytes starts with the prefix string, return bytes[len(prefix):]. 22297db96d56Sopenharmony_ciOtherwise, return a copy of the original bytes. 22307db96d56Sopenharmony_ci[clinic start generated code]*/ 22317db96d56Sopenharmony_ci 22327db96d56Sopenharmony_cistatic PyObject * 22337db96d56Sopenharmony_cibytes_removeprefix_impl(PyBytesObject *self, Py_buffer *prefix) 22347db96d56Sopenharmony_ci/*[clinic end generated code: output=f006865331a06ab6 input=0c93bac817a8502c]*/ 22357db96d56Sopenharmony_ci{ 22367db96d56Sopenharmony_ci const char *self_start = PyBytes_AS_STRING(self); 22377db96d56Sopenharmony_ci Py_ssize_t self_len = PyBytes_GET_SIZE(self); 22387db96d56Sopenharmony_ci const char *prefix_start = prefix->buf; 22397db96d56Sopenharmony_ci Py_ssize_t prefix_len = prefix->len; 22407db96d56Sopenharmony_ci 22417db96d56Sopenharmony_ci if (self_len >= prefix_len 22427db96d56Sopenharmony_ci && prefix_len > 0 22437db96d56Sopenharmony_ci && memcmp(self_start, prefix_start, prefix_len) == 0) 22447db96d56Sopenharmony_ci { 22457db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(self_start + prefix_len, 22467db96d56Sopenharmony_ci self_len - prefix_len); 22477db96d56Sopenharmony_ci } 22487db96d56Sopenharmony_ci 22497db96d56Sopenharmony_ci if (PyBytes_CheckExact(self)) { 22507db96d56Sopenharmony_ci Py_INCREF(self); 22517db96d56Sopenharmony_ci return (PyObject *)self; 22527db96d56Sopenharmony_ci } 22537db96d56Sopenharmony_ci 22547db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(self_start, self_len); 22557db96d56Sopenharmony_ci} 22567db96d56Sopenharmony_ci 22577db96d56Sopenharmony_ci/*[clinic input] 22587db96d56Sopenharmony_cibytes.removesuffix as bytes_removesuffix 22597db96d56Sopenharmony_ci 22607db96d56Sopenharmony_ci suffix: Py_buffer 22617db96d56Sopenharmony_ci / 22627db96d56Sopenharmony_ci 22637db96d56Sopenharmony_ciReturn a bytes object with the given suffix string removed if present. 22647db96d56Sopenharmony_ci 22657db96d56Sopenharmony_ciIf the bytes ends with the suffix string and that suffix is not empty, 22667db96d56Sopenharmony_cireturn bytes[:-len(prefix)]. Otherwise, return a copy of the original 22677db96d56Sopenharmony_cibytes. 22687db96d56Sopenharmony_ci[clinic start generated code]*/ 22697db96d56Sopenharmony_ci 22707db96d56Sopenharmony_cistatic PyObject * 22717db96d56Sopenharmony_cibytes_removesuffix_impl(PyBytesObject *self, Py_buffer *suffix) 22727db96d56Sopenharmony_ci/*[clinic end generated code: output=d887d308e3242eeb input=9f4e1da8c637bbf1]*/ 22737db96d56Sopenharmony_ci{ 22747db96d56Sopenharmony_ci const char *self_start = PyBytes_AS_STRING(self); 22757db96d56Sopenharmony_ci Py_ssize_t self_len = PyBytes_GET_SIZE(self); 22767db96d56Sopenharmony_ci const char *suffix_start = suffix->buf; 22777db96d56Sopenharmony_ci Py_ssize_t suffix_len = suffix->len; 22787db96d56Sopenharmony_ci 22797db96d56Sopenharmony_ci if (self_len >= suffix_len 22807db96d56Sopenharmony_ci && suffix_len > 0 22817db96d56Sopenharmony_ci && memcmp(self_start + self_len - suffix_len, 22827db96d56Sopenharmony_ci suffix_start, suffix_len) == 0) 22837db96d56Sopenharmony_ci { 22847db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(self_start, 22857db96d56Sopenharmony_ci self_len - suffix_len); 22867db96d56Sopenharmony_ci } 22877db96d56Sopenharmony_ci 22887db96d56Sopenharmony_ci if (PyBytes_CheckExact(self)) { 22897db96d56Sopenharmony_ci Py_INCREF(self); 22907db96d56Sopenharmony_ci return (PyObject *)self; 22917db96d56Sopenharmony_ci } 22927db96d56Sopenharmony_ci 22937db96d56Sopenharmony_ci return PyBytes_FromStringAndSize(self_start, self_len); 22947db96d56Sopenharmony_ci} 22957db96d56Sopenharmony_ci 22967db96d56Sopenharmony_cistatic PyObject * 22977db96d56Sopenharmony_cibytes_startswith(PyBytesObject *self, PyObject *args) 22987db96d56Sopenharmony_ci{ 22997db96d56Sopenharmony_ci return _Py_bytes_startswith(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 23007db96d56Sopenharmony_ci} 23017db96d56Sopenharmony_ci 23027db96d56Sopenharmony_cistatic PyObject * 23037db96d56Sopenharmony_cibytes_endswith(PyBytesObject *self, PyObject *args) 23047db96d56Sopenharmony_ci{ 23057db96d56Sopenharmony_ci return _Py_bytes_endswith(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), args); 23067db96d56Sopenharmony_ci} 23077db96d56Sopenharmony_ci 23087db96d56Sopenharmony_ci 23097db96d56Sopenharmony_ci/*[clinic input] 23107db96d56Sopenharmony_cibytes.decode 23117db96d56Sopenharmony_ci 23127db96d56Sopenharmony_ci encoding: str(c_default="NULL") = 'utf-8' 23137db96d56Sopenharmony_ci The encoding with which to decode the bytes. 23147db96d56Sopenharmony_ci errors: str(c_default="NULL") = 'strict' 23157db96d56Sopenharmony_ci The error handling scheme to use for the handling of decoding errors. 23167db96d56Sopenharmony_ci The default is 'strict' meaning that decoding errors raise a 23177db96d56Sopenharmony_ci UnicodeDecodeError. Other possible values are 'ignore' and 'replace' 23187db96d56Sopenharmony_ci as well as any other name registered with codecs.register_error that 23197db96d56Sopenharmony_ci can handle UnicodeDecodeErrors. 23207db96d56Sopenharmony_ci 23217db96d56Sopenharmony_ciDecode the bytes using the codec registered for encoding. 23227db96d56Sopenharmony_ci[clinic start generated code]*/ 23237db96d56Sopenharmony_ci 23247db96d56Sopenharmony_cistatic PyObject * 23257db96d56Sopenharmony_cibytes_decode_impl(PyBytesObject *self, const char *encoding, 23267db96d56Sopenharmony_ci const char *errors) 23277db96d56Sopenharmony_ci/*[clinic end generated code: output=5649a53dde27b314 input=958174769d2a40ca]*/ 23287db96d56Sopenharmony_ci{ 23297db96d56Sopenharmony_ci return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors); 23307db96d56Sopenharmony_ci} 23317db96d56Sopenharmony_ci 23327db96d56Sopenharmony_ci 23337db96d56Sopenharmony_ci/*[clinic input] 23347db96d56Sopenharmony_cibytes.splitlines 23357db96d56Sopenharmony_ci 23367db96d56Sopenharmony_ci keepends: bool(accept={int}) = False 23377db96d56Sopenharmony_ci 23387db96d56Sopenharmony_ciReturn a list of the lines in the bytes, breaking at line boundaries. 23397db96d56Sopenharmony_ci 23407db96d56Sopenharmony_ciLine breaks are not included in the resulting list unless keepends is given and 23417db96d56Sopenharmony_citrue. 23427db96d56Sopenharmony_ci[clinic start generated code]*/ 23437db96d56Sopenharmony_ci 23447db96d56Sopenharmony_cistatic PyObject * 23457db96d56Sopenharmony_cibytes_splitlines_impl(PyBytesObject *self, int keepends) 23467db96d56Sopenharmony_ci/*[clinic end generated code: output=3484149a5d880ffb input=a8b32eb01ff5a5ed]*/ 23477db96d56Sopenharmony_ci{ 23487db96d56Sopenharmony_ci return stringlib_splitlines( 23497db96d56Sopenharmony_ci (PyObject*) self, PyBytes_AS_STRING(self), 23507db96d56Sopenharmony_ci PyBytes_GET_SIZE(self), keepends 23517db96d56Sopenharmony_ci ); 23527db96d56Sopenharmony_ci} 23537db96d56Sopenharmony_ci 23547db96d56Sopenharmony_ci/*[clinic input] 23557db96d56Sopenharmony_ci@classmethod 23567db96d56Sopenharmony_cibytes.fromhex 23577db96d56Sopenharmony_ci 23587db96d56Sopenharmony_ci string: unicode 23597db96d56Sopenharmony_ci / 23607db96d56Sopenharmony_ci 23617db96d56Sopenharmony_ciCreate a bytes object from a string of hexadecimal numbers. 23627db96d56Sopenharmony_ci 23637db96d56Sopenharmony_ciSpaces between two numbers are accepted. 23647db96d56Sopenharmony_ciExample: bytes.fromhex('B9 01EF') -> b'\\xb9\\x01\\xef'. 23657db96d56Sopenharmony_ci[clinic start generated code]*/ 23667db96d56Sopenharmony_ci 23677db96d56Sopenharmony_cistatic PyObject * 23687db96d56Sopenharmony_cibytes_fromhex_impl(PyTypeObject *type, PyObject *string) 23697db96d56Sopenharmony_ci/*[clinic end generated code: output=0973acc63661bb2e input=bf4d1c361670acd3]*/ 23707db96d56Sopenharmony_ci{ 23717db96d56Sopenharmony_ci PyObject *result = _PyBytes_FromHex(string, 0); 23727db96d56Sopenharmony_ci if (type != &PyBytes_Type && result != NULL) { 23737db96d56Sopenharmony_ci Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result)); 23747db96d56Sopenharmony_ci } 23757db96d56Sopenharmony_ci return result; 23767db96d56Sopenharmony_ci} 23777db96d56Sopenharmony_ci 23787db96d56Sopenharmony_ciPyObject* 23797db96d56Sopenharmony_ci_PyBytes_FromHex(PyObject *string, int use_bytearray) 23807db96d56Sopenharmony_ci{ 23817db96d56Sopenharmony_ci char *buf; 23827db96d56Sopenharmony_ci Py_ssize_t hexlen, invalid_char; 23837db96d56Sopenharmony_ci unsigned int top, bot; 23847db96d56Sopenharmony_ci const Py_UCS1 *str, *end; 23857db96d56Sopenharmony_ci _PyBytesWriter writer; 23867db96d56Sopenharmony_ci 23877db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 23887db96d56Sopenharmony_ci writer.use_bytearray = use_bytearray; 23897db96d56Sopenharmony_ci 23907db96d56Sopenharmony_ci assert(PyUnicode_Check(string)); 23917db96d56Sopenharmony_ci if (PyUnicode_READY(string)) 23927db96d56Sopenharmony_ci return NULL; 23937db96d56Sopenharmony_ci hexlen = PyUnicode_GET_LENGTH(string); 23947db96d56Sopenharmony_ci 23957db96d56Sopenharmony_ci if (!PyUnicode_IS_ASCII(string)) { 23967db96d56Sopenharmony_ci const void *data = PyUnicode_DATA(string); 23977db96d56Sopenharmony_ci unsigned int kind = PyUnicode_KIND(string); 23987db96d56Sopenharmony_ci Py_ssize_t i; 23997db96d56Sopenharmony_ci 24007db96d56Sopenharmony_ci /* search for the first non-ASCII character */ 24017db96d56Sopenharmony_ci for (i = 0; i < hexlen; i++) { 24027db96d56Sopenharmony_ci if (PyUnicode_READ(kind, data, i) >= 128) 24037db96d56Sopenharmony_ci break; 24047db96d56Sopenharmony_ci } 24057db96d56Sopenharmony_ci invalid_char = i; 24067db96d56Sopenharmony_ci goto error; 24077db96d56Sopenharmony_ci } 24087db96d56Sopenharmony_ci 24097db96d56Sopenharmony_ci assert(PyUnicode_KIND(string) == PyUnicode_1BYTE_KIND); 24107db96d56Sopenharmony_ci str = PyUnicode_1BYTE_DATA(string); 24117db96d56Sopenharmony_ci 24127db96d56Sopenharmony_ci /* This overestimates if there are spaces */ 24137db96d56Sopenharmony_ci buf = _PyBytesWriter_Alloc(&writer, hexlen / 2); 24147db96d56Sopenharmony_ci if (buf == NULL) 24157db96d56Sopenharmony_ci return NULL; 24167db96d56Sopenharmony_ci 24177db96d56Sopenharmony_ci end = str + hexlen; 24187db96d56Sopenharmony_ci while (str < end) { 24197db96d56Sopenharmony_ci /* skip over spaces in the input */ 24207db96d56Sopenharmony_ci if (Py_ISSPACE(*str)) { 24217db96d56Sopenharmony_ci do { 24227db96d56Sopenharmony_ci str++; 24237db96d56Sopenharmony_ci } while (Py_ISSPACE(*str)); 24247db96d56Sopenharmony_ci if (str >= end) 24257db96d56Sopenharmony_ci break; 24267db96d56Sopenharmony_ci } 24277db96d56Sopenharmony_ci 24287db96d56Sopenharmony_ci top = _PyLong_DigitValue[*str]; 24297db96d56Sopenharmony_ci if (top >= 16) { 24307db96d56Sopenharmony_ci invalid_char = str - PyUnicode_1BYTE_DATA(string); 24317db96d56Sopenharmony_ci goto error; 24327db96d56Sopenharmony_ci } 24337db96d56Sopenharmony_ci str++; 24347db96d56Sopenharmony_ci 24357db96d56Sopenharmony_ci bot = _PyLong_DigitValue[*str]; 24367db96d56Sopenharmony_ci if (bot >= 16) { 24377db96d56Sopenharmony_ci invalid_char = str - PyUnicode_1BYTE_DATA(string); 24387db96d56Sopenharmony_ci goto error; 24397db96d56Sopenharmony_ci } 24407db96d56Sopenharmony_ci str++; 24417db96d56Sopenharmony_ci 24427db96d56Sopenharmony_ci *buf++ = (unsigned char)((top << 4) + bot); 24437db96d56Sopenharmony_ci } 24447db96d56Sopenharmony_ci 24457db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, buf); 24467db96d56Sopenharmony_ci 24477db96d56Sopenharmony_ci error: 24487db96d56Sopenharmony_ci PyErr_Format(PyExc_ValueError, 24497db96d56Sopenharmony_ci "non-hexadecimal number found in " 24507db96d56Sopenharmony_ci "fromhex() arg at position %zd", invalid_char); 24517db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 24527db96d56Sopenharmony_ci return NULL; 24537db96d56Sopenharmony_ci} 24547db96d56Sopenharmony_ci 24557db96d56Sopenharmony_ci/*[clinic input] 24567db96d56Sopenharmony_cibytes.hex 24577db96d56Sopenharmony_ci 24587db96d56Sopenharmony_ci sep: object = NULL 24597db96d56Sopenharmony_ci An optional single character or byte to separate hex bytes. 24607db96d56Sopenharmony_ci bytes_per_sep: int = 1 24617db96d56Sopenharmony_ci How many bytes between separators. Positive values count from the 24627db96d56Sopenharmony_ci right, negative values count from the left. 24637db96d56Sopenharmony_ci 24647db96d56Sopenharmony_ciCreate a string of hexadecimal numbers from a bytes object. 24657db96d56Sopenharmony_ci 24667db96d56Sopenharmony_ciExample: 24677db96d56Sopenharmony_ci>>> value = b'\xb9\x01\xef' 24687db96d56Sopenharmony_ci>>> value.hex() 24697db96d56Sopenharmony_ci'b901ef' 24707db96d56Sopenharmony_ci>>> value.hex(':') 24717db96d56Sopenharmony_ci'b9:01:ef' 24727db96d56Sopenharmony_ci>>> value.hex(':', 2) 24737db96d56Sopenharmony_ci'b9:01ef' 24747db96d56Sopenharmony_ci>>> value.hex(':', -2) 24757db96d56Sopenharmony_ci'b901:ef' 24767db96d56Sopenharmony_ci[clinic start generated code]*/ 24777db96d56Sopenharmony_ci 24787db96d56Sopenharmony_cistatic PyObject * 24797db96d56Sopenharmony_cibytes_hex_impl(PyBytesObject *self, PyObject *sep, int bytes_per_sep) 24807db96d56Sopenharmony_ci/*[clinic end generated code: output=1f134da504064139 input=1a21282b1f1ae595]*/ 24817db96d56Sopenharmony_ci{ 24827db96d56Sopenharmony_ci const char *argbuf = PyBytes_AS_STRING(self); 24837db96d56Sopenharmony_ci Py_ssize_t arglen = PyBytes_GET_SIZE(self); 24847db96d56Sopenharmony_ci return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep); 24857db96d56Sopenharmony_ci} 24867db96d56Sopenharmony_ci 24877db96d56Sopenharmony_cistatic PyObject * 24887db96d56Sopenharmony_cibytes_getnewargs(PyBytesObject *v, PyObject *Py_UNUSED(ignored)) 24897db96d56Sopenharmony_ci{ 24907db96d56Sopenharmony_ci return Py_BuildValue("(y#)", v->ob_sval, Py_SIZE(v)); 24917db96d56Sopenharmony_ci} 24927db96d56Sopenharmony_ci 24937db96d56Sopenharmony_ci 24947db96d56Sopenharmony_cistatic PyMethodDef 24957db96d56Sopenharmony_cibytes_methods[] = { 24967db96d56Sopenharmony_ci {"__getnewargs__", (PyCFunction)bytes_getnewargs, METH_NOARGS}, 24977db96d56Sopenharmony_ci BYTES___BYTES___METHODDEF 24987db96d56Sopenharmony_ci {"capitalize", stringlib_capitalize, METH_NOARGS, 24997db96d56Sopenharmony_ci _Py_capitalize__doc__}, 25007db96d56Sopenharmony_ci STRINGLIB_CENTER_METHODDEF 25017db96d56Sopenharmony_ci {"count", (PyCFunction)bytes_count, METH_VARARGS, 25027db96d56Sopenharmony_ci _Py_count__doc__}, 25037db96d56Sopenharmony_ci BYTES_DECODE_METHODDEF 25047db96d56Sopenharmony_ci {"endswith", (PyCFunction)bytes_endswith, METH_VARARGS, 25057db96d56Sopenharmony_ci _Py_endswith__doc__}, 25067db96d56Sopenharmony_ci STRINGLIB_EXPANDTABS_METHODDEF 25077db96d56Sopenharmony_ci {"find", (PyCFunction)bytes_find, METH_VARARGS, 25087db96d56Sopenharmony_ci _Py_find__doc__}, 25097db96d56Sopenharmony_ci BYTES_FROMHEX_METHODDEF 25107db96d56Sopenharmony_ci BYTES_HEX_METHODDEF 25117db96d56Sopenharmony_ci {"index", (PyCFunction)bytes_index, METH_VARARGS, _Py_index__doc__}, 25127db96d56Sopenharmony_ci {"isalnum", stringlib_isalnum, METH_NOARGS, 25137db96d56Sopenharmony_ci _Py_isalnum__doc__}, 25147db96d56Sopenharmony_ci {"isalpha", stringlib_isalpha, METH_NOARGS, 25157db96d56Sopenharmony_ci _Py_isalpha__doc__}, 25167db96d56Sopenharmony_ci {"isascii", stringlib_isascii, METH_NOARGS, 25177db96d56Sopenharmony_ci _Py_isascii__doc__}, 25187db96d56Sopenharmony_ci {"isdigit", stringlib_isdigit, METH_NOARGS, 25197db96d56Sopenharmony_ci _Py_isdigit__doc__}, 25207db96d56Sopenharmony_ci {"islower", stringlib_islower, METH_NOARGS, 25217db96d56Sopenharmony_ci _Py_islower__doc__}, 25227db96d56Sopenharmony_ci {"isspace", stringlib_isspace, METH_NOARGS, 25237db96d56Sopenharmony_ci _Py_isspace__doc__}, 25247db96d56Sopenharmony_ci {"istitle", stringlib_istitle, METH_NOARGS, 25257db96d56Sopenharmony_ci _Py_istitle__doc__}, 25267db96d56Sopenharmony_ci {"isupper", stringlib_isupper, METH_NOARGS, 25277db96d56Sopenharmony_ci _Py_isupper__doc__}, 25287db96d56Sopenharmony_ci BYTES_JOIN_METHODDEF 25297db96d56Sopenharmony_ci STRINGLIB_LJUST_METHODDEF 25307db96d56Sopenharmony_ci {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__}, 25317db96d56Sopenharmony_ci BYTES_LSTRIP_METHODDEF 25327db96d56Sopenharmony_ci BYTES_MAKETRANS_METHODDEF 25337db96d56Sopenharmony_ci BYTES_PARTITION_METHODDEF 25347db96d56Sopenharmony_ci BYTES_REPLACE_METHODDEF 25357db96d56Sopenharmony_ci BYTES_REMOVEPREFIX_METHODDEF 25367db96d56Sopenharmony_ci BYTES_REMOVESUFFIX_METHODDEF 25377db96d56Sopenharmony_ci {"rfind", (PyCFunction)bytes_rfind, METH_VARARGS, _Py_rfind__doc__}, 25387db96d56Sopenharmony_ci {"rindex", (PyCFunction)bytes_rindex, METH_VARARGS, _Py_rindex__doc__}, 25397db96d56Sopenharmony_ci STRINGLIB_RJUST_METHODDEF 25407db96d56Sopenharmony_ci BYTES_RPARTITION_METHODDEF 25417db96d56Sopenharmony_ci BYTES_RSPLIT_METHODDEF 25427db96d56Sopenharmony_ci BYTES_RSTRIP_METHODDEF 25437db96d56Sopenharmony_ci BYTES_SPLIT_METHODDEF 25447db96d56Sopenharmony_ci BYTES_SPLITLINES_METHODDEF 25457db96d56Sopenharmony_ci {"startswith", (PyCFunction)bytes_startswith, METH_VARARGS, 25467db96d56Sopenharmony_ci _Py_startswith__doc__}, 25477db96d56Sopenharmony_ci BYTES_STRIP_METHODDEF 25487db96d56Sopenharmony_ci {"swapcase", stringlib_swapcase, METH_NOARGS, 25497db96d56Sopenharmony_ci _Py_swapcase__doc__}, 25507db96d56Sopenharmony_ci {"title", stringlib_title, METH_NOARGS, _Py_title__doc__}, 25517db96d56Sopenharmony_ci BYTES_TRANSLATE_METHODDEF 25527db96d56Sopenharmony_ci {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__}, 25537db96d56Sopenharmony_ci STRINGLIB_ZFILL_METHODDEF 25547db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 25557db96d56Sopenharmony_ci}; 25567db96d56Sopenharmony_ci 25577db96d56Sopenharmony_cistatic PyObject * 25587db96d56Sopenharmony_cibytes_mod(PyObject *self, PyObject *arg) 25597db96d56Sopenharmony_ci{ 25607db96d56Sopenharmony_ci if (!PyBytes_Check(self)) { 25617db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 25627db96d56Sopenharmony_ci } 25637db96d56Sopenharmony_ci return _PyBytes_FormatEx(PyBytes_AS_STRING(self), PyBytes_GET_SIZE(self), 25647db96d56Sopenharmony_ci arg, 0); 25657db96d56Sopenharmony_ci} 25667db96d56Sopenharmony_ci 25677db96d56Sopenharmony_cistatic PyNumberMethods bytes_as_number = { 25687db96d56Sopenharmony_ci 0, /*nb_add*/ 25697db96d56Sopenharmony_ci 0, /*nb_subtract*/ 25707db96d56Sopenharmony_ci 0, /*nb_multiply*/ 25717db96d56Sopenharmony_ci bytes_mod, /*nb_remainder*/ 25727db96d56Sopenharmony_ci}; 25737db96d56Sopenharmony_ci 25747db96d56Sopenharmony_cistatic PyObject * 25757db96d56Sopenharmony_cibytes_subtype_new(PyTypeObject *, PyObject *); 25767db96d56Sopenharmony_ci 25777db96d56Sopenharmony_ci/*[clinic input] 25787db96d56Sopenharmony_ci@classmethod 25797db96d56Sopenharmony_cibytes.__new__ as bytes_new 25807db96d56Sopenharmony_ci 25817db96d56Sopenharmony_ci source as x: object = NULL 25827db96d56Sopenharmony_ci encoding: str = NULL 25837db96d56Sopenharmony_ci errors: str = NULL 25847db96d56Sopenharmony_ci 25857db96d56Sopenharmony_ci[clinic start generated code]*/ 25867db96d56Sopenharmony_ci 25877db96d56Sopenharmony_cistatic PyObject * 25887db96d56Sopenharmony_cibytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding, 25897db96d56Sopenharmony_ci const char *errors) 25907db96d56Sopenharmony_ci/*[clinic end generated code: output=1e0c471be311a425 input=f0a966d19b7262b4]*/ 25917db96d56Sopenharmony_ci{ 25927db96d56Sopenharmony_ci PyObject *bytes; 25937db96d56Sopenharmony_ci PyObject *func; 25947db96d56Sopenharmony_ci Py_ssize_t size; 25957db96d56Sopenharmony_ci 25967db96d56Sopenharmony_ci if (x == NULL) { 25977db96d56Sopenharmony_ci if (encoding != NULL || errors != NULL) { 25987db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 25997db96d56Sopenharmony_ci encoding != NULL ? 26007db96d56Sopenharmony_ci "encoding without a string argument" : 26017db96d56Sopenharmony_ci "errors without a string argument"); 26027db96d56Sopenharmony_ci return NULL; 26037db96d56Sopenharmony_ci } 26047db96d56Sopenharmony_ci bytes = PyBytes_FromStringAndSize(NULL, 0); 26057db96d56Sopenharmony_ci } 26067db96d56Sopenharmony_ci else if (encoding != NULL) { 26077db96d56Sopenharmony_ci /* Encode via the codec registry */ 26087db96d56Sopenharmony_ci if (!PyUnicode_Check(x)) { 26097db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 26107db96d56Sopenharmony_ci "encoding without a string argument"); 26117db96d56Sopenharmony_ci return NULL; 26127db96d56Sopenharmony_ci } 26137db96d56Sopenharmony_ci bytes = PyUnicode_AsEncodedString(x, encoding, errors); 26147db96d56Sopenharmony_ci } 26157db96d56Sopenharmony_ci else if (errors != NULL) { 26167db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 26177db96d56Sopenharmony_ci PyUnicode_Check(x) ? 26187db96d56Sopenharmony_ci "string argument without an encoding" : 26197db96d56Sopenharmony_ci "errors without a string argument"); 26207db96d56Sopenharmony_ci return NULL; 26217db96d56Sopenharmony_ci } 26227db96d56Sopenharmony_ci /* We'd like to call PyObject_Bytes here, but we need to check for an 26237db96d56Sopenharmony_ci integer argument before deferring to PyBytes_FromObject, something 26247db96d56Sopenharmony_ci PyObject_Bytes doesn't do. */ 26257db96d56Sopenharmony_ci else if ((func = _PyObject_LookupSpecial(x, &_Py_ID(__bytes__))) != NULL) { 26267db96d56Sopenharmony_ci bytes = _PyObject_CallNoArgs(func); 26277db96d56Sopenharmony_ci Py_DECREF(func); 26287db96d56Sopenharmony_ci if (bytes == NULL) 26297db96d56Sopenharmony_ci return NULL; 26307db96d56Sopenharmony_ci if (!PyBytes_Check(bytes)) { 26317db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 26327db96d56Sopenharmony_ci "__bytes__ returned non-bytes (type %.200s)", 26337db96d56Sopenharmony_ci Py_TYPE(bytes)->tp_name); 26347db96d56Sopenharmony_ci Py_DECREF(bytes); 26357db96d56Sopenharmony_ci return NULL; 26367db96d56Sopenharmony_ci } 26377db96d56Sopenharmony_ci } 26387db96d56Sopenharmony_ci else if (PyErr_Occurred()) 26397db96d56Sopenharmony_ci return NULL; 26407db96d56Sopenharmony_ci else if (PyUnicode_Check(x)) { 26417db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 26427db96d56Sopenharmony_ci "string argument without an encoding"); 26437db96d56Sopenharmony_ci return NULL; 26447db96d56Sopenharmony_ci } 26457db96d56Sopenharmony_ci /* Is it an integer? */ 26467db96d56Sopenharmony_ci else if (_PyIndex_Check(x)) { 26477db96d56Sopenharmony_ci size = PyNumber_AsSsize_t(x, PyExc_OverflowError); 26487db96d56Sopenharmony_ci if (size == -1 && PyErr_Occurred()) { 26497db96d56Sopenharmony_ci if (!PyErr_ExceptionMatches(PyExc_TypeError)) 26507db96d56Sopenharmony_ci return NULL; 26517db96d56Sopenharmony_ci PyErr_Clear(); /* fall through */ 26527db96d56Sopenharmony_ci bytes = PyBytes_FromObject(x); 26537db96d56Sopenharmony_ci } 26547db96d56Sopenharmony_ci else { 26557db96d56Sopenharmony_ci if (size < 0) { 26567db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, "negative count"); 26577db96d56Sopenharmony_ci return NULL; 26587db96d56Sopenharmony_ci } 26597db96d56Sopenharmony_ci bytes = _PyBytes_FromSize(size, 1); 26607db96d56Sopenharmony_ci } 26617db96d56Sopenharmony_ci } 26627db96d56Sopenharmony_ci else { 26637db96d56Sopenharmony_ci bytes = PyBytes_FromObject(x); 26647db96d56Sopenharmony_ci } 26657db96d56Sopenharmony_ci 26667db96d56Sopenharmony_ci if (bytes != NULL && type != &PyBytes_Type) { 26677db96d56Sopenharmony_ci Py_SETREF(bytes, bytes_subtype_new(type, bytes)); 26687db96d56Sopenharmony_ci } 26697db96d56Sopenharmony_ci 26707db96d56Sopenharmony_ci return bytes; 26717db96d56Sopenharmony_ci} 26727db96d56Sopenharmony_ci 26737db96d56Sopenharmony_cistatic PyObject* 26747db96d56Sopenharmony_ci_PyBytes_FromBuffer(PyObject *x) 26757db96d56Sopenharmony_ci{ 26767db96d56Sopenharmony_ci PyObject *new; 26777db96d56Sopenharmony_ci Py_buffer view; 26787db96d56Sopenharmony_ci 26797db96d56Sopenharmony_ci if (PyObject_GetBuffer(x, &view, PyBUF_FULL_RO) < 0) 26807db96d56Sopenharmony_ci return NULL; 26817db96d56Sopenharmony_ci 26827db96d56Sopenharmony_ci new = PyBytes_FromStringAndSize(NULL, view.len); 26837db96d56Sopenharmony_ci if (!new) 26847db96d56Sopenharmony_ci goto fail; 26857db96d56Sopenharmony_ci if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval, 26867db96d56Sopenharmony_ci &view, view.len, 'C') < 0) 26877db96d56Sopenharmony_ci goto fail; 26887db96d56Sopenharmony_ci PyBuffer_Release(&view); 26897db96d56Sopenharmony_ci return new; 26907db96d56Sopenharmony_ci 26917db96d56Sopenharmony_cifail: 26927db96d56Sopenharmony_ci Py_XDECREF(new); 26937db96d56Sopenharmony_ci PyBuffer_Release(&view); 26947db96d56Sopenharmony_ci return NULL; 26957db96d56Sopenharmony_ci} 26967db96d56Sopenharmony_ci 26977db96d56Sopenharmony_cistatic PyObject* 26987db96d56Sopenharmony_ci_PyBytes_FromList(PyObject *x) 26997db96d56Sopenharmony_ci{ 27007db96d56Sopenharmony_ci Py_ssize_t i, size = PyList_GET_SIZE(x); 27017db96d56Sopenharmony_ci Py_ssize_t value; 27027db96d56Sopenharmony_ci char *str; 27037db96d56Sopenharmony_ci PyObject *item; 27047db96d56Sopenharmony_ci _PyBytesWriter writer; 27057db96d56Sopenharmony_ci 27067db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 27077db96d56Sopenharmony_ci str = _PyBytesWriter_Alloc(&writer, size); 27087db96d56Sopenharmony_ci if (str == NULL) 27097db96d56Sopenharmony_ci return NULL; 27107db96d56Sopenharmony_ci writer.overallocate = 1; 27117db96d56Sopenharmony_ci size = writer.allocated; 27127db96d56Sopenharmony_ci 27137db96d56Sopenharmony_ci for (i = 0; i < PyList_GET_SIZE(x); i++) { 27147db96d56Sopenharmony_ci item = PyList_GET_ITEM(x, i); 27157db96d56Sopenharmony_ci Py_INCREF(item); 27167db96d56Sopenharmony_ci value = PyNumber_AsSsize_t(item, NULL); 27177db96d56Sopenharmony_ci Py_DECREF(item); 27187db96d56Sopenharmony_ci if (value == -1 && PyErr_Occurred()) 27197db96d56Sopenharmony_ci goto error; 27207db96d56Sopenharmony_ci 27217db96d56Sopenharmony_ci if (value < 0 || value >= 256) { 27227db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 27237db96d56Sopenharmony_ci "bytes must be in range(0, 256)"); 27247db96d56Sopenharmony_ci goto error; 27257db96d56Sopenharmony_ci } 27267db96d56Sopenharmony_ci 27277db96d56Sopenharmony_ci if (i >= size) { 27287db96d56Sopenharmony_ci str = _PyBytesWriter_Resize(&writer, str, size+1); 27297db96d56Sopenharmony_ci if (str == NULL) 27307db96d56Sopenharmony_ci return NULL; 27317db96d56Sopenharmony_ci size = writer.allocated; 27327db96d56Sopenharmony_ci } 27337db96d56Sopenharmony_ci *str++ = (char) value; 27347db96d56Sopenharmony_ci } 27357db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, str); 27367db96d56Sopenharmony_ci 27377db96d56Sopenharmony_ci error: 27387db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 27397db96d56Sopenharmony_ci return NULL; 27407db96d56Sopenharmony_ci} 27417db96d56Sopenharmony_ci 27427db96d56Sopenharmony_cistatic PyObject* 27437db96d56Sopenharmony_ci_PyBytes_FromTuple(PyObject *x) 27447db96d56Sopenharmony_ci{ 27457db96d56Sopenharmony_ci PyObject *bytes; 27467db96d56Sopenharmony_ci Py_ssize_t i, size = PyTuple_GET_SIZE(x); 27477db96d56Sopenharmony_ci Py_ssize_t value; 27487db96d56Sopenharmony_ci char *str; 27497db96d56Sopenharmony_ci PyObject *item; 27507db96d56Sopenharmony_ci 27517db96d56Sopenharmony_ci bytes = PyBytes_FromStringAndSize(NULL, size); 27527db96d56Sopenharmony_ci if (bytes == NULL) 27537db96d56Sopenharmony_ci return NULL; 27547db96d56Sopenharmony_ci str = ((PyBytesObject *)bytes)->ob_sval; 27557db96d56Sopenharmony_ci 27567db96d56Sopenharmony_ci for (i = 0; i < size; i++) { 27577db96d56Sopenharmony_ci item = PyTuple_GET_ITEM(x, i); 27587db96d56Sopenharmony_ci value = PyNumber_AsSsize_t(item, NULL); 27597db96d56Sopenharmony_ci if (value == -1 && PyErr_Occurred()) 27607db96d56Sopenharmony_ci goto error; 27617db96d56Sopenharmony_ci 27627db96d56Sopenharmony_ci if (value < 0 || value >= 256) { 27637db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 27647db96d56Sopenharmony_ci "bytes must be in range(0, 256)"); 27657db96d56Sopenharmony_ci goto error; 27667db96d56Sopenharmony_ci } 27677db96d56Sopenharmony_ci *str++ = (char) value; 27687db96d56Sopenharmony_ci } 27697db96d56Sopenharmony_ci return bytes; 27707db96d56Sopenharmony_ci 27717db96d56Sopenharmony_ci error: 27727db96d56Sopenharmony_ci Py_DECREF(bytes); 27737db96d56Sopenharmony_ci return NULL; 27747db96d56Sopenharmony_ci} 27757db96d56Sopenharmony_ci 27767db96d56Sopenharmony_cistatic PyObject * 27777db96d56Sopenharmony_ci_PyBytes_FromIterator(PyObject *it, PyObject *x) 27787db96d56Sopenharmony_ci{ 27797db96d56Sopenharmony_ci char *str; 27807db96d56Sopenharmony_ci Py_ssize_t i, size; 27817db96d56Sopenharmony_ci _PyBytesWriter writer; 27827db96d56Sopenharmony_ci 27837db96d56Sopenharmony_ci /* For iterator version, create a bytes object and resize as needed */ 27847db96d56Sopenharmony_ci size = PyObject_LengthHint(x, 64); 27857db96d56Sopenharmony_ci if (size == -1 && PyErr_Occurred()) 27867db96d56Sopenharmony_ci return NULL; 27877db96d56Sopenharmony_ci 27887db96d56Sopenharmony_ci _PyBytesWriter_Init(&writer); 27897db96d56Sopenharmony_ci str = _PyBytesWriter_Alloc(&writer, size); 27907db96d56Sopenharmony_ci if (str == NULL) 27917db96d56Sopenharmony_ci return NULL; 27927db96d56Sopenharmony_ci writer.overallocate = 1; 27937db96d56Sopenharmony_ci size = writer.allocated; 27947db96d56Sopenharmony_ci 27957db96d56Sopenharmony_ci /* Run the iterator to exhaustion */ 27967db96d56Sopenharmony_ci for (i = 0; ; i++) { 27977db96d56Sopenharmony_ci PyObject *item; 27987db96d56Sopenharmony_ci Py_ssize_t value; 27997db96d56Sopenharmony_ci 28007db96d56Sopenharmony_ci /* Get the next item */ 28017db96d56Sopenharmony_ci item = PyIter_Next(it); 28027db96d56Sopenharmony_ci if (item == NULL) { 28037db96d56Sopenharmony_ci if (PyErr_Occurred()) 28047db96d56Sopenharmony_ci goto error; 28057db96d56Sopenharmony_ci break; 28067db96d56Sopenharmony_ci } 28077db96d56Sopenharmony_ci 28087db96d56Sopenharmony_ci /* Interpret it as an int (__index__) */ 28097db96d56Sopenharmony_ci value = PyNumber_AsSsize_t(item, NULL); 28107db96d56Sopenharmony_ci Py_DECREF(item); 28117db96d56Sopenharmony_ci if (value == -1 && PyErr_Occurred()) 28127db96d56Sopenharmony_ci goto error; 28137db96d56Sopenharmony_ci 28147db96d56Sopenharmony_ci /* Range check */ 28157db96d56Sopenharmony_ci if (value < 0 || value >= 256) { 28167db96d56Sopenharmony_ci PyErr_SetString(PyExc_ValueError, 28177db96d56Sopenharmony_ci "bytes must be in range(0, 256)"); 28187db96d56Sopenharmony_ci goto error; 28197db96d56Sopenharmony_ci } 28207db96d56Sopenharmony_ci 28217db96d56Sopenharmony_ci /* Append the byte */ 28227db96d56Sopenharmony_ci if (i >= size) { 28237db96d56Sopenharmony_ci str = _PyBytesWriter_Resize(&writer, str, size+1); 28247db96d56Sopenharmony_ci if (str == NULL) 28257db96d56Sopenharmony_ci return NULL; 28267db96d56Sopenharmony_ci size = writer.allocated; 28277db96d56Sopenharmony_ci } 28287db96d56Sopenharmony_ci *str++ = (char) value; 28297db96d56Sopenharmony_ci } 28307db96d56Sopenharmony_ci 28317db96d56Sopenharmony_ci return _PyBytesWriter_Finish(&writer, str); 28327db96d56Sopenharmony_ci 28337db96d56Sopenharmony_ci error: 28347db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(&writer); 28357db96d56Sopenharmony_ci return NULL; 28367db96d56Sopenharmony_ci} 28377db96d56Sopenharmony_ci 28387db96d56Sopenharmony_ciPyObject * 28397db96d56Sopenharmony_ciPyBytes_FromObject(PyObject *x) 28407db96d56Sopenharmony_ci{ 28417db96d56Sopenharmony_ci PyObject *it, *result; 28427db96d56Sopenharmony_ci 28437db96d56Sopenharmony_ci if (x == NULL) { 28447db96d56Sopenharmony_ci PyErr_BadInternalCall(); 28457db96d56Sopenharmony_ci return NULL; 28467db96d56Sopenharmony_ci } 28477db96d56Sopenharmony_ci 28487db96d56Sopenharmony_ci if (PyBytes_CheckExact(x)) { 28497db96d56Sopenharmony_ci Py_INCREF(x); 28507db96d56Sopenharmony_ci return x; 28517db96d56Sopenharmony_ci } 28527db96d56Sopenharmony_ci 28537db96d56Sopenharmony_ci /* Use the modern buffer interface */ 28547db96d56Sopenharmony_ci if (PyObject_CheckBuffer(x)) 28557db96d56Sopenharmony_ci return _PyBytes_FromBuffer(x); 28567db96d56Sopenharmony_ci 28577db96d56Sopenharmony_ci if (PyList_CheckExact(x)) 28587db96d56Sopenharmony_ci return _PyBytes_FromList(x); 28597db96d56Sopenharmony_ci 28607db96d56Sopenharmony_ci if (PyTuple_CheckExact(x)) 28617db96d56Sopenharmony_ci return _PyBytes_FromTuple(x); 28627db96d56Sopenharmony_ci 28637db96d56Sopenharmony_ci if (!PyUnicode_Check(x)) { 28647db96d56Sopenharmony_ci it = PyObject_GetIter(x); 28657db96d56Sopenharmony_ci if (it != NULL) { 28667db96d56Sopenharmony_ci result = _PyBytes_FromIterator(it, x); 28677db96d56Sopenharmony_ci Py_DECREF(it); 28687db96d56Sopenharmony_ci return result; 28697db96d56Sopenharmony_ci } 28707db96d56Sopenharmony_ci if (!PyErr_ExceptionMatches(PyExc_TypeError)) { 28717db96d56Sopenharmony_ci return NULL; 28727db96d56Sopenharmony_ci } 28737db96d56Sopenharmony_ci } 28747db96d56Sopenharmony_ci 28757db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, 28767db96d56Sopenharmony_ci "cannot convert '%.200s' object to bytes", 28777db96d56Sopenharmony_ci Py_TYPE(x)->tp_name); 28787db96d56Sopenharmony_ci return NULL; 28797db96d56Sopenharmony_ci} 28807db96d56Sopenharmony_ci 28817db96d56Sopenharmony_ci/* This allocator is needed for subclasses don't want to use __new__. 28827db96d56Sopenharmony_ci * See https://github.com/python/cpython/issues/91020#issuecomment-1096793239 28837db96d56Sopenharmony_ci * 28847db96d56Sopenharmony_ci * This allocator will be removed when ob_shash is removed. 28857db96d56Sopenharmony_ci */ 28867db96d56Sopenharmony_cistatic PyObject * 28877db96d56Sopenharmony_cibytes_alloc(PyTypeObject *self, Py_ssize_t nitems) 28887db96d56Sopenharmony_ci{ 28897db96d56Sopenharmony_ci PyBytesObject *obj = (PyBytesObject*)PyType_GenericAlloc(self, nitems); 28907db96d56Sopenharmony_ci if (obj == NULL) { 28917db96d56Sopenharmony_ci return NULL; 28927db96d56Sopenharmony_ci } 28937db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 28947db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 28957db96d56Sopenharmony_ci obj->ob_shash = -1; 28967db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 28977db96d56Sopenharmony_ci return (PyObject*)obj; 28987db96d56Sopenharmony_ci} 28997db96d56Sopenharmony_ci 29007db96d56Sopenharmony_cistatic PyObject * 29017db96d56Sopenharmony_cibytes_subtype_new(PyTypeObject *type, PyObject *tmp) 29027db96d56Sopenharmony_ci{ 29037db96d56Sopenharmony_ci PyObject *pnew; 29047db96d56Sopenharmony_ci Py_ssize_t n; 29057db96d56Sopenharmony_ci 29067db96d56Sopenharmony_ci assert(PyType_IsSubtype(type, &PyBytes_Type)); 29077db96d56Sopenharmony_ci assert(PyBytes_Check(tmp)); 29087db96d56Sopenharmony_ci n = PyBytes_GET_SIZE(tmp); 29097db96d56Sopenharmony_ci pnew = type->tp_alloc(type, n); 29107db96d56Sopenharmony_ci if (pnew != NULL) { 29117db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(pnew), 29127db96d56Sopenharmony_ci PyBytes_AS_STRING(tmp), n+1); 29137db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 29147db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 29157db96d56Sopenharmony_ci ((PyBytesObject *)pnew)->ob_shash = 29167db96d56Sopenharmony_ci ((PyBytesObject *)tmp)->ob_shash; 29177db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 29187db96d56Sopenharmony_ci } 29197db96d56Sopenharmony_ci return pnew; 29207db96d56Sopenharmony_ci} 29217db96d56Sopenharmony_ci 29227db96d56Sopenharmony_ciPyDoc_STRVAR(bytes_doc, 29237db96d56Sopenharmony_ci"bytes(iterable_of_ints) -> bytes\n\ 29247db96d56Sopenharmony_cibytes(string, encoding[, errors]) -> bytes\n\ 29257db96d56Sopenharmony_cibytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer\n\ 29267db96d56Sopenharmony_cibytes(int) -> bytes object of size given by the parameter initialized with null bytes\n\ 29277db96d56Sopenharmony_cibytes() -> empty bytes object\n\ 29287db96d56Sopenharmony_ci\n\ 29297db96d56Sopenharmony_ciConstruct an immutable array of bytes from:\n\ 29307db96d56Sopenharmony_ci - an iterable yielding integers in range(256)\n\ 29317db96d56Sopenharmony_ci - a text string encoded using the specified encoding\n\ 29327db96d56Sopenharmony_ci - any object implementing the buffer API.\n\ 29337db96d56Sopenharmony_ci - an integer"); 29347db96d56Sopenharmony_ci 29357db96d56Sopenharmony_cistatic PyObject *bytes_iter(PyObject *seq); 29367db96d56Sopenharmony_ci 29377db96d56Sopenharmony_ciPyTypeObject PyBytes_Type = { 29387db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 29397db96d56Sopenharmony_ci "bytes", 29407db96d56Sopenharmony_ci PyBytesObject_SIZE, 29417db96d56Sopenharmony_ci sizeof(char), 29427db96d56Sopenharmony_ci 0, /* tp_dealloc */ 29437db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 29447db96d56Sopenharmony_ci 0, /* tp_getattr */ 29457db96d56Sopenharmony_ci 0, /* tp_setattr */ 29467db96d56Sopenharmony_ci 0, /* tp_as_async */ 29477db96d56Sopenharmony_ci (reprfunc)bytes_repr, /* tp_repr */ 29487db96d56Sopenharmony_ci &bytes_as_number, /* tp_as_number */ 29497db96d56Sopenharmony_ci &bytes_as_sequence, /* tp_as_sequence */ 29507db96d56Sopenharmony_ci &bytes_as_mapping, /* tp_as_mapping */ 29517db96d56Sopenharmony_ci (hashfunc)bytes_hash, /* tp_hash */ 29527db96d56Sopenharmony_ci 0, /* tp_call */ 29537db96d56Sopenharmony_ci bytes_str, /* tp_str */ 29547db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 29557db96d56Sopenharmony_ci 0, /* tp_setattro */ 29567db96d56Sopenharmony_ci &bytes_as_buffer, /* tp_as_buffer */ 29577db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | 29587db96d56Sopenharmony_ci Py_TPFLAGS_BYTES_SUBCLASS | 29597db96d56Sopenharmony_ci _Py_TPFLAGS_MATCH_SELF, /* tp_flags */ 29607db96d56Sopenharmony_ci bytes_doc, /* tp_doc */ 29617db96d56Sopenharmony_ci 0, /* tp_traverse */ 29627db96d56Sopenharmony_ci 0, /* tp_clear */ 29637db96d56Sopenharmony_ci (richcmpfunc)bytes_richcompare, /* tp_richcompare */ 29647db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 29657db96d56Sopenharmony_ci bytes_iter, /* tp_iter */ 29667db96d56Sopenharmony_ci 0, /* tp_iternext */ 29677db96d56Sopenharmony_ci bytes_methods, /* tp_methods */ 29687db96d56Sopenharmony_ci 0, /* tp_members */ 29697db96d56Sopenharmony_ci 0, /* tp_getset */ 29707db96d56Sopenharmony_ci 0, /* tp_base */ 29717db96d56Sopenharmony_ci 0, /* tp_dict */ 29727db96d56Sopenharmony_ci 0, /* tp_descr_get */ 29737db96d56Sopenharmony_ci 0, /* tp_descr_set */ 29747db96d56Sopenharmony_ci 0, /* tp_dictoffset */ 29757db96d56Sopenharmony_ci 0, /* tp_init */ 29767db96d56Sopenharmony_ci bytes_alloc, /* tp_alloc */ 29777db96d56Sopenharmony_ci bytes_new, /* tp_new */ 29787db96d56Sopenharmony_ci PyObject_Del, /* tp_free */ 29797db96d56Sopenharmony_ci}; 29807db96d56Sopenharmony_ci 29817db96d56Sopenharmony_civoid 29827db96d56Sopenharmony_ciPyBytes_Concat(PyObject **pv, PyObject *w) 29837db96d56Sopenharmony_ci{ 29847db96d56Sopenharmony_ci assert(pv != NULL); 29857db96d56Sopenharmony_ci if (*pv == NULL) 29867db96d56Sopenharmony_ci return; 29877db96d56Sopenharmony_ci if (w == NULL) { 29887db96d56Sopenharmony_ci Py_CLEAR(*pv); 29897db96d56Sopenharmony_ci return; 29907db96d56Sopenharmony_ci } 29917db96d56Sopenharmony_ci 29927db96d56Sopenharmony_ci if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) { 29937db96d56Sopenharmony_ci /* Only one reference, so we can resize in place */ 29947db96d56Sopenharmony_ci Py_ssize_t oldsize; 29957db96d56Sopenharmony_ci Py_buffer wb; 29967db96d56Sopenharmony_ci 29977db96d56Sopenharmony_ci if (PyObject_GetBuffer(w, &wb, PyBUF_SIMPLE) != 0) { 29987db96d56Sopenharmony_ci PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s", 29997db96d56Sopenharmony_ci Py_TYPE(w)->tp_name, Py_TYPE(*pv)->tp_name); 30007db96d56Sopenharmony_ci Py_CLEAR(*pv); 30017db96d56Sopenharmony_ci return; 30027db96d56Sopenharmony_ci } 30037db96d56Sopenharmony_ci 30047db96d56Sopenharmony_ci oldsize = PyBytes_GET_SIZE(*pv); 30057db96d56Sopenharmony_ci if (oldsize > PY_SSIZE_T_MAX - wb.len) { 30067db96d56Sopenharmony_ci PyErr_NoMemory(); 30077db96d56Sopenharmony_ci goto error; 30087db96d56Sopenharmony_ci } 30097db96d56Sopenharmony_ci if (_PyBytes_Resize(pv, oldsize + wb.len) < 0) 30107db96d56Sopenharmony_ci goto error; 30117db96d56Sopenharmony_ci 30127db96d56Sopenharmony_ci memcpy(PyBytes_AS_STRING(*pv) + oldsize, wb.buf, wb.len); 30137db96d56Sopenharmony_ci PyBuffer_Release(&wb); 30147db96d56Sopenharmony_ci return; 30157db96d56Sopenharmony_ci 30167db96d56Sopenharmony_ci error: 30177db96d56Sopenharmony_ci PyBuffer_Release(&wb); 30187db96d56Sopenharmony_ci Py_CLEAR(*pv); 30197db96d56Sopenharmony_ci return; 30207db96d56Sopenharmony_ci } 30217db96d56Sopenharmony_ci 30227db96d56Sopenharmony_ci else { 30237db96d56Sopenharmony_ci /* Multiple references, need to create new object */ 30247db96d56Sopenharmony_ci PyObject *v; 30257db96d56Sopenharmony_ci v = bytes_concat(*pv, w); 30267db96d56Sopenharmony_ci Py_SETREF(*pv, v); 30277db96d56Sopenharmony_ci } 30287db96d56Sopenharmony_ci} 30297db96d56Sopenharmony_ci 30307db96d56Sopenharmony_civoid 30317db96d56Sopenharmony_ciPyBytes_ConcatAndDel(PyObject **pv, PyObject *w) 30327db96d56Sopenharmony_ci{ 30337db96d56Sopenharmony_ci PyBytes_Concat(pv, w); 30347db96d56Sopenharmony_ci Py_XDECREF(w); 30357db96d56Sopenharmony_ci} 30367db96d56Sopenharmony_ci 30377db96d56Sopenharmony_ci 30387db96d56Sopenharmony_ci/* The following function breaks the notion that bytes are immutable: 30397db96d56Sopenharmony_ci it changes the size of a bytes object. We get away with this only if there 30407db96d56Sopenharmony_ci is only one module referencing the object. You can also think of it 30417db96d56Sopenharmony_ci as creating a new bytes object and destroying the old one, only 30427db96d56Sopenharmony_ci more efficiently. In any case, don't use this if the bytes object may 30437db96d56Sopenharmony_ci already be known to some other part of the code... 30447db96d56Sopenharmony_ci Note that if there's not enough memory to resize the bytes object, the 30457db96d56Sopenharmony_ci original bytes object at *pv is deallocated, *pv is set to NULL, an "out of 30467db96d56Sopenharmony_ci memory" exception is set, and -1 is returned. Else (on success) 0 is 30477db96d56Sopenharmony_ci returned, and the value in *pv may or may not be the same as on input. 30487db96d56Sopenharmony_ci As always, an extra byte is allocated for a trailing \0 byte (newsize 30497db96d56Sopenharmony_ci does *not* include that), and a trailing \0 byte is stored. 30507db96d56Sopenharmony_ci*/ 30517db96d56Sopenharmony_ci 30527db96d56Sopenharmony_ciint 30537db96d56Sopenharmony_ci_PyBytes_Resize(PyObject **pv, Py_ssize_t newsize) 30547db96d56Sopenharmony_ci{ 30557db96d56Sopenharmony_ci PyObject *v; 30567db96d56Sopenharmony_ci PyBytesObject *sv; 30577db96d56Sopenharmony_ci v = *pv; 30587db96d56Sopenharmony_ci if (!PyBytes_Check(v) || newsize < 0) { 30597db96d56Sopenharmony_ci goto error; 30607db96d56Sopenharmony_ci } 30617db96d56Sopenharmony_ci if (Py_SIZE(v) == newsize) { 30627db96d56Sopenharmony_ci /* return early if newsize equals to v->ob_size */ 30637db96d56Sopenharmony_ci return 0; 30647db96d56Sopenharmony_ci } 30657db96d56Sopenharmony_ci if (Py_SIZE(v) == 0) { 30667db96d56Sopenharmony_ci if (newsize == 0) { 30677db96d56Sopenharmony_ci return 0; 30687db96d56Sopenharmony_ci } 30697db96d56Sopenharmony_ci *pv = _PyBytes_FromSize(newsize, 0); 30707db96d56Sopenharmony_ci Py_DECREF(v); 30717db96d56Sopenharmony_ci return (*pv == NULL) ? -1 : 0; 30727db96d56Sopenharmony_ci } 30737db96d56Sopenharmony_ci if (Py_REFCNT(v) != 1) { 30747db96d56Sopenharmony_ci goto error; 30757db96d56Sopenharmony_ci } 30767db96d56Sopenharmony_ci if (newsize == 0) { 30777db96d56Sopenharmony_ci *pv = bytes_new_empty(); 30787db96d56Sopenharmony_ci Py_DECREF(v); 30797db96d56Sopenharmony_ci return 0; 30807db96d56Sopenharmony_ci } 30817db96d56Sopenharmony_ci /* XXX UNREF/NEWREF interface should be more symmetrical */ 30827db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG 30837db96d56Sopenharmony_ci _Py_RefTotal--; 30847db96d56Sopenharmony_ci#endif 30857db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS 30867db96d56Sopenharmony_ci _Py_ForgetReference(v); 30877db96d56Sopenharmony_ci#endif 30887db96d56Sopenharmony_ci *pv = (PyObject *) 30897db96d56Sopenharmony_ci PyObject_Realloc(v, PyBytesObject_SIZE + newsize); 30907db96d56Sopenharmony_ci if (*pv == NULL) { 30917db96d56Sopenharmony_ci PyObject_Free(v); 30927db96d56Sopenharmony_ci PyErr_NoMemory(); 30937db96d56Sopenharmony_ci return -1; 30947db96d56Sopenharmony_ci } 30957db96d56Sopenharmony_ci _Py_NewReference(*pv); 30967db96d56Sopenharmony_ci sv = (PyBytesObject *) *pv; 30977db96d56Sopenharmony_ci Py_SET_SIZE(sv, newsize); 30987db96d56Sopenharmony_ci sv->ob_sval[newsize] = '\0'; 30997db96d56Sopenharmony_ci_Py_COMP_DIAG_PUSH 31007db96d56Sopenharmony_ci_Py_COMP_DIAG_IGNORE_DEPR_DECLS 31017db96d56Sopenharmony_ci sv->ob_shash = -1; /* invalidate cached hash value */ 31027db96d56Sopenharmony_ci_Py_COMP_DIAG_POP 31037db96d56Sopenharmony_ci return 0; 31047db96d56Sopenharmony_cierror: 31057db96d56Sopenharmony_ci *pv = 0; 31067db96d56Sopenharmony_ci Py_DECREF(v); 31077db96d56Sopenharmony_ci PyErr_BadInternalCall(); 31087db96d56Sopenharmony_ci return -1; 31097db96d56Sopenharmony_ci} 31107db96d56Sopenharmony_ci 31117db96d56Sopenharmony_ci 31127db96d56Sopenharmony_ciPyStatus 31137db96d56Sopenharmony_ci_PyBytes_InitTypes(PyInterpreterState *interp) 31147db96d56Sopenharmony_ci{ 31157db96d56Sopenharmony_ci if (!_Py_IsMainInterpreter(interp)) { 31167db96d56Sopenharmony_ci return _PyStatus_OK(); 31177db96d56Sopenharmony_ci } 31187db96d56Sopenharmony_ci 31197db96d56Sopenharmony_ci if (PyType_Ready(&PyBytes_Type) < 0) { 31207db96d56Sopenharmony_ci return _PyStatus_ERR("Can't initialize bytes type"); 31217db96d56Sopenharmony_ci } 31227db96d56Sopenharmony_ci 31237db96d56Sopenharmony_ci if (PyType_Ready(&PyBytesIter_Type) < 0) { 31247db96d56Sopenharmony_ci return _PyStatus_ERR("Can't initialize bytes iterator type"); 31257db96d56Sopenharmony_ci } 31267db96d56Sopenharmony_ci 31277db96d56Sopenharmony_ci return _PyStatus_OK(); 31287db96d56Sopenharmony_ci} 31297db96d56Sopenharmony_ci 31307db96d56Sopenharmony_ci 31317db96d56Sopenharmony_ci/*********************** Bytes Iterator ****************************/ 31327db96d56Sopenharmony_ci 31337db96d56Sopenharmony_citypedef struct { 31347db96d56Sopenharmony_ci PyObject_HEAD 31357db96d56Sopenharmony_ci Py_ssize_t it_index; 31367db96d56Sopenharmony_ci PyBytesObject *it_seq; /* Set to NULL when iterator is exhausted */ 31377db96d56Sopenharmony_ci} striterobject; 31387db96d56Sopenharmony_ci 31397db96d56Sopenharmony_cistatic void 31407db96d56Sopenharmony_cistriter_dealloc(striterobject *it) 31417db96d56Sopenharmony_ci{ 31427db96d56Sopenharmony_ci _PyObject_GC_UNTRACK(it); 31437db96d56Sopenharmony_ci Py_XDECREF(it->it_seq); 31447db96d56Sopenharmony_ci PyObject_GC_Del(it); 31457db96d56Sopenharmony_ci} 31467db96d56Sopenharmony_ci 31477db96d56Sopenharmony_cistatic int 31487db96d56Sopenharmony_cistriter_traverse(striterobject *it, visitproc visit, void *arg) 31497db96d56Sopenharmony_ci{ 31507db96d56Sopenharmony_ci Py_VISIT(it->it_seq); 31517db96d56Sopenharmony_ci return 0; 31527db96d56Sopenharmony_ci} 31537db96d56Sopenharmony_ci 31547db96d56Sopenharmony_cistatic PyObject * 31557db96d56Sopenharmony_cistriter_next(striterobject *it) 31567db96d56Sopenharmony_ci{ 31577db96d56Sopenharmony_ci PyBytesObject *seq; 31587db96d56Sopenharmony_ci 31597db96d56Sopenharmony_ci assert(it != NULL); 31607db96d56Sopenharmony_ci seq = it->it_seq; 31617db96d56Sopenharmony_ci if (seq == NULL) 31627db96d56Sopenharmony_ci return NULL; 31637db96d56Sopenharmony_ci assert(PyBytes_Check(seq)); 31647db96d56Sopenharmony_ci 31657db96d56Sopenharmony_ci if (it->it_index < PyBytes_GET_SIZE(seq)) { 31667db96d56Sopenharmony_ci return _PyLong_FromUnsignedChar( 31677db96d56Sopenharmony_ci (unsigned char)seq->ob_sval[it->it_index++]); 31687db96d56Sopenharmony_ci } 31697db96d56Sopenharmony_ci 31707db96d56Sopenharmony_ci it->it_seq = NULL; 31717db96d56Sopenharmony_ci Py_DECREF(seq); 31727db96d56Sopenharmony_ci return NULL; 31737db96d56Sopenharmony_ci} 31747db96d56Sopenharmony_ci 31757db96d56Sopenharmony_cistatic PyObject * 31767db96d56Sopenharmony_cistriter_len(striterobject *it, PyObject *Py_UNUSED(ignored)) 31777db96d56Sopenharmony_ci{ 31787db96d56Sopenharmony_ci Py_ssize_t len = 0; 31797db96d56Sopenharmony_ci if (it->it_seq) 31807db96d56Sopenharmony_ci len = PyBytes_GET_SIZE(it->it_seq) - it->it_index; 31817db96d56Sopenharmony_ci return PyLong_FromSsize_t(len); 31827db96d56Sopenharmony_ci} 31837db96d56Sopenharmony_ci 31847db96d56Sopenharmony_ciPyDoc_STRVAR(length_hint_doc, 31857db96d56Sopenharmony_ci "Private method returning an estimate of len(list(it))."); 31867db96d56Sopenharmony_ci 31877db96d56Sopenharmony_cistatic PyObject * 31887db96d56Sopenharmony_cistriter_reduce(striterobject *it, PyObject *Py_UNUSED(ignored)) 31897db96d56Sopenharmony_ci{ 31907db96d56Sopenharmony_ci PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); 31917db96d56Sopenharmony_ci 31927db96d56Sopenharmony_ci /* _PyEval_GetBuiltin can invoke arbitrary code, 31937db96d56Sopenharmony_ci * call must be before access of iterator pointers. 31947db96d56Sopenharmony_ci * see issue #101765 */ 31957db96d56Sopenharmony_ci 31967db96d56Sopenharmony_ci if (it->it_seq != NULL) { 31977db96d56Sopenharmony_ci return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index); 31987db96d56Sopenharmony_ci } else { 31997db96d56Sopenharmony_ci return Py_BuildValue("N(())", iter); 32007db96d56Sopenharmony_ci } 32017db96d56Sopenharmony_ci} 32027db96d56Sopenharmony_ci 32037db96d56Sopenharmony_ciPyDoc_STRVAR(reduce_doc, "Return state information for pickling."); 32047db96d56Sopenharmony_ci 32057db96d56Sopenharmony_cistatic PyObject * 32067db96d56Sopenharmony_cistriter_setstate(striterobject *it, PyObject *state) 32077db96d56Sopenharmony_ci{ 32087db96d56Sopenharmony_ci Py_ssize_t index = PyLong_AsSsize_t(state); 32097db96d56Sopenharmony_ci if (index == -1 && PyErr_Occurred()) 32107db96d56Sopenharmony_ci return NULL; 32117db96d56Sopenharmony_ci if (it->it_seq != NULL) { 32127db96d56Sopenharmony_ci if (index < 0) 32137db96d56Sopenharmony_ci index = 0; 32147db96d56Sopenharmony_ci else if (index > PyBytes_GET_SIZE(it->it_seq)) 32157db96d56Sopenharmony_ci index = PyBytes_GET_SIZE(it->it_seq); /* iterator exhausted */ 32167db96d56Sopenharmony_ci it->it_index = index; 32177db96d56Sopenharmony_ci } 32187db96d56Sopenharmony_ci Py_RETURN_NONE; 32197db96d56Sopenharmony_ci} 32207db96d56Sopenharmony_ci 32217db96d56Sopenharmony_ciPyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); 32227db96d56Sopenharmony_ci 32237db96d56Sopenharmony_cistatic PyMethodDef striter_methods[] = { 32247db96d56Sopenharmony_ci {"__length_hint__", (PyCFunction)striter_len, METH_NOARGS, 32257db96d56Sopenharmony_ci length_hint_doc}, 32267db96d56Sopenharmony_ci {"__reduce__", (PyCFunction)striter_reduce, METH_NOARGS, 32277db96d56Sopenharmony_ci reduce_doc}, 32287db96d56Sopenharmony_ci {"__setstate__", (PyCFunction)striter_setstate, METH_O, 32297db96d56Sopenharmony_ci setstate_doc}, 32307db96d56Sopenharmony_ci {NULL, NULL} /* sentinel */ 32317db96d56Sopenharmony_ci}; 32327db96d56Sopenharmony_ci 32337db96d56Sopenharmony_ciPyTypeObject PyBytesIter_Type = { 32347db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 32357db96d56Sopenharmony_ci "bytes_iterator", /* tp_name */ 32367db96d56Sopenharmony_ci sizeof(striterobject), /* tp_basicsize */ 32377db96d56Sopenharmony_ci 0, /* tp_itemsize */ 32387db96d56Sopenharmony_ci /* methods */ 32397db96d56Sopenharmony_ci (destructor)striter_dealloc, /* tp_dealloc */ 32407db96d56Sopenharmony_ci 0, /* tp_vectorcall_offset */ 32417db96d56Sopenharmony_ci 0, /* tp_getattr */ 32427db96d56Sopenharmony_ci 0, /* tp_setattr */ 32437db96d56Sopenharmony_ci 0, /* tp_as_async */ 32447db96d56Sopenharmony_ci 0, /* tp_repr */ 32457db96d56Sopenharmony_ci 0, /* tp_as_number */ 32467db96d56Sopenharmony_ci 0, /* tp_as_sequence */ 32477db96d56Sopenharmony_ci 0, /* tp_as_mapping */ 32487db96d56Sopenharmony_ci 0, /* tp_hash */ 32497db96d56Sopenharmony_ci 0, /* tp_call */ 32507db96d56Sopenharmony_ci 0, /* tp_str */ 32517db96d56Sopenharmony_ci PyObject_GenericGetAttr, /* tp_getattro */ 32527db96d56Sopenharmony_ci 0, /* tp_setattro */ 32537db96d56Sopenharmony_ci 0, /* tp_as_buffer */ 32547db96d56Sopenharmony_ci Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */ 32557db96d56Sopenharmony_ci 0, /* tp_doc */ 32567db96d56Sopenharmony_ci (traverseproc)striter_traverse, /* tp_traverse */ 32577db96d56Sopenharmony_ci 0, /* tp_clear */ 32587db96d56Sopenharmony_ci 0, /* tp_richcompare */ 32597db96d56Sopenharmony_ci 0, /* tp_weaklistoffset */ 32607db96d56Sopenharmony_ci PyObject_SelfIter, /* tp_iter */ 32617db96d56Sopenharmony_ci (iternextfunc)striter_next, /* tp_iternext */ 32627db96d56Sopenharmony_ci striter_methods, /* tp_methods */ 32637db96d56Sopenharmony_ci 0, 32647db96d56Sopenharmony_ci}; 32657db96d56Sopenharmony_ci 32667db96d56Sopenharmony_cistatic PyObject * 32677db96d56Sopenharmony_cibytes_iter(PyObject *seq) 32687db96d56Sopenharmony_ci{ 32697db96d56Sopenharmony_ci striterobject *it; 32707db96d56Sopenharmony_ci 32717db96d56Sopenharmony_ci if (!PyBytes_Check(seq)) { 32727db96d56Sopenharmony_ci PyErr_BadInternalCall(); 32737db96d56Sopenharmony_ci return NULL; 32747db96d56Sopenharmony_ci } 32757db96d56Sopenharmony_ci it = PyObject_GC_New(striterobject, &PyBytesIter_Type); 32767db96d56Sopenharmony_ci if (it == NULL) 32777db96d56Sopenharmony_ci return NULL; 32787db96d56Sopenharmony_ci it->it_index = 0; 32797db96d56Sopenharmony_ci Py_INCREF(seq); 32807db96d56Sopenharmony_ci it->it_seq = (PyBytesObject *)seq; 32817db96d56Sopenharmony_ci _PyObject_GC_TRACK(it); 32827db96d56Sopenharmony_ci return (PyObject *)it; 32837db96d56Sopenharmony_ci} 32847db96d56Sopenharmony_ci 32857db96d56Sopenharmony_ci 32867db96d56Sopenharmony_ci/* _PyBytesWriter API */ 32877db96d56Sopenharmony_ci 32887db96d56Sopenharmony_ci#ifdef MS_WINDOWS 32897db96d56Sopenharmony_ci /* On Windows, overallocate by 50% is the best factor */ 32907db96d56Sopenharmony_ci# define OVERALLOCATE_FACTOR 2 32917db96d56Sopenharmony_ci#else 32927db96d56Sopenharmony_ci /* On Linux, overallocate by 25% is the best factor */ 32937db96d56Sopenharmony_ci# define OVERALLOCATE_FACTOR 4 32947db96d56Sopenharmony_ci#endif 32957db96d56Sopenharmony_ci 32967db96d56Sopenharmony_civoid 32977db96d56Sopenharmony_ci_PyBytesWriter_Init(_PyBytesWriter *writer) 32987db96d56Sopenharmony_ci{ 32997db96d56Sopenharmony_ci /* Set all attributes before small_buffer to 0 */ 33007db96d56Sopenharmony_ci memset(writer, 0, offsetof(_PyBytesWriter, small_buffer)); 33017db96d56Sopenharmony_ci#ifndef NDEBUG 33027db96d56Sopenharmony_ci memset(writer->small_buffer, PYMEM_CLEANBYTE, 33037db96d56Sopenharmony_ci sizeof(writer->small_buffer)); 33047db96d56Sopenharmony_ci#endif 33057db96d56Sopenharmony_ci} 33067db96d56Sopenharmony_ci 33077db96d56Sopenharmony_civoid 33087db96d56Sopenharmony_ci_PyBytesWriter_Dealloc(_PyBytesWriter *writer) 33097db96d56Sopenharmony_ci{ 33107db96d56Sopenharmony_ci Py_CLEAR(writer->buffer); 33117db96d56Sopenharmony_ci} 33127db96d56Sopenharmony_ci 33137db96d56Sopenharmony_ciPy_LOCAL_INLINE(char*) 33147db96d56Sopenharmony_ci_PyBytesWriter_AsString(_PyBytesWriter *writer) 33157db96d56Sopenharmony_ci{ 33167db96d56Sopenharmony_ci if (writer->use_small_buffer) { 33177db96d56Sopenharmony_ci assert(writer->buffer == NULL); 33187db96d56Sopenharmony_ci return writer->small_buffer; 33197db96d56Sopenharmony_ci } 33207db96d56Sopenharmony_ci else if (writer->use_bytearray) { 33217db96d56Sopenharmony_ci assert(writer->buffer != NULL); 33227db96d56Sopenharmony_ci return PyByteArray_AS_STRING(writer->buffer); 33237db96d56Sopenharmony_ci } 33247db96d56Sopenharmony_ci else { 33257db96d56Sopenharmony_ci assert(writer->buffer != NULL); 33267db96d56Sopenharmony_ci return PyBytes_AS_STRING(writer->buffer); 33277db96d56Sopenharmony_ci } 33287db96d56Sopenharmony_ci} 33297db96d56Sopenharmony_ci 33307db96d56Sopenharmony_ciPy_LOCAL_INLINE(Py_ssize_t) 33317db96d56Sopenharmony_ci_PyBytesWriter_GetSize(_PyBytesWriter *writer, char *str) 33327db96d56Sopenharmony_ci{ 33337db96d56Sopenharmony_ci const char *start = _PyBytesWriter_AsString(writer); 33347db96d56Sopenharmony_ci assert(str != NULL); 33357db96d56Sopenharmony_ci assert(str >= start); 33367db96d56Sopenharmony_ci assert(str - start <= writer->allocated); 33377db96d56Sopenharmony_ci return str - start; 33387db96d56Sopenharmony_ci} 33397db96d56Sopenharmony_ci 33407db96d56Sopenharmony_ci#ifndef NDEBUG 33417db96d56Sopenharmony_ciPy_LOCAL_INLINE(int) 33427db96d56Sopenharmony_ci_PyBytesWriter_CheckConsistency(_PyBytesWriter *writer, char *str) 33437db96d56Sopenharmony_ci{ 33447db96d56Sopenharmony_ci const char *start, *end; 33457db96d56Sopenharmony_ci 33467db96d56Sopenharmony_ci if (writer->use_small_buffer) { 33477db96d56Sopenharmony_ci assert(writer->buffer == NULL); 33487db96d56Sopenharmony_ci } 33497db96d56Sopenharmony_ci else { 33507db96d56Sopenharmony_ci assert(writer->buffer != NULL); 33517db96d56Sopenharmony_ci if (writer->use_bytearray) 33527db96d56Sopenharmony_ci assert(PyByteArray_CheckExact(writer->buffer)); 33537db96d56Sopenharmony_ci else 33547db96d56Sopenharmony_ci assert(PyBytes_CheckExact(writer->buffer)); 33557db96d56Sopenharmony_ci assert(Py_REFCNT(writer->buffer) == 1); 33567db96d56Sopenharmony_ci } 33577db96d56Sopenharmony_ci 33587db96d56Sopenharmony_ci if (writer->use_bytearray) { 33597db96d56Sopenharmony_ci /* bytearray has its own overallocation algorithm, 33607db96d56Sopenharmony_ci writer overallocation must be disabled */ 33617db96d56Sopenharmony_ci assert(!writer->overallocate); 33627db96d56Sopenharmony_ci } 33637db96d56Sopenharmony_ci 33647db96d56Sopenharmony_ci assert(0 <= writer->allocated); 33657db96d56Sopenharmony_ci assert(0 <= writer->min_size && writer->min_size <= writer->allocated); 33667db96d56Sopenharmony_ci /* the last byte must always be null */ 33677db96d56Sopenharmony_ci start = _PyBytesWriter_AsString(writer); 33687db96d56Sopenharmony_ci assert(start[writer->allocated] == 0); 33697db96d56Sopenharmony_ci 33707db96d56Sopenharmony_ci end = start + writer->allocated; 33717db96d56Sopenharmony_ci assert(str != NULL); 33727db96d56Sopenharmony_ci assert(start <= str && str <= end); 33737db96d56Sopenharmony_ci return 1; 33747db96d56Sopenharmony_ci} 33757db96d56Sopenharmony_ci#endif 33767db96d56Sopenharmony_ci 33777db96d56Sopenharmony_civoid* 33787db96d56Sopenharmony_ci_PyBytesWriter_Resize(_PyBytesWriter *writer, void *str, Py_ssize_t size) 33797db96d56Sopenharmony_ci{ 33807db96d56Sopenharmony_ci Py_ssize_t allocated, pos; 33817db96d56Sopenharmony_ci 33827db96d56Sopenharmony_ci assert(_PyBytesWriter_CheckConsistency(writer, str)); 33837db96d56Sopenharmony_ci assert(writer->allocated < size); 33847db96d56Sopenharmony_ci 33857db96d56Sopenharmony_ci allocated = size; 33867db96d56Sopenharmony_ci if (writer->overallocate 33877db96d56Sopenharmony_ci && allocated <= (PY_SSIZE_T_MAX - allocated / OVERALLOCATE_FACTOR)) { 33887db96d56Sopenharmony_ci /* overallocate to limit the number of realloc() */ 33897db96d56Sopenharmony_ci allocated += allocated / OVERALLOCATE_FACTOR; 33907db96d56Sopenharmony_ci } 33917db96d56Sopenharmony_ci 33927db96d56Sopenharmony_ci pos = _PyBytesWriter_GetSize(writer, str); 33937db96d56Sopenharmony_ci if (!writer->use_small_buffer) { 33947db96d56Sopenharmony_ci if (writer->use_bytearray) { 33957db96d56Sopenharmony_ci if (PyByteArray_Resize(writer->buffer, allocated)) 33967db96d56Sopenharmony_ci goto error; 33977db96d56Sopenharmony_ci /* writer->allocated can be smaller than writer->buffer->ob_alloc, 33987db96d56Sopenharmony_ci but we cannot use ob_alloc because bytes may need to be moved 33997db96d56Sopenharmony_ci to use the whole buffer. bytearray uses an internal optimization 34007db96d56Sopenharmony_ci to avoid moving or copying bytes when bytes are removed at the 34017db96d56Sopenharmony_ci beginning (ex: del bytearray[:1]). */ 34027db96d56Sopenharmony_ci } 34037db96d56Sopenharmony_ci else { 34047db96d56Sopenharmony_ci if (_PyBytes_Resize(&writer->buffer, allocated)) 34057db96d56Sopenharmony_ci goto error; 34067db96d56Sopenharmony_ci } 34077db96d56Sopenharmony_ci } 34087db96d56Sopenharmony_ci else { 34097db96d56Sopenharmony_ci /* convert from stack buffer to bytes object buffer */ 34107db96d56Sopenharmony_ci assert(writer->buffer == NULL); 34117db96d56Sopenharmony_ci 34127db96d56Sopenharmony_ci if (writer->use_bytearray) 34137db96d56Sopenharmony_ci writer->buffer = PyByteArray_FromStringAndSize(NULL, allocated); 34147db96d56Sopenharmony_ci else 34157db96d56Sopenharmony_ci writer->buffer = PyBytes_FromStringAndSize(NULL, allocated); 34167db96d56Sopenharmony_ci if (writer->buffer == NULL) 34177db96d56Sopenharmony_ci goto error; 34187db96d56Sopenharmony_ci 34197db96d56Sopenharmony_ci if (pos != 0) { 34207db96d56Sopenharmony_ci char *dest; 34217db96d56Sopenharmony_ci if (writer->use_bytearray) 34227db96d56Sopenharmony_ci dest = PyByteArray_AS_STRING(writer->buffer); 34237db96d56Sopenharmony_ci else 34247db96d56Sopenharmony_ci dest = PyBytes_AS_STRING(writer->buffer); 34257db96d56Sopenharmony_ci memcpy(dest, 34267db96d56Sopenharmony_ci writer->small_buffer, 34277db96d56Sopenharmony_ci pos); 34287db96d56Sopenharmony_ci } 34297db96d56Sopenharmony_ci 34307db96d56Sopenharmony_ci writer->use_small_buffer = 0; 34317db96d56Sopenharmony_ci#ifndef NDEBUG 34327db96d56Sopenharmony_ci memset(writer->small_buffer, PYMEM_CLEANBYTE, 34337db96d56Sopenharmony_ci sizeof(writer->small_buffer)); 34347db96d56Sopenharmony_ci#endif 34357db96d56Sopenharmony_ci } 34367db96d56Sopenharmony_ci writer->allocated = allocated; 34377db96d56Sopenharmony_ci 34387db96d56Sopenharmony_ci str = _PyBytesWriter_AsString(writer) + pos; 34397db96d56Sopenharmony_ci assert(_PyBytesWriter_CheckConsistency(writer, str)); 34407db96d56Sopenharmony_ci return str; 34417db96d56Sopenharmony_ci 34427db96d56Sopenharmony_cierror: 34437db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(writer); 34447db96d56Sopenharmony_ci return NULL; 34457db96d56Sopenharmony_ci} 34467db96d56Sopenharmony_ci 34477db96d56Sopenharmony_civoid* 34487db96d56Sopenharmony_ci_PyBytesWriter_Prepare(_PyBytesWriter *writer, void *str, Py_ssize_t size) 34497db96d56Sopenharmony_ci{ 34507db96d56Sopenharmony_ci Py_ssize_t new_min_size; 34517db96d56Sopenharmony_ci 34527db96d56Sopenharmony_ci assert(_PyBytesWriter_CheckConsistency(writer, str)); 34537db96d56Sopenharmony_ci assert(size >= 0); 34547db96d56Sopenharmony_ci 34557db96d56Sopenharmony_ci if (size == 0) { 34567db96d56Sopenharmony_ci /* nothing to do */ 34577db96d56Sopenharmony_ci return str; 34587db96d56Sopenharmony_ci } 34597db96d56Sopenharmony_ci 34607db96d56Sopenharmony_ci if (writer->min_size > PY_SSIZE_T_MAX - size) { 34617db96d56Sopenharmony_ci PyErr_NoMemory(); 34627db96d56Sopenharmony_ci _PyBytesWriter_Dealloc(writer); 34637db96d56Sopenharmony_ci return NULL; 34647db96d56Sopenharmony_ci } 34657db96d56Sopenharmony_ci new_min_size = writer->min_size + size; 34667db96d56Sopenharmony_ci 34677db96d56Sopenharmony_ci if (new_min_size > writer->allocated) 34687db96d56Sopenharmony_ci str = _PyBytesWriter_Resize(writer, str, new_min_size); 34697db96d56Sopenharmony_ci 34707db96d56Sopenharmony_ci writer->min_size = new_min_size; 34717db96d56Sopenharmony_ci return str; 34727db96d56Sopenharmony_ci} 34737db96d56Sopenharmony_ci 34747db96d56Sopenharmony_ci/* Allocate the buffer to write size bytes. 34757db96d56Sopenharmony_ci Return the pointer to the beginning of buffer data. 34767db96d56Sopenharmony_ci Raise an exception and return NULL on error. */ 34777db96d56Sopenharmony_civoid* 34787db96d56Sopenharmony_ci_PyBytesWriter_Alloc(_PyBytesWriter *writer, Py_ssize_t size) 34797db96d56Sopenharmony_ci{ 34807db96d56Sopenharmony_ci /* ensure that _PyBytesWriter_Alloc() is only called once */ 34817db96d56Sopenharmony_ci assert(writer->min_size == 0 && writer->buffer == NULL); 34827db96d56Sopenharmony_ci assert(size >= 0); 34837db96d56Sopenharmony_ci 34847db96d56Sopenharmony_ci writer->use_small_buffer = 1; 34857db96d56Sopenharmony_ci#ifndef NDEBUG 34867db96d56Sopenharmony_ci writer->allocated = sizeof(writer->small_buffer) - 1; 34877db96d56Sopenharmony_ci /* In debug mode, don't use the full small buffer because it is less 34887db96d56Sopenharmony_ci efficient than bytes and bytearray objects to detect buffer underflow 34897db96d56Sopenharmony_ci and buffer overflow. Use 10 bytes of the small buffer to test also 34907db96d56Sopenharmony_ci code using the smaller buffer in debug mode. 34917db96d56Sopenharmony_ci 34927db96d56Sopenharmony_ci Don't modify the _PyBytesWriter structure (use a shorter small buffer) 34937db96d56Sopenharmony_ci in debug mode to also be able to detect stack overflow when running 34947db96d56Sopenharmony_ci tests in debug mode. The _PyBytesWriter is large (more than 512 bytes), 34957db96d56Sopenharmony_ci if _Py_EnterRecursiveCall() is not used in deep C callback, we may hit a 34967db96d56Sopenharmony_ci stack overflow. */ 34977db96d56Sopenharmony_ci writer->allocated = Py_MIN(writer->allocated, 10); 34987db96d56Sopenharmony_ci /* _PyBytesWriter_CheckConsistency() requires the last byte to be 0, 34997db96d56Sopenharmony_ci to detect buffer overflow */ 35007db96d56Sopenharmony_ci writer->small_buffer[writer->allocated] = 0; 35017db96d56Sopenharmony_ci#else 35027db96d56Sopenharmony_ci writer->allocated = sizeof(writer->small_buffer); 35037db96d56Sopenharmony_ci#endif 35047db96d56Sopenharmony_ci return _PyBytesWriter_Prepare(writer, writer->small_buffer, size); 35057db96d56Sopenharmony_ci} 35067db96d56Sopenharmony_ci 35077db96d56Sopenharmony_ciPyObject * 35087db96d56Sopenharmony_ci_PyBytesWriter_Finish(_PyBytesWriter *writer, void *str) 35097db96d56Sopenharmony_ci{ 35107db96d56Sopenharmony_ci Py_ssize_t size; 35117db96d56Sopenharmony_ci PyObject *result; 35127db96d56Sopenharmony_ci 35137db96d56Sopenharmony_ci assert(_PyBytesWriter_CheckConsistency(writer, str)); 35147db96d56Sopenharmony_ci 35157db96d56Sopenharmony_ci size = _PyBytesWriter_GetSize(writer, str); 35167db96d56Sopenharmony_ci if (size == 0 && !writer->use_bytearray) { 35177db96d56Sopenharmony_ci Py_CLEAR(writer->buffer); 35187db96d56Sopenharmony_ci /* Get the empty byte string singleton */ 35197db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(NULL, 0); 35207db96d56Sopenharmony_ci } 35217db96d56Sopenharmony_ci else if (writer->use_small_buffer) { 35227db96d56Sopenharmony_ci if (writer->use_bytearray) { 35237db96d56Sopenharmony_ci result = PyByteArray_FromStringAndSize(writer->small_buffer, size); 35247db96d56Sopenharmony_ci } 35257db96d56Sopenharmony_ci else { 35267db96d56Sopenharmony_ci result = PyBytes_FromStringAndSize(writer->small_buffer, size); 35277db96d56Sopenharmony_ci } 35287db96d56Sopenharmony_ci } 35297db96d56Sopenharmony_ci else { 35307db96d56Sopenharmony_ci result = writer->buffer; 35317db96d56Sopenharmony_ci writer->buffer = NULL; 35327db96d56Sopenharmony_ci 35337db96d56Sopenharmony_ci if (size != writer->allocated) { 35347db96d56Sopenharmony_ci if (writer->use_bytearray) { 35357db96d56Sopenharmony_ci if (PyByteArray_Resize(result, size)) { 35367db96d56Sopenharmony_ci Py_DECREF(result); 35377db96d56Sopenharmony_ci return NULL; 35387db96d56Sopenharmony_ci } 35397db96d56Sopenharmony_ci } 35407db96d56Sopenharmony_ci else { 35417db96d56Sopenharmony_ci if (_PyBytes_Resize(&result, size)) { 35427db96d56Sopenharmony_ci assert(result == NULL); 35437db96d56Sopenharmony_ci return NULL; 35447db96d56Sopenharmony_ci } 35457db96d56Sopenharmony_ci } 35467db96d56Sopenharmony_ci } 35477db96d56Sopenharmony_ci } 35487db96d56Sopenharmony_ci return result; 35497db96d56Sopenharmony_ci} 35507db96d56Sopenharmony_ci 35517db96d56Sopenharmony_civoid* 35527db96d56Sopenharmony_ci_PyBytesWriter_WriteBytes(_PyBytesWriter *writer, void *ptr, 35537db96d56Sopenharmony_ci const void *bytes, Py_ssize_t size) 35547db96d56Sopenharmony_ci{ 35557db96d56Sopenharmony_ci char *str = (char *)ptr; 35567db96d56Sopenharmony_ci 35577db96d56Sopenharmony_ci str = _PyBytesWriter_Prepare(writer, str, size); 35587db96d56Sopenharmony_ci if (str == NULL) 35597db96d56Sopenharmony_ci return NULL; 35607db96d56Sopenharmony_ci 35617db96d56Sopenharmony_ci memcpy(str, bytes, size); 35627db96d56Sopenharmony_ci str += size; 35637db96d56Sopenharmony_ci 35647db96d56Sopenharmony_ci return str; 35657db96d56Sopenharmony_ci} 35667db96d56Sopenharmony_ci 35677db96d56Sopenharmony_ci 35687db96d56Sopenharmony_civoid 35697db96d56Sopenharmony_ci_PyBytes_Repeat(char* dest, Py_ssize_t len_dest, 35707db96d56Sopenharmony_ci const char* src, Py_ssize_t len_src) 35717db96d56Sopenharmony_ci{ 35727db96d56Sopenharmony_ci if (len_dest == 0) { 35737db96d56Sopenharmony_ci return; 35747db96d56Sopenharmony_ci } 35757db96d56Sopenharmony_ci if (len_src == 1) { 35767db96d56Sopenharmony_ci memset(dest, src[0], len_dest); 35777db96d56Sopenharmony_ci } 35787db96d56Sopenharmony_ci else { 35797db96d56Sopenharmony_ci if (src != dest) { 35807db96d56Sopenharmony_ci memcpy(dest, src, len_src); 35817db96d56Sopenharmony_ci } 35827db96d56Sopenharmony_ci Py_ssize_t copied = len_src; 35837db96d56Sopenharmony_ci while (copied < len_dest) { 35847db96d56Sopenharmony_ci Py_ssize_t bytes_to_copy = Py_MIN(copied, len_dest - copied); 35857db96d56Sopenharmony_ci memcpy(dest + copied, dest, bytes_to_copy); 35867db96d56Sopenharmony_ci copied += bytes_to_copy; 35877db96d56Sopenharmony_ci } 35887db96d56Sopenharmony_ci } 35897db96d56Sopenharmony_ci} 35907db96d56Sopenharmony_ci 3591