@@ -248,19 +248,22 @@ mmap_read_method(mmap_object *self,
248248}
249249
250250static PyObject *
251- mmap_find_method (mmap_object * self ,
252- PyObject * args )
251+ mmap_gfind (mmap_object * self ,
252+ PyObject * args ,
253+ int reverse )
253254{
254255 Py_ssize_t start = self -> pos ;
256+ Py_ssize_t end = self -> size ;
255257 char * needle ;
256258 Py_ssize_t len ;
257259
258260 CHECK_VALID (NULL );
259- if (!PyArg_ParseTuple (args , "s#|n:find" , & needle , & len , & start )) {
261+ if (!PyArg_ParseTuple (args , reverse ? "s#|nn:rfind" : "s#|nn:find" ,
262+ & needle , & len , & start , & end )) {
260263 return NULL ;
261264 } else {
262265 char * p ;
263- char * e = self -> data + self -> size ;
266+ char sign = reverse ? -1 : 1 ;
264267
265268 if (start < 0 )
266269 start += self -> size ;
@@ -269,7 +272,18 @@ mmap_find_method(mmap_object *self,
269272 else if ((size_t )start > self -> size )
270273 start = self -> size ;
271274
272- for (p = self -> data + start ; p + len <= e ; ++ p ) {
275+ if (end < 0 )
276+ end += self -> size ;
277+ if (end < 0 )
278+ end = 0 ;
279+ else if ((size_t )end > self -> size )
280+ end = self -> size ;
281+
282+ start += (Py_ssize_t )self -> data ;
283+ end += (Py_ssize_t )self -> data ;
284+
285+ for (p = (char * )(reverse ? end - len : start );
286+ p >= (char * )start && p + len <= (char * )end ; p += sign ) {
273287 Py_ssize_t i ;
274288 for (i = 0 ; i < len && needle [i ] == p [i ]; ++ i )
275289 /* nothing */ ;
@@ -281,6 +295,20 @@ mmap_find_method(mmap_object *self,
281295 }
282296}
283297
298+ static PyObject *
299+ mmap_find_method (mmap_object * self ,
300+ PyObject * args )
301+ {
302+ return mmap_gfind (self , args , 0 );
303+ }
304+
305+ static PyObject *
306+ mmap_rfind_method (mmap_object * self ,
307+ PyObject * args )
308+ {
309+ return mmap_gfind (self , args , 1 );
310+ }
311+
284312static int
285313is_writeable (mmap_object * self )
286314{
@@ -593,6 +621,7 @@ mmap_move_method(mmap_object *self, PyObject *args)
593621static struct PyMethodDef mmap_object_methods [] = {
594622 {"close" , (PyCFunction ) mmap_close_method , METH_NOARGS },
595623 {"find" , (PyCFunction ) mmap_find_method , METH_VARARGS },
624+ {"rfind" , (PyCFunction ) mmap_rfind_method , METH_VARARGS },
596625 {"flush" , (PyCFunction ) mmap_flush_method , METH_VARARGS },
597626 {"move" , (PyCFunction ) mmap_move_method , METH_VARARGS },
598627 {"read" , (PyCFunction ) mmap_read_method , METH_VARARGS },
0 commit comments