1/* stringlib: partition implementation */
2
3#ifndef STRINGLIB_PARTITION_H
4#define STRINGLIB_PARTITION_H
5
6#ifndef STRINGLIB_FASTSEARCH_H
7#error must include "stringlib/fastsearch.h" before including this module
8#endif
9
10Py_LOCAL_INLINE(PyObject*)
11stringlib_partition(PyObject* str_obj,
12                    const STRINGLIB_CHAR* str, Py_ssize_t str_len,
13                    PyObject* sep_obj,
14                    const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
15{
16    PyObject* out;
17    Py_ssize_t pos;
18
19    if (sep_len == 0) {
20        PyErr_SetString(PyExc_ValueError, "empty separator");
21        return NULL;
22    }
23
24    out = PyTuple_New(3);
25    if (!out)
26        return NULL;
27
28    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH);
29
30    if (pos < 0) {
31#if STRINGLIB_MUTABLE
32        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
33        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
34        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
35#else
36        Py_INCREF(str_obj);
37        PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
38        Py_INCREF(STRINGLIB_EMPTY);
39        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
40        Py_INCREF(STRINGLIB_EMPTY);
41        PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
42#endif
43        return out;
44    }
45
46    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
47    Py_INCREF(sep_obj);
48    PyTuple_SET_ITEM(out, 1, sep_obj);
49    pos += sep_len;
50    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
51
52    if (PyErr_Occurred()) {
53        Py_DECREF(out);
54        return NULL;
55    }
56
57    return out;
58}
59
60Py_LOCAL_INLINE(PyObject*)
61stringlib_rpartition(PyObject* str_obj,
62                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
63                     PyObject* sep_obj,
64                     const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
65{
66    PyObject* out;
67    Py_ssize_t pos;
68
69    if (sep_len == 0) {
70        PyErr_SetString(PyExc_ValueError, "empty separator");
71        return NULL;
72    }
73
74    out = PyTuple_New(3);
75    if (!out)
76        return NULL;
77
78    pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
79
80    if (pos < 0) {
81#if STRINGLIB_MUTABLE
82        PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
83        PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
84        PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
85#else
86        Py_INCREF(STRINGLIB_EMPTY);
87        PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
88        Py_INCREF(STRINGLIB_EMPTY);
89        PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
90        Py_INCREF(str_obj);
91        PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
92#endif
93        return out;
94    }
95
96    PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
97    Py_INCREF(sep_obj);
98    PyTuple_SET_ITEM(out, 1, sep_obj);
99    pos += sep_len;
100    PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
101
102    if (PyErr_Occurred()) {
103        Py_DECREF(out);
104        return NULL;
105    }
106
107    return out;
108}
109
110#endif
111