您的位置:首页 > 编程语言 > PHP开发

php strripos 字符串查找函数内部源码实现

2013-05-30 00:00 591 查看
和stripos实现不相同,除开查找方式不一样即返回的地址不一样外,个人感觉strripos比stripos的实现在条件判断上更好(看strripos函数的判断,绿色字体的地方)。

/* {{{ proto int strripos(string haystack, string needle [, int offset])
Finds position of last occurrence of a string within another string */

PHP_FUNCTION(strripos)

{

zval *zneedle;

char *needle, *haystack;

int needle_len, haystack_len;

long offset = 0;

char *p, *e, ord_needle[2];

char *needle_dup, *haystack_dup;

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) {

RETURN_FALSE;

}

if (Z_TYPE_P(zneedle) == IS_STRING) {

needle = Z_STRVAL_P(zneedle);

needle_len = Z_STRLEN_P(zneedle);

} else {

if (php_needle_char(zneedle, ord_needle TSRMLS_CC) != SUCCESS) {

RETURN_FALSE;

}

ord_needle[1] = '\0';

needle = ord_needle;

needle_len = 1;

}

if ((haystack_len == 0) || (needle_len == 0)) {

RETURN_FALSE;

}

if (needle_len == 1) {

/* Single character search can shortcut memcmps

Can also avoid tolower emallocs */

if (offset >= 0) {

if (offset > haystack_len) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");

RETURN_FALSE;

}

p = haystack + offset;

e = haystack + haystack_len - 1;

} else {

p = haystack;

if (offset < -INT_MAX || -offset > haystack_len) {

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");

RETURN_FALSE;

}

e = haystack + haystack_len + offset;

}

/* Borrow that ord_needle buffer to avoid repeatedly tolower()ing needle */

*ord_needle = tolower(*needle);

while (e >= p) {

if (tolower(*e) == *ord_needle) {

RETURN_LONG(e - p + (offset > 0 ? offset : 0));

}

e--;

}

RETURN_FALSE;

}

needle_dup = estrndup(needle, needle_len);

php_strtolower(needle_dup, needle_len);

haystack_dup = estrndup(haystack, haystack_len);

php_strtolower(haystack_dup, haystack_len);

if (offset >= 0) {

if (offset > haystack_len) {

efree(needle_dup);

efree(haystack_dup);

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");

RETURN_FALSE;

}

p = haystack_dup + offset;

e = haystack_dup + haystack_len - needle_len;

} else {

if (offset < -INT_MAX || -offset > haystack_len) {

efree(needle_dup);

efree(haystack_dup);

php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset is greater than the length of haystack string");

RETURN_FALSE;

}

p = haystack_dup;

if (needle_len > -offset) {

e = haystack_dup + haystack_len - needle_len;

} else {

e = haystack_dup + haystack_len + offset;

}

}

while (e >= p) {

if (memcmp(e, needle_dup, needle_len) == 0) {

efree(haystack_dup);

efree(needle_dup);

RETURN_LONG(e - p + (offset > 0 ? offset : 0));

}

e--;

}

efree(haystack_dup);

efree(needle_dup);

RETURN_FALSE;

}

/* }}} */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: