⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 array.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			   **length,		/* How many elements to get */			   **entry;			/* An array entry */	int			 offset_val,	/* Value of the offset argument */				 length_val,	/* Value of the length argument */				 num_in,		/* Number of elements in the input array */				 pos,			/* Current position in the array */				 argc;			/* Number of function arguments */				 	char		*string_key;	uint		 string_key_len;	ulong		 num_key;	HashPosition hpos;		/* Get the arguments and do error-checking */		argc = ZEND_NUM_ARGS();	if (argc < 2 || argc > 3 || zend_get_parameters_ex(argc, &input, &offset, &length)) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array");		return;	}		/* Make sure offset and length are integers and assume	   we want all entries from offset to the end if length	   is not passed */	convert_to_long_ex(offset);	offset_val = Z_LVAL_PP(offset);	if (argc == 3) {		convert_to_long_ex(length);		length_val = Z_LVAL_PP(length);	} else {		length_val = zend_hash_num_elements(Z_ARRVAL_PP(input));	}		/* Initialize returned array */	array_init(return_value);		/* Get number of entries in the input hash */	num_in = zend_hash_num_elements(Z_ARRVAL_PP(input));		/* Clamp the offset.. */	if (offset_val > num_in)		return;	else if (offset_val < 0 && (offset_val=num_in+offset_val) < 0)		offset_val = 0;		/* ..and the length */	if (length_val < 0) {		length_val = num_in-offset_val+length_val;	} else if (((unsigned) offset_val + (unsigned)length_val) > num_in) {		length_val = num_in-offset_val;	}		if (length_val == 0)		return;		/* Start at the beginning and go until we hit offset */	pos = 0;	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &hpos);	while (pos < offset_val &&		  zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) == SUCCESS) {		pos++;		zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);	}		/* Copy elements from input array to the one that's returned */	while (pos < offset_val+length_val &&		  zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &hpos) == SUCCESS) {				(*entry)->refcount++;		switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &hpos)) {			case HASH_KEY_IS_STRING:				zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len,								 entry, sizeof(zval *), NULL);				break;				case HASH_KEY_IS_LONG:				zend_hash_next_index_insert(Z_ARRVAL_P(return_value),											entry, sizeof(zval *), NULL);				break;		}		pos++;		zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &hpos);	}}/* }}} */PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC){	zval	  **src_entry,			  **dest_entry;	char	   *string_key;	uint		string_key_len;	ulong		num_key;	HashPosition pos;	zend_hash_internal_pointer_reset_ex(src, &pos);	while (zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS) {		switch (zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos)) {			case HASH_KEY_IS_STRING:				if (recursive &&					zend_hash_find(dest, string_key, string_key_len,								   (void **)&dest_entry) == SUCCESS) {					if (*src_entry == *dest_entry && ((*dest_entry)->refcount % 2)) {						zend_error(E_WARNING, "%s(): recursion detected",								   get_active_function_name(TSRMLS_C));						return 0;					}					SEPARATE_ZVAL(dest_entry);					SEPARATE_ZVAL(src_entry);										convert_to_array_ex(dest_entry);					convert_to_array_ex(src_entry);					if (!php_array_merge(Z_ARRVAL_PP(dest_entry),									Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC))						return 0;				} else {					(*src_entry)->refcount++;					zend_hash_update(dest, string_key, strlen(string_key)+1,									 src_entry, sizeof(zval *), NULL);				}				break;			case HASH_KEY_IS_LONG:				(*src_entry)->refcount++;				zend_hash_next_index_insert(dest, src_entry, sizeof(zval *), NULL);				break;		}		zend_hash_move_forward_ex(src, &pos);	}	return 1;}static void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive){	zval	  ***args = NULL;	int			 argc,				 i;	/* Get the argument count and check it */		argc = ZEND_NUM_ARGS();	if (argc < 1) {		WRONG_PARAM_COUNT;	}		/* Allocate arguments array and get the arguments, checking for errors. */	args = (zval ***)safe_emalloc(sizeof(zval **), argc, 0);	if (zend_get_parameters_array_ex(argc, args) == FAILURE) {		efree(args);		WRONG_PARAM_COUNT;	}		array_init(return_value);		for (i=0; i<argc; i++) {		SEPARATE_ZVAL(args[i]);		convert_to_array_ex(args[i]);		php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive TSRMLS_CC);	}		efree(args);}/* {{{ proto array array_merge(array arr1, array arr2 [, array ...])   Merges elements from passed arrays into one array */PHP_FUNCTION(array_merge){	php_array_merge_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto array array_merge_recursive(array arr1, array arr2 [, array ...])   Recursively merges elements from passed arrays into one array */PHP_FUNCTION(array_merge_recursive){	php_array_merge_wrapper(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto array array_keys(array input [, mixed search_value])   Return just the keys from the input array, optionally only for the specified search_value */PHP_FUNCTION(array_keys){	zval	   **input,			/* Input array */			   **search_value,	/* Value to search for */			   **entry,			/* An entry in the input array */				 res,			/* Result of comparison */				*new_val;		/* New value */	int			 add_key;		/* Flag to indicate whether a key should be added */	char		*string_key;	/* String key */	uint		 string_key_len;	ulong		 num_key;		/* Numeric key */	HashPosition pos;	search_value = NULL;		/* Get arguments and do error-checking */	if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 ||		zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &search_value) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array");		return;	}		/* Initialize return array */	array_init(return_value);	add_key = 1;		/* Go through input array and add keys to the return array */	zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);	while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) {		if (search_value != NULL) {	 		is_equal_function(&res, *search_value, *entry TSRMLS_CC);			add_key = zval_is_true(&res);		}			if (add_key) {				MAKE_STD_ZVAL(new_val);			switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 1, &pos)) {				case HASH_KEY_IS_STRING:					Z_TYPE_P(new_val) = IS_STRING;					Z_STRVAL_P(new_val) = string_key;					Z_STRLEN_P(new_val) = string_key_len-1;					zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val,												sizeof(zval *), NULL);					break;				case HASH_KEY_IS_LONG:					Z_TYPE_P(new_val) = IS_LONG;					Z_LVAL_P(new_val) = num_key;					zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val,												sizeof(zval *), NULL);					break;			}		}		zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);	}}/* }}} *//* {{{ proto array array_values(array input)   Return just the values from the input array */PHP_FUNCTION(array_values){	zval	   **input,		/* Input array */			   **entry;		/* An entry in the input array */	HashPosition pos;		/* Get arguments and do error-checking */	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &input) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");		return;	}		/* Initialize return array */	array_init(return_value);	/* Go through input array and add values to the return array */		zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos);	while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) {				(*entry)->refcount++;		zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry,											sizeof(zval *), NULL);		zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos);	}}/* }}} *//* {{{ proto array array_count_values(array input)   Return the value as key and the frequency of that value in input as value */PHP_FUNCTION(array_count_values){	zval	   **input,		/* Input array */			   **entry;		/* An entry in the input array */	zval	   **tmp;	HashTable   *myht;	HashPosition pos;		/* Get arguments and do error-checking */	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &input) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");		return;	}		/* Initialize return array */	array_init(return_value);	/* Go through input array and add values to the return array */		myht = Z_ARRVAL_PP(input);	zend_hash_internal_pointer_reset_ex(myht, &pos);	while (zend_hash_get_current_data_ex(myht, (void **)&entry, &pos) == SUCCESS) {		if (Z_TYPE_PP(entry) == IS_LONG) {			if (zend_hash_index_find(Z_ARRVAL_P(return_value), 									 Z_LVAL_PP(entry), 									 (void**)&tmp) == FAILURE) {				zval *data;				MAKE_STD_ZVAL(data);				Z_TYPE_P(data) = IS_LONG;				Z_LVAL_P(data) = 1;				zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);			} else {				Z_LVAL_PP(tmp)++;			}		} else if (Z_TYPE_PP(entry) == IS_STRING) {			if (zend_hash_find(Z_ARRVAL_P(return_value), 							   Z_STRVAL_PP(entry), 							   Z_STRLEN_PP(entry)+1, 							   (void**)&tmp) == FAILURE) {				zval *data;				MAKE_STD_ZVAL(data);				Z_TYPE_P(data) = IS_LONG;				Z_LVAL_P(data) = 1;				zend_hash_update(Z_ARRVAL_P(return_value), Z_STRVAL_PP(entry), Z_STRLEN_PP(entry) + 1, &data, sizeof(data), NULL);			} else {				Z_LVAL_PP(tmp)++;			}		} else {			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!");		}		zend_hash_move_forward_ex(myht, &pos);	}}/* }}} *//* {{{ proto array array_reverse(array input [, bool preserve keys])   Return input as a new array with the order of the entries reversed */PHP_FUNCTION(array_reverse){	zval	   **input,			  /* Input array */			   **z_preserve_keys, /* Flag: whether to preserve keys */			   **entry;			  /* An entry in the input array */	char		*string_key;	uint		 string_key_len;	ulong		 num_key;	zend_bool	 preserve_keys = 0;	HashPosition pos;		/* Get arguments and do error-checking */	if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 ||		zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &z_preserve_keys) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");		return;	}	if (ZEND_NUM_ARGS() > 1) {		convert_to_boolean_ex(z_preserve_keys);		preserve_keys = Z_BVAL_PP(z_preserve_keys);	}		/* Initialize return array */	array_init(return_value);		zend_hash_internal_pointer_end_ex(Z_ARRVAL_PP(input), &pos);	while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS) {		(*entry)->refcount++;				switch (zend_hash_get_current_key_ex(Z_ARRVAL_PP(input), &string_key, &string_key_len, &num_key, 0, &pos)) {			case HASH_KEY_IS_STRING:				zend_hash_update(Z_ARRVAL_P(return_value), string_key, string_key_len,								 entry, sizeof(zval *), NULL);				break;			case HASH_KEY_IS_LONG:				if (preserve_keys)					zend_hash_index_update(Z_ARRVAL_P(return_value), num_key,										   entry, sizeof(zval *), NULL);				else					zend_hash_next_index_insert(Z_ARRVAL_P(return_value),												entry, sizeof(zval *), NULL);				break;		}				zend_hash_move_backwards_ex(Z_ARRVAL_PP(input), &pos);	}}/* }}} *//* {{{ proto array array_pad(array input, int pad_size, mixed pad_value)   Returns a copy of input array padded with pad_value to size pad_size */PHP_FUNCTION(array_pad){	zval		**input;		/* Input array */	zval		**pad_size;		/* Size to pad to */	zval		**pad_value;	/* Padding value obviously */	zval	   ***pads;			/* Array to pass to splice */	HashTable	 *new_hash;		/* Return value from splice */	int			  input_size;	/* Size of the input array */	int			  pad_size_abs; /* Absolute value of pad_size */	int			  num_pads;		/* How many pads do we need */	int			  do_pad;		/* Whether we should do padding at all */	int			  i;		/* Get arguments and do error-checking */	if (ZEND_NUM_ARGS() != 3 || zend_get_parameters_ex(3, &input, &pad_size, &pad_value) == FAILURE) {		WRONG_PARAM_COUNT;	}		/* Make sure arguments are of the proper type */	if (Z_TYPE_PP(input) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");		return;	}	convert_to_long_ex(pad_size);		/* Do some initial calculations */	input_size = zend_hash_num_elements(Z_ARRVAL_PP(input));	pad_size_abs = abs(Z_LVAL_PP(pad_size));	do_pad = (input_size >= pad_size_abs) ? 0 : 1;		/* Copy the original array */	*return_value = **input;	zval_copy_ctor(return_value);		/* If no need to pad, no need to continue */	if (!do_pad)		return;		/* Populate the pads array */	num_pads = pad_size_abs - input_size;	if(num_pads > 1048576) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "You may only pad up to 1048576 elements at a time");		RETURN_FALSE;	}	pads = (zval ***)safe_emalloc(sizeof(zval **), num_pads, 0);	for (i = 0; i < num_pads; i++)		pads[i] = pad_value;		/* Pad on the right or on the left */	if (Z_LVAL_PP(pad_size) > 0)		new_hash = php_splice(Z_ARRVAL_P(return_value), input_size, 0, pads, num_pads, NULL);	else		new_hash = php_splice(Z_ARRVAL_P(return_value), 0, 0, pads, num_pads, NULL);		/* Copy the result hash into return value */	zend_hash_destroy(Z_ARRVAL_P(return_value));	*Z_ARRVAL_P(return_value) = *new_hash;	FREE_HASHTABLE(new_hash);		/* Clean up */	efree(pads);}/* }}} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -