Line data Source code
1 : /* stringlib: replace implementation */ 2 : 3 : #ifndef STRINGLIB_FASTSEARCH_H 4 : #error must include "stringlib/fastsearch.h" before including this module 5 : #endif 6 : 7 : Py_LOCAL_INLINE(void) 8 35157 : STRINGLIB(replace_1char_inplace)(STRINGLIB_CHAR* s, STRINGLIB_CHAR* end, 9 : Py_UCS4 u1, Py_UCS4 u2, Py_ssize_t maxcount) 10 : { 11 35157 : *s = u2; 12 65081 : while (--maxcount && ++s != end) { 13 : /* Find the next character to be replaced. 14 : 15 : If it occurs often, it is faster to scan for it using an inline 16 : loop. If it occurs seldom, it is faster to scan for it using a 17 : function call; the overhead of the function call is amortized 18 : across the many characters that call covers. We start with an 19 : inline loop and use a heuristic to determine whether to fall back 20 : to a function call. */ 21 64645 : if (*s != u1) { 22 52900 : int attempts = 10; 23 : /* search u1 in a dummy loop */ 24 : while (1) { 25 389347 : if (++s == end) 26 22455 : return; 27 366892 : if (*s == u1) 28 15148 : break; 29 351744 : if (!--attempts) { 30 : /* if u1 was not found for attempts iterations, 31 : use FASTSEARCH() or memchr() */ 32 : #ifdef STRINGLIB_FAST_MEMCHR 33 15291 : s++; 34 15291 : s = STRINGLIB_FAST_MEMCHR(s, u1, end - s); 35 15291 : if (s == NULL) 36 12264 : return; 37 : #else 38 : Py_ssize_t i; 39 6 : STRINGLIB_CHAR ch1 = (STRINGLIB_CHAR) u1; 40 6 : s++; 41 6 : i = FASTSEARCH(s, end - s, &ch1, 1, 0, FAST_SEARCH); 42 6 : if (i < 0) 43 2 : return; 44 4 : s += i; 45 : #endif 46 : /* restart the dummy loop */ 47 3031 : break; 48 : } 49 : } 50 : } 51 29924 : *s = u2; 52 : } 53 : }