[php-i18n-commits] cvs commit: php4/ext/mbstring mbfunction.c

Back to archive index

Moriyoshi Koizumi moriy****@users*****
2002年 10月 7日 (月) 06:59:22 JST


moriyoshi    02/10/07 06:59:22

  Modified:    ext/mbstring mbfunction.c
  Log:
  added binary safe version of strtok_r / strrchr
  
  Revision  Changes    Path
  1.13      +158 -34   php4/ext/mbstring/mbfunction.c
  
  Index: mbfunction.c
  ===================================================================
  RCS file: /cvsroot/php-i18n/php4/ext/mbstring/mbfunction.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- mbfunction.c	6 Oct 2002 16:08:31 -0000	1.12
  +++ mbfunction.c	6 Oct 2002 21:59:22 -0000	1.13
  @@ -3144,7 +3144,7 @@
   
   /* {{{ PHPAPI php_mbstr_mbchar_bytes_ex(const char *s, const php_mb_enc *enc) */
   
  -PHPAPI int php_mb_mbchar_bytes_ex(const char *s, const php_mb_enc *enc)
  +PHPAPI size_t php_mb_mbchar_bytes_ex(const char *s, const php_mb_enc *enc)
   {
   	if ( enc != NULL ) {
   		if( enc->type & PHP_MB_ENCTYPE_MBCS ) {
  @@ -3161,57 +3161,181 @@
   }
   /* }}} */
   
  -/* {{{ php_mb_strtok_r_ex(char*, char*, char**, php_mb_enc *enc) */
  -PHPAPI char *php_mb_strtok_r_ex(char *s1, const char *s2, char **last, php_mb_enc *enc)
  +/* {{{ php_mb_safe_strtok_r_ex(char*, char*, char**, size_t nbytes, php_mb_enc *enc) */
  +PHPAPI char *php_mb_safe_strtok_r_ex(char *s1, size_t nbytes_s1, const char *s2, size_t nbytes_s2, php_mb_strtok_t *tok_d, php_mb_enc *enc)
   {
  -	register char *p1;
  -	register const char *p2;
  +	char *p1;
  +
   	char *retval = NULL;
  -	int nbytes;
  +	size_t nbytes_char;
   
  -	if( s2 == NULL || last == NULL ) return NULL;
  +	if( s2 == NULL || tok_d == NULL ) return NULL;
  +
  +	if ( s1 != NULL ) {
  +		p1 = s1;
  +	} else {
  +		if ( ( p1 = tok_d->last ) == NULL ) {
  +			return NULL;
  +		}
  +		nbytes_s1 = tok_d->nbytes_left;
  +	}
   
  -	p1 = ( s1 ? s1 : *last );
   	if( p1 == NULL ) return NULL;
   
   	retval = NULL;
  -	*last = NULL;
  -	while (*p1 != '\0') {
  -		nbytes = php_mb_mbchar_bytes_ex( p1, enc );
  -		if (nbytes == 1) {
  -			for (p2 = s2; *p2 != '\0' && *p1 == *p2; p2++);
  +	tok_d->last = NULL;
  +	tok_d->nbytes_left = 0;
   
  -			if (*p1 != *p2) {
  +	if ( nbytes_s1 == (size_t)-1 ) {
  +		while (*p1 != '\0') {
  +			register const char *p2;
  +			register size_t bcnt_s2;
  +
  +			nbytes_char = php_mb_mbchar_bytes_ex( p1, enc );
  +			if (nbytes_char == 1) {
  +				if (nbytes_s2 == (size_t)-1) {
  +					for (p2=s2; *p2!='\0' && *p1==*p2; p2++);
  +				} else {
  +					for (p2=s2, bcnt_s2=nbytes_s2; bcnt_s2>0 && *p1==*p2; p2++,bcnt_s2--);
  +				}
  +				if (*p1 != *p2) {
  +					retval = p1;
  +					break;
  +				} 
  +			} else {
   				retval = p1;
   				break;
  +			}
  +			while (nbytes_char-- > 0) {
  +				if( *(++p1) == '\0' ) goto out;
   			} 
  -		} else {
  -			retval = p1;
  -			break;
  -		}
  -		while (--nbytes >= 0) {
  -			if( *(++p1) == '\0' ) goto out;
  -		} 
  -	}
  +		}
   
  -	while (*p1 != '\0') {
  -		nbytes = php_mb_mbchar_bytes_ex( p1, enc );
  -		if (nbytes == 1) {
  -			for (p2 = s2; *p2 != '\0'; p2++) {
  -				if (*p1 == *p2) {
  -					*p1 = '\0';
  -					*last = p1 + 1;
  -					goto out;
  +		while (*p1 != '\0') {
  +			register const char *p2;
  +			register size_t bcnt_s2;
  +
  +			nbytes_char = php_mb_mbchar_bytes_ex( p1, enc );
  +			if (nbytes_char == 1) {
  +				if (nbytes_s2 == (size_t)-1) {
  +					for (p2=s2; *p2!='\0'; p2++) {
  +						if (*p1 == *p2) {
  +							*p1 = '\0';
  +							tok_d->last = p1 + 1;
  +							goto out;
  +						}
  +					}
  +				} else {
  +					for (bcnt_s2=nbytes_s2,p2=s2; bcnt_s2>0; p2++,bcnt_s2--) {
  +						if (*p1 == *p2) {
  +							*p1 = '\0';
  +							tok_d->last = p1 + 1;
  +							goto out;
  +						}
  +					}
   				}
   			}
  +			while (nbytes_char-- >= 0) {
  +				if( *(++p1) == '\0' ) goto out;
  +			} 
  +		}
  +	} else {
  +		size_t bcnt_s1 = nbytes_s1;
  +
  +		while (bcnt_s1 > 0) {
  +			register const char *p2;
  +			register size_t bcnt_s2;
  +
  +			nbytes_char = php_mb_mbchar_bytes_ex( p1, enc );
  +			if (nbytes_char == 1) {
  +				if (nbytes_s2 == (size_t)-1) {
  +					for (p2=s2; *p2!='\0' && *p1==*p2; p2++);
  +				} else {
  +					for (p2=s2, bcnt_s2=nbytes_s2; bcnt_s2>0 && *p1==*p2; p2++,bcnt_s2--);
  +				}
  +				if (*p1 != *p2) {
  +					retval = p1;
  +					break;
  +				} 
  +			} else {
  +				retval = p1;
  +				break;
  +			}
  +			if ( nbytes_char < bcnt_s1 ) {
  +				return NULL;
  +			}
  +			bcnt_s1 -= nbytes_char;
  +			if ( bcnt_s1 == 0 ) goto out;
   		}
  -		while (--nbytes >= 0) {
  -			if( *(++p1) == '\0' ) goto out;
  -		} 
  -	}
   
  +		while (bcnt_s1 > 0) {
  +			register const char *p2;
  +			register size_t bcnt_s2;
  +
  +			nbytes_char = php_mb_mbchar_bytes_ex( p1, enc );
  +			if (nbytes_char == 1) {
  +				if (nbytes_s2 == (size_t)-1) {
  +					for (p2=s2; *p2!='\0'; p2++) {
  +						if (*p1 == *p2) {
  +							*p1 = '\0';
  +							tok_d->last = p1 + 1;
  +							tok_d->nbytes_left = bcnt_s1;
  +							goto out;
  +						}
  +					}
  +				} else {
  +					for (bcnt_s2=nbytes_s2,p2=s2; bcnt_s2>0; p2++,bcnt_s2--) {
  +						if (*p1 == *p2) {
  +							*p1 = '\0';
  +							tok_d->last = p1 + 1;
  +							tok_d->nbytes_left = bcnt_s1;
  +							goto out;
  +						}
  +					}
  +				}
  +			}
  +			if ( nbytes_char < bcnt_s1 ) {
  +				return NULL;
  +			}
  +			bcnt_s1 -= nbytes_char;
  +			if ( bcnt_s1 == 0 ) goto out;
  +		}
  +	}
   out:
   	return retval;
  +}
  +/* }}} */
  +
  +/* {{{ php_mb_safe_strrchr_ex(const char *s, char c, php_mb_enc *enc)
  + */
  +PHPAPI char *php_mb_safe_strrchr_ex(const char *s, unsigned int c, size_t nbytes, php_mb_enc *enc)
  +{
  +	register const char *p = s;
  +	char *last;
  +
  +	if (nbytes == (size_t)-1) {
  +		while ( *p != '\0') {
  +			if (*p == c) {
  +				last = (char *)p;
  +			}
  +			p += php_mb_mbchar_bytes_ex( p, enc );
  +		}
  +	} else {
  +		register size_t bcnt = nbytes;
  +		register size_t nbytes_char;
  +		while ( bcnt > 0 ) {
  +			if (*p == c) {
  +				last = (char *)p;
  +			}
  +			nbytes_char = php_mb_mbchar_bytes_ex( p, enc );
  +			if ( bcnt < nbytes_char ) {
  +				return NULL;
  +			}
  +			p += nbytes_char;
  +			bcnt -= nbytes_char;
  +		}
  +	}
  +	return last;
   }
   /* }}} */
   
  
  
  



php-i18n-commits メーリングリストの案内
Back to archive index