All pastes #44988 Raw Edit

Anonymous

public c v1 · immutable
#44988 ·published 2006-03-09 02:02 UTC
rendered paste body
PHPAPI char *php_str_to_str_ex(char *haystack, int length, 	char *needle, int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity, int replace_limit, int *replace_count){	char *new_str;	int real_replace_count;	if (needle_len < length) {		char *end, *haystack_dup = NULL, *needle_dup = NULL;		char *e, *s, *p, *r;		if (needle_len == str_len) {			new_str = estrndup(haystack, length);			*_new_length = length;			if (case_sensitivity) {				end = new_str + length;				for (p = new_str; (r = php_memnstr(p, needle, needle_len, end) && replace_limit > real_replace_count); p = r + needle_len) {					memcpy(r, str, str_len);					if (replace_count) {						(*replace_count)++;					}					real_replace_count++;				}			} else {				haystack_dup = estrndup(haystack, length);				needle_dup = estrndup(needle, needle_len);				php_strtolower(haystack_dup, length);				php_strtolower(needle_dup, needle_len);				end = haystack_dup + length;				for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end) && replace_limit > real_replace_count); p = r + needle_len) {					memcpy(new_str + (r - haystack_dup), str, str_len);					if (replace_count) {						(*replace_count)++;					}					real_replace_count++;				}				efree(haystack_dup);				efree(needle_dup);			}			return new_str;		} else {			if (!case_sensitivity) {				haystack_dup = estrndup(haystack, length);				needle_dup = estrndup(needle, needle_len);				php_strtolower(haystack_dup, length);				php_strtolower(needle_dup, needle_len);			}			if (str_len < needle_len) {				new_str = emalloc(length + 1);			} else {				int count = 0;				char *o, *n, *endp;				if (case_sensitivity) {					o = haystack;					n = needle;				} else {					o = haystack_dup;					n = needle_dup;				}				endp = o + length;				while ((o = php_memnstr(o, n, needle_len, endp))) {					o += needle_len;					count++;				}				if (count == 0) {					/* Needle doesn't occur, shortcircuit the actual replacement. */					if (haystack_dup) {						efree(haystack_dup);					}					if (needle_dup) {						efree(needle_dup);					}					new_str = estrndup(haystack, length);					if (_new_length) {						*_new_length = length;					}					return new_str;				} else {					new_str = safe_emalloc(count, str_len - needle_len, length + 1);				}			}			e = s = new_str;			if (case_sensitivity) {				end = haystack + length;				for (p = haystack; (r = php_memnstr(p, needle, needle_len, end) && replace_limit > real_replace_count); p = r + needle_len) {					memcpy(e, p, r - p);					e += r - p;					memcpy(e, str, str_len);					e += str_len;					if (replace_count) {						(*replace_count)++;					}					real_replace_count++;				}				if (p < end) {					memcpy(e, p, end - p);					e += end - p;				}			} else {				end = haystack_dup + length;				for (p = haystack_dup; (r = php_memnstr(p, needle_dup, needle_len, end) && replace_limit > real_replace_count); p = r + needle_len) {					memcpy(e, haystack + (p - haystack_dup), r - p);					e += r - p;					memcpy(e, str, str_len);					e += str_len;					if (replace_count) {						(*replace_count)++;					}					real_replace_count++;				}				if (p < end) {					memcpy(e, haystack + (p - haystack_dup), end - p);					e += end - p;				}			}			if (haystack_dup) {				efree(haystack_dup);			}			if (needle_dup) {				efree(needle_dup);			}			*e = '\0';			*_new_length = e - s;			new_str = erealloc(new_str, *_new_length + 1);			return new_str;		}	} else if (needle_len > length) {nothing_todo:		*_new_length = length;		new_str = estrndup(haystack, length);		return new_str;	} else {		if (case_sensitivity ? strncmp(haystack, needle, length) : strncasecmp(haystack, needle, length)) {			goto nothing_todo;		} else {			*_new_length = str_len;			new_str = estrndup(str, str_len);			if (replace_count) {				(*replace_count)++;			}			return new_str;		}	}}/* }}} *//* {{{ php_str_to_str */PHPAPI char *php_str_to_str(char *haystack, int length, 	char *needle, int needle_len, char *str, int str_len, int *_new_length){	return php_str_to_str_ex(haystack, length, needle, needle_len, str, str_len, _new_length, 1, NULL);} /* }}} *//* {{{ php_str_replace_in_subject */static void php_str_replace_in_subject(zval *search, zval *replace, zval **subject, zval *result, int case_sensitivity, int replace_limit, int *replace_count){	zval		**search_entry,				**replace_entry = NULL,				  temp_result;	char		*replace_value = NULL;	int			 replace_len = 0;	/* Make sure we're dealing with strings. */		convert_to_string_ex(subject);	Z_TYPE_P(result) = IS_STRING;	if (Z_STRLEN_PP(subject) == 0) {		ZVAL_STRINGL(result, "", 0, 1);		return;	}		/* If search is an array */	if (Z_TYPE_P(search) == IS_ARRAY) {		/* Duplicate subject string for repeated replacement */		*result = **subject;		zval_copy_ctor(result);		INIT_PZVAL(result);				zend_hash_internal_pointer_reset(Z_ARRVAL_P(search));		if (Z_TYPE_P(replace) == IS_ARRAY) {			zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace));		} else {			/* Set replacement value to the passed one */			replace_value = Z_STRVAL_P(replace);			replace_len = Z_STRLEN_P(replace);		}		/* For each entry in the search array, get the entry */		while (zend_hash_get_current_data(Z_ARRVAL_P(search), (void **) &search_entry) == SUCCESS) {			/* Make sure we're dealing with strings. */				SEPARATE_ZVAL(search_entry);			convert_to_string(*search_entry);			if (Z_STRLEN_PP(search_entry) == 0) {				zend_hash_move_forward(Z_ARRVAL_P(search));				if (Z_TYPE_P(replace) == IS_ARRAY) {					zend_hash_move_forward(Z_ARRVAL_P(replace));				}				continue;			}			/* If replace is an array. */			if (Z_TYPE_P(replace) == IS_ARRAY) {				/* Get current entry */				if (zend_hash_get_current_data(Z_ARRVAL_P(replace), (void **)&replace_entry) == SUCCESS) {					/* Make sure we're dealing with strings. */						convert_to_string_ex(replace_entry);										/* Set replacement value to the one we got from array */					replace_value = Z_STRVAL_PP(replace_entry);					replace_len = Z_STRLEN_PP(replace_entry);					zend_hash_move_forward(Z_ARRVAL_P(replace));				} else {					/* We've run out of replacement strings, so use an empty one. */					replace_value = "";					replace_len = 0;				}			}						if (Z_STRLEN_PP(search_entry) == 1) {				php_char_to_str_ex(Z_STRVAL_P(result),								Z_STRLEN_P(result),								Z_STRVAL_PP(search_entry)[0],								replace_value,								replace_len,								&temp_result,								case_sensitivity,								replace_limit,								replace_count);			} else if (Z_STRLEN_PP(search_entry) > 1) {				Z_STRVAL(temp_result) = php_str_to_str_ex(Z_STRVAL_P(result), Z_STRLEN_P(result),														   Z_STRVAL_PP(search_entry), Z_STRLEN_PP(search_entry),														   replace_value, replace_len, &Z_STRLEN(temp_result), case_sensitivity, replace_count);			}			efree(Z_STRVAL_P(result));			Z_STRVAL_P(result) = Z_STRVAL(temp_result);			Z_STRLEN_P(result) = Z_STRLEN(temp_result);			if (Z_STRLEN_P(result) == 0) {				return;			}			zend_hash_move_forward(Z_ARRVAL_P(search));		}	} else {		if (Z_STRLEN_P(search) == 1) {			php_char_to_str_ex(Z_STRVAL_PP(subject),							Z_STRLEN_PP(subject),							Z_STRVAL_P(search)[0],							Z_STRVAL_P(replace),							Z_STRLEN_P(replace),							result,							case_sensitivity,							replace_limit,							replace_count);		} else if (Z_STRLEN_P(search) > 1) {			Z_STRVAL_P(result) = php_str_to_str_ex(Z_STRVAL_PP(subject), Z_STRLEN_PP(subject),													Z_STRVAL_P(search), Z_STRLEN_P(search),													Z_STRVAL_P(replace), Z_STRLEN_P(replace), &Z_STRLEN_P(result), case_sensitivity, replace_limit, replace_count);		} else {			*result = **subject;			zval_copy_ctor(result);			INIT_PZVAL(result);		}	}}/* }}} *//* {{{ php_str_replace_common */static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensitivity){	zval **subject, **search, **replace, **subject_entry, **replace_limit, **zcount;	zval *result;	char *string_key;	uint string_key_len;	ulong num_key;	int count = 0;	int argc = ZEND_NUM_ARGS();	convert_to_long_ex(replace_limit);	if (argc < 3 || argc > 5 ||	   zend_get_parameters_ex(argc, &search, &replace, &subject, &replace_limit, &zcount) == FAILURE) {		WRONG_PARAM_COUNT;	}	SEPARATE_ZVAL(search);	SEPARATE_ZVAL(replace);	SEPARATE_ZVAL(subject);	/* Make sure we're dealing with strings and do the replacement. */	if (Z_TYPE_PP(search) != IS_ARRAY) {		convert_to_string_ex(search);		convert_to_string_ex(replace);	} else if (Z_TYPE_PP(replace) != IS_ARRAY) {		convert_to_string_ex(replace);	}	/* if subject is an array */	if (Z_TYPE_PP(subject) == IS_ARRAY) {		array_init(return_value);		zend_hash_internal_pointer_reset(Z_ARRVAL_PP(subject));		/* For each subject entry, convert it to string, then perform replacement		   and add the result to the return_value array. */		while (zend_hash_get_current_data(Z_ARRVAL_PP(subject), (void **)&subject_entry) == SUCCESS) {			if (Z_TYPE_PP(subject_entry) != IS_ARRAY && Z_TYPE_PP(subject_entry) != IS_OBJECT) {				MAKE_STD_ZVAL(result);				SEPARATE_ZVAL(subject_entry);				php_str_replace_in_subject(*search, *replace, subject_entry, result, case_sensitivity, (argc > 3) ? replace_limit : NULL, (argc > 4) ? &count : NULL);			} else {				ALLOC_ZVAL(result);				ZVAL_ADDREF(*subject_entry);				COPY_PZVAL_TO_ZVAL(*result, *subject_entry);			}			/* Add to return array */			switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(subject), &string_key,												&string_key_len, &num_key, 0, NULL)) {				case HASH_KEY_IS_STRING:					add_assoc_zval_ex(return_value, string_key, string_key_len, result);					break;				case HASH_KEY_IS_LONG:					add_index_zval(return_value, num_key, result);					break;			}					zend_hash_move_forward(Z_ARRVAL_PP(subject));		}	} else {	/* if subject is not an array */		php_str_replace_in_subject(*search, *replace, subject, return_value, case_sensitivity, (argc > 3) ? replace_limit : NULL, (argc > 4) ? &count : NULL);	}		if (argc > 3) {		zval_dtor(*zcount);		ZVAL_LONG(*zcount, count);	}}/* }}} *//* {{{ proto mixed str_replace(mixed search, mixed replace, mixed subject [, int &replace_count])   Replaces all occurrences of search in haystack with replace */PHP_FUNCTION(str_replace){	php_str_replace_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}