iliaa Tue Mar 8 16:13:05 2005 EDT Modified files: /php-src/ext/standard html.c Log: Improve the performance of htmlspecialchars_decode() by 20-30%. http://cvs.php.net/diff.php/php-src/ext/standard/html.c?r1=1.103&r2=1.104&ty=u Index: php-src/ext/standard/html.c diff -u php-src/ext/standard/html.c:1.103 php-src/ext/standard/html.c:1.104 --- php-src/ext/standard/html.c:1.103 Mon Mar 7 14:37:26 2005 +++ php-src/ext/standard/html.c Tue Mar 8 16:13:03 2005 @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.c,v 1.103 2005/03/07 19:37:26 iliaa Exp $ */ +/* $Id: html.c,v 1.104 2005/03/08 21:13:03 iliaa Exp $ */ /* * HTML entity resources: @@ -469,6 +469,12 @@ { 0, NULL, 0, 0 } }; +struct basic_entities_dec { + unsigned short charcode; + char entity[8]; + int entitylen; +}; + #define MB_RETURN { \ *newpos = pos; \ mbseq[mbpos] = '\0'; \ @@ -1211,8 +1217,9 @@ PHP_FUNCTION(htmlspecialchars_decode) { char *str, *new_str, *e, *p; - int len, i, new_len; + int len, j, i, new_len; long quote_style = ENT_COMPAT; + struct basic_entities_dec basic_entities_dec[8]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &len, "e_style) == FAILURE) { return; @@ -1220,37 +1227,51 @@ new_str = estrndup(str, len); new_len = len; + e = new_str + new_len; + + if (!(p = memchr(new_str, '&', new_len))) { + RETURN_STRINGL(new_str, new_len, 0); + } - for (i = 0; basic_entities[i].charcode != 0; i++) { + for (j = 0, i = 0; basic_entities[i].charcode != 0; i++) { if (basic_entities[i].flags && !(quote_style & basic_entities[i].flags)) { continue; } - - e = new_str + new_len; - p = new_str; - - while ((p = php_memnstr(p, basic_entities[i].entity, basic_entities[i].entitylen, e))) { - int e_len = basic_entities[i].entitylen - 1; + basic_entities_dec[j].charcode = basic_entities[i].charcode; + memcpy(basic_entities_dec[j].entity, basic_entities[i].entity, basic_entities[i].entitylen + 1); + basic_entities_dec[j].entitylen = basic_entities[i].entitylen; + j++; + } + basic_entities_dec[j].charcode = '&'; + basic_entities_dec[j].entitylen = sizeof("&") - 1; + memcpy(basic_entities_dec[j].entity, "&", sizeof("&")); + i = j + 1; + + do { + int l = e - p; + + for (j = 0; j < i; j++) { + if (basic_entities_dec[j].entitylen > l) { + continue; + } + if (!memcmp(p, basic_entities_dec[j].entity, basic_entities_dec[j].entitylen)) { + int e_len = basic_entities_dec[j].entitylen - 1; - *p++ = basic_entities[i].charcode; - memmove(p, p + e_len, (e - p - e_len)); - - new_len -= e_len; - e -= e_len; + *p++ = basic_entities_dec[j].charcode; + memmove(p, p + e_len, (e - p - e_len)); + e -= e_len; + goto done; + } } - } - - e = new_str + new_len; - p = new_str; - while ((p = php_memnstr(p, "&", sizeof("&") - 1, e))) { - int e_len = sizeof("&") - 2; - p++; - memmove(p, p + e_len, (e - p - e_len)); - new_len -= e_len; - e -= e_len; - } +done: + if (p >= e) { + break; + } + } while ((p = memchr(p, '&', (e - p)))); + + new_len = e - new_str; new_str[new_len] = '\0'; RETURN_STRINGL(new_str, new_len, 0);
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php