@@ -6,8 +6,9 @@ struct cstring {
66 char value [];
77};
88
9- #define CSTRING_HASH (self ) (((struct cstring *)self)->hash)
10- #define CSTRING_VALUE (self ) (((struct cstring *)self)->value)
9+ #define CSTRING_HASH (self ) (((struct cstring *)self)->hash)
10+ #define CSTRING_VALUE (self ) (((struct cstring *)self)->value)
11+ #define CSTRING_VALUE_AT (self , i ) (&CSTRING_VALUE(self)[(i)])
1112
1213
1314static PyObject * _cstring_new (PyTypeObject * type , const char * value , size_t len ) {
@@ -132,7 +133,7 @@ static Py_ssize_t _ensure_valid_index(PyObject *self, Py_ssize_t i) {
132133static PyObject * cstring_item (PyObject * self , Py_ssize_t i ) {
133134 if (_ensure_valid_index (self , i ) < 0 )
134135 return NULL ;
135- return _cstring_new (Py_TYPE (self ), & CSTRING_VALUE (self )[ i ] , 1 );
136+ return _cstring_new (Py_TYPE (self ), CSTRING_VALUE_AT (self , i ) , 1 );
136137}
137138
138139static int cstring_contains (PyObject * self , PyObject * arg ) {
@@ -160,7 +161,7 @@ static PyObject *_cstring_subscript_slice(PyObject *self, PyObject *slice) {
160161 assert (slicelen >= 0 );
161162
162163 struct cstring * new = Py_TYPE (self )-> tp_alloc (Py_TYPE (self ), slicelen + 1 );
163- char * src = & CSTRING_VALUE (self )[ start ] ;
164+ char * src = CSTRING_VALUE_AT (self , start ) ;
164165 for (Py_ssize_t i = 0 ; i < slicelen ; ++ i ) {
165166 new -> value [i ] = * src ;
166167 src += step ;
@@ -202,8 +203,14 @@ static Py_ssize_t _fix_index(Py_ssize_t i, Py_ssize_t len) {
202203 return result ;
203204}
204205
205- PyDoc_STRVAR (count__doc__ , "" );
206- static PyObject * cstring_count (PyObject * self , PyObject * args ) {
206+ struct _substr_params {
207+ const char * start ;
208+ const char * end ;
209+ const char * substr ;
210+ Py_ssize_t substr_len ;
211+ };
212+
213+ static struct _substr_params * _parse_substr_args (PyObject * self , PyObject * args , struct _substr_params * params ) {
207214 PyObject * substr_obj ;
208215 Py_ssize_t start = 0 ;
209216 Py_ssize_t end = PY_SSIZE_T_MAX ;
@@ -219,12 +226,27 @@ static PyObject *cstring_count(PyObject *self, PyObject *args) {
219226 start = _fix_index (start , cstring_len (self ));
220227 end = _fix_index (end , cstring_len (self ));
221228
222- char * p = & CSTRING_VALUE (self )[start ];
229+ params -> start = CSTRING_VALUE_AT (self , start );
230+ params -> end = CSTRING_VALUE_AT (self , end );
231+ params -> substr = substr ;
232+ params -> substr_len = substr_len ;
233+
234+ return params ;
235+ }
236+
237+ PyDoc_STRVAR (count__doc__ , "" );
238+ static PyObject * cstring_count (PyObject * self , PyObject * args ) {
239+ struct _substr_params params ;
240+
241+ if (!_parse_substr_args (self , args , & params ))
242+ return NULL ;
243+
244+ char * p = params .start ;
223245 long result = 0 ;
224- while ((p = strstr (p , substr )) != NULL ) {
246+ while ((p = strstr (p , params . substr )) != NULL ) {
225247 ++ result ;
226- p += substr_len ;
227- if (p >= & CSTRING_VALUE ( self )[ end ] )
248+ p += params . substr_len ;
249+ if (p >= params . end )
228250 break ;
229251 }
230252
@@ -233,30 +255,18 @@ static PyObject *cstring_count(PyObject *self, PyObject *args) {
233255
234256PyDoc_STRVAR (find__doc__ , "" );
235257PyObject * 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 ;
258+ struct _substr_params params ;
239259
240- if (!PyArg_ParseTuple ( args , "O|nn" , & substr_obj , & start , & end ))
260+ if (!_parse_substr_args ( self , args , & params ))
241261 return NULL ;
242262
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 );
263+ char * p = strstr (params .start , params .substr );
252264 if (!p )
253265 return PyLong_FromLong (-1 );
254-
255- Py_ssize_t result = p - CSTRING_VALUE (self );
256- if (result + substr_len > end )
266+ if (p + params .substr_len > params .end )
257267 return PyLong_FromLong (-1 );
258268
259- return PyLong_FromSsize_t (result );
269+ return PyLong_FromSsize_t (p - CSTRING_VALUE ( self ) );
260270}
261271
262272static PySequenceMethods cstring_as_sequence = {
0 commit comments