diff options
Diffstat (limited to 'Objects/stringlib/join.h')
-rw-r--r-- | Objects/stringlib/join.h | 140 |
1 files changed, 0 insertions, 140 deletions
diff --git a/Objects/stringlib/join.h b/Objects/stringlib/join.h deleted file mode 100644 index 6f314e1..0000000 --- a/Objects/stringlib/join.h +++ /dev/null @@ -1,140 +0,0 @@ -/* stringlib: bytes joining implementation */ - -#if STRINGLIB_IS_UNICODE -#error join.h only compatible with byte-wise strings -#endif - -Py_LOCAL_INLINE(PyObject *) -STRINGLIB(bytes_join)(PyObject *sep, PyObject *iterable) -{ - char *sepstr = STRINGLIB_STR(sep); - const Py_ssize_t seplen = STRINGLIB_LEN(sep); - PyObject *res = NULL; - char *p; - Py_ssize_t seqlen = 0; - Py_ssize_t sz = 0; - Py_ssize_t i, nbufs; - PyObject *seq, *item; - Py_buffer *buffers = NULL; -#define NB_STATIC_BUFFERS 10 - Py_buffer static_buffers[NB_STATIC_BUFFERS]; - - seq = PySequence_Fast(iterable, "can only join an iterable"); - if (seq == NULL) { - return NULL; - } - - seqlen = PySequence_Fast_GET_SIZE(seq); - if (seqlen == 0) { - Py_DECREF(seq); - return STRINGLIB_NEW(NULL, 0); - } -#ifndef STRINGLIB_MUTABLE - if (seqlen == 1) { - item = PySequence_Fast_GET_ITEM(seq, 0); - if (STRINGLIB_CHECK_EXACT(item)) { - Py_INCREF(item); - Py_DECREF(seq); - return item; - } - } -#endif - if (seqlen > NB_STATIC_BUFFERS) { - buffers = PyMem_NEW(Py_buffer, seqlen); - if (buffers == NULL) { - Py_DECREF(seq); - PyErr_NoMemory(); - return NULL; - } - } - else { - buffers = static_buffers; - } - - /* Here is the general case. Do a pre-pass to figure out the total - * amount of space we'll need (sz), and see whether all arguments are - * bytes-like. - */ - for (i = 0, nbufs = 0; i < seqlen; i++) { - Py_ssize_t itemlen; - item = PySequence_Fast_GET_ITEM(seq, i); - if (PyBytes_CheckExact(item)) { - /* Fast path. */ - Py_INCREF(item); - buffers[i].obj = item; - buffers[i].buf = PyBytes_AS_STRING(item); - buffers[i].len = PyBytes_GET_SIZE(item); - } - else if (PyObject_GetBuffer(item, &buffers[i], PyBUF_SIMPLE) != 0) { - PyErr_Format(PyExc_TypeError, - "sequence item %zd: expected a bytes-like object, " - "%.80s found", - i, Py_TYPE(item)->tp_name); - goto error; - } - nbufs = i + 1; /* for error cleanup */ - itemlen = buffers[i].len; - if (itemlen > PY_SSIZE_T_MAX - sz) { - PyErr_SetString(PyExc_OverflowError, - "join() result is too long"); - goto error; - } - sz += itemlen; - if (i != 0) { - if (seplen > PY_SSIZE_T_MAX - sz) { - PyErr_SetString(PyExc_OverflowError, - "join() result is too long"); - goto error; - } - sz += seplen; - } - if (seqlen != PySequence_Fast_GET_SIZE(seq)) { - PyErr_SetString(PyExc_RuntimeError, - "sequence changed size during iteration"); - goto error; - } - } - - /* Allocate result space. */ - res = STRINGLIB_NEW(NULL, sz); - if (res == NULL) - goto error; - - /* Catenate everything. */ - p = STRINGLIB_STR(res); - if (!seplen) { - /* fast path */ - for (i = 0; i < nbufs; i++) { - Py_ssize_t n = buffers[i].len; - char *q = buffers[i].buf; - memcpy(p, q, n); - p += n; - } - goto done; - } - for (i = 0; i < nbufs; i++) { - Py_ssize_t n; - char *q; - if (i) { - memcpy(p, sepstr, seplen); - p += seplen; - } - n = buffers[i].len; - q = buffers[i].buf; - memcpy(p, q, n); - p += n; - } - goto done; - -error: - res = NULL; -done: - Py_DECREF(seq); - for (i = 0; i < nbufs; i++) - PyBuffer_Release(&buffers[i]); - if (buffers != static_buffers) - PyMem_FREE(buffers); - return res; -} - -#undef NB_STATIC_BUFFERS |