Skip to content

Commit 3b165ef

Browse files
committed
Implement find() method
1 parent 9975948 commit 3b165ef

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/cstring.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,34 @@ static PyObject *cstring_count(PyObject *self, PyObject *args) {
231231
return PyLong_FromLong(result);
232232
}
233233

234+
PyDoc_STRVAR(find__doc__, "");
235+
PyObject *cstring_find(PyObject *self, PyObject *args) {
236+
PyObject *substr_obj;
237+
Py_ssize_t start = 0;
238+
Py_ssize_t end = PY_SSIZE_T_MAX;
239+
240+
if(!PyArg_ParseTuple(args, "O|nn", &substr_obj, &start, &end))
241+
return NULL;
242+
243+
Py_ssize_t substr_len;
244+
const char *substr = _obj_to_utf8(substr_obj, &substr_len);
245+
if(!substr)
246+
return NULL;
247+
248+
start = _fix_index(start, cstring_len(self));
249+
end = _fix_index(end, cstring_len(self));
250+
251+
char *p = strstr(&CSTRING_VALUE(self)[start], substr);
252+
if(!p)
253+
return PyLong_FromLong(-1);
254+
255+
Py_ssize_t result = p - CSTRING_VALUE(self);
256+
if(result + substr_len > end)
257+
return PyLong_FromLong(-1);
258+
259+
return PyLong_FromSsize_t(result);
260+
}
261+
234262
static PySequenceMethods cstring_as_sequence = {
235263
.sq_length = cstring_len,
236264
.sq_concat = cstring_concat,
@@ -246,6 +274,7 @@ static PyMappingMethods cstring_as_mapping = {
246274

247275
static PyMethodDef cstring_methods[] = {
248276
{"count", cstring_count, METH_VARARGS, count__doc__},
277+
{"find", cstring_find, METH_VARARGS, find__doc__},
249278
{0},
250279
};
251280

test/test_methods.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,18 @@ def test_count_str_unicode():
2020
target = cstring('🙂 🙃 🙂 🙂 🙃 🙂 🙂')
2121
assert target.count('🙂') == 5
2222

23+
24+
def test_find():
25+
target = cstring('hello')
26+
assert target.find('lo') == 3
27+
28+
29+
def test_find_with_start():
30+
target = cstring('hello')
31+
assert target.find('lo', 3) == 3
32+
33+
34+
def test_find_missing():
35+
target = cstring('hello')
36+
assert target.find('lo', 0, 4) == -1
37+

0 commit comments

Comments
 (0)