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

📄 array.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}}/* }}} *//* {{{ proto array range(mixed low, mixed high)   Create an array containing the range of integers or characters from low to high (inclusive) */PHP_FUNCTION(range){	zval **zlow, **zhigh;		if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &zlow, &zhigh) == FAILURE) {		WRONG_PARAM_COUNT;	}	/* allocate an array for return */	array_init(return_value);	if (Z_TYPE_PP(zlow) == IS_STRING && Z_TYPE_PP(zhigh) == IS_STRING && Z_STRLEN_PP(zlow) == 1 && Z_STRLEN_PP(zhigh) == 1) {		unsigned char low, high;		low = *((unsigned char *)Z_STRVAL_PP(zlow));		high = *((unsigned char *)Z_STRVAL_PP(zhigh));				if (low>high) {			for (; low >= high; (low)--) {				add_next_index_stringl(return_value, (char *)&low, 1, 1);				if ((int)low == 0) {					break;				}			}			} else {			for (; low <= high; (low)++) {				add_next_index_stringl(return_value, (char *)&low, 1, 1);				if ((int)low == 255) {					break;				}			}			}	} else {		int low, high;		convert_to_long_ex(zlow);		convert_to_long_ex(zhigh);		low = Z_LVAL_PP(zlow);		high = Z_LVAL_PP(zhigh);		if (low > high) { 			for (; low >= high; low--) {				add_next_index_long(return_value, low);			}			} else {			for (; low <= high; low++) {				add_next_index_long(return_value, low);			}			}	}}/* }}} */static void array_data_shuffle(zval *array TSRMLS_DC){	Bucket **elems, *temp;	HashTable *hash;	int j, n_elems, rnd_idx, n_left;	n_elems = zend_hash_num_elements(Z_ARRVAL_P(array));		if (n_elems < 1) {		return;	}	elems = (Bucket **)safe_emalloc(sizeof(Bucket *), n_elems, 0);	hash = Z_ARRVAL_P(array);	n_left = n_elems;	for (j = 0, temp = hash->pListHead; temp; temp = temp->pListNext)		elems[j++] = temp;	while (--n_left) {		rnd_idx = php_rand(TSRMLS_C);		RAND_RANGE(rnd_idx, 0, n_left, PHP_RAND_MAX);		if (rnd_idx != n_left) {			temp = elems[n_left];			elems[n_left] = elems[rnd_idx];			elems[rnd_idx] = temp;		}	}	HANDLE_BLOCK_INTERRUPTIONS();	hash->pListHead = elems[0];	hash->pListTail = NULL;	hash->pInternalPointer = hash->pListHead;	for (j = 0; j < n_elems; j++) {		if (hash->pListTail) {			hash->pListTail->pListNext = elems[j];		}		elems[j]->pListLast = hash->pListTail;		elems[j]->pListNext = NULL;		hash->pListTail = elems[j];	}	temp = hash->pListHead;	j = 0;	while (temp != NULL) {		temp->nKeyLength = 0;		temp->h = j++;		temp = temp->pListNext;	}	hash->nNextFreeElement = n_elems;	zend_hash_rehash(hash);	HANDLE_UNBLOCK_INTERRUPTIONS();	efree(elems);}/* {{{ proto bool shuffle(array array_arg)   Randomly shuffle the contents of an array */PHP_FUNCTION(shuffle){	zval *array;	if (zend_parse_parameters(1 TSRMLS_CC, "a", &array) == FAILURE) {		RETURN_FALSE;	}	array_data_shuffle(array TSRMLS_CC);	RETURN_TRUE;}/* }}} *//* HashTable* php_splice(HashTable *in_hash, int offset, int length,						 zval ***list, int list_count, HashTable **removed) */HashTable* php_splice(HashTable *in_hash, int offset, int length,					  zval ***list, int list_count, HashTable **removed){	HashTable 	*out_hash = NULL;	/* Output hashtable */	int			 num_in,			/* Number of entries in the input hashtable */				 pos,				/* Current position in the hashtable */				 i;					/* Loop counter */	Bucket		*p;					/* Pointer to hash bucket */	zval		*entry;				/* Hash entry */		/* If input hash doesn't exist, we have nothing to do */	if (!in_hash)		return NULL;		/* Get number of entries in the input hash */	num_in = zend_hash_num_elements(in_hash);		/* Clamp the offset.. */	if (offset > num_in)		offset = num_in;	else if (offset < 0 && (offset=num_in+offset) < 0)		offset = 0;		/* ..and the length */	if (length < 0) {		length = num_in-offset+length;	} else if (((unsigned) offset + (unsigned) length) > num_in) {		length = num_in-offset;	}	/* Create and initialize output hash */	ALLOC_HASHTABLE(out_hash);	zend_hash_init(out_hash, 0, NULL, ZVAL_PTR_DTOR, 0);		/* Start at the beginning of the input hash and copy	   entries to output hash until offset is reached */	for (pos=0, p=in_hash->pListHead; pos<offset && p ; pos++, p=p->pListNext) {		/* Get entry and increase reference count */		entry = *((zval **)p->pData);		entry->refcount++;				/* Update output hash depending on key type */		if (p->nKeyLength)			zend_hash_update(out_hash, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);		else			zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);	}		/* If hash for removed entries exists, go until offset+length	   and copy the entries to it */	if (removed != NULL) {		for ( ; pos<offset+length && p; pos++, p=p->pListNext) {			entry = *((zval **)p->pData);			entry->refcount++;			if (p->nKeyLength)				zend_hash_update(*removed, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);			else				zend_hash_next_index_insert(*removed, &entry, sizeof(zval *), NULL);		}	} else /* otherwise just skip those entries */		for ( ; pos<offset+length && p; pos++, p=p->pListNext);		/* If there are entries to insert.. */	if (list != NULL) {		/* ..for each one, create a new zval, copy entry into it		   and copy it into the output hash */		for (i=0; i<list_count; i++) {			entry = *list[i];			if (entry->refcount>=1000) {				zval *tmp = (zval *) emalloc(sizeof(zval));				*tmp = *entry;				zval_copy_ctor(tmp);				tmp->refcount = 1;				tmp->is_ref = 0;				entry = tmp;			} else {				entry->refcount++;			}			zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);		}	}		/* Copy the remaining input hash entries to the output hash */	for ( ; p ; p=p->pListNext) {		entry = *((zval **)p->pData);		entry->refcount++;		if (p->nKeyLength)			zend_hash_update(out_hash, p->arKey, p->nKeyLength, &entry, sizeof(zval *), NULL);		else			zend_hash_next_index_insert(out_hash, &entry, sizeof(zval *), NULL);	}	zend_hash_internal_pointer_reset(out_hash);	return out_hash;}/* }}} *//* {{{ proto int array_push(array stack, mixed var [, mixed ...])   Pushes elements onto the end of the array */PHP_FUNCTION(array_push){	zval	  ***args,		/* Function arguments array */				*stack,		/* Input array */				*new_var;	/* Variable to be pushed */	int			 i,			/* Loop counter */				 argc;		/* Number of function arguments */	/* Get the argument count and check it */	argc = ZEND_NUM_ARGS();	if (argc < 2) {		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;	}	/* Get first argument and check that it's an array */		stack = *args[0];	if (Z_TYPE_P(stack) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "First argument should be an array");		efree(args);		RETURN_FALSE;	}	/* For each subsequent argument, make it a reference, increase refcount,	   and add it to the end of the array */	for (i=1; i<argc; i++) {		new_var = *args[i];		new_var->refcount++;			zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var, sizeof(zval *), NULL);	}		/* Clean up and return the number of values in the stack */	efree(args);	RETVAL_LONG(zend_hash_num_elements(Z_ARRVAL_P(stack)));}/* }}} *//* {{{ void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int which_end) */static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end){	zval	   **stack,			/* Input stack */			   **val;			/* Value to be popped */	char *key = NULL;	uint key_len = 0;	ulong index;		/* Get the arguments and do error-checking */	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &stack) == FAILURE) {		WRONG_PARAM_COUNT;	}		if (Z_TYPE_PP(stack) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array");		return;	}	if (zend_hash_num_elements(Z_ARRVAL_PP(stack)) == 0) {		return;	}			/* Get the first or last value and copy it into the return value */	if (off_the_end)		zend_hash_internal_pointer_end(Z_ARRVAL_PP(stack));	else		zend_hash_internal_pointer_reset(Z_ARRVAL_PP(stack));	zend_hash_get_current_data(Z_ARRVAL_PP(stack), (void **)&val);	*return_value = **val;	zval_copy_ctor(return_value);	INIT_PZVAL(return_value);		/* Delete the first or last value */	zend_hash_get_current_key_ex(Z_ARRVAL_PP(stack), &key, &key_len, &index, 0, NULL);	zend_hash_del_key_or_index(Z_ARRVAL_PP(stack), key, key_len, index, (key) ? HASH_DEL_KEY : HASH_DEL_INDEX);		/* If we did a shift... re-index like it did before */	if (!off_the_end) {		int k = 0;		Bucket *p = Z_ARRVAL_PP(stack)->pListHead;		while (p != NULL) {			if (p->nKeyLength == 0) {				p->h = k++;			}			p = p->pListNext;		}		Z_ARRVAL_PP(stack)->nNextFreeElement = k;		zend_hash_rehash(Z_ARRVAL_PP(stack));	} else if (!key_len && index >= Z_ARRVAL_PP(stack)->nNextFreeElement-1) {		Z_ARRVAL_PP(stack)->nNextFreeElement = Z_ARRVAL_PP(stack)->nNextFreeElement - 1;	}	zend_hash_internal_pointer_reset(Z_ARRVAL_PP(stack));}/* }}} *//* {{{ proto mixed array_pop(array stack)   Pops an element off the end of the array */PHP_FUNCTION(array_pop){	_phpi_pop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);}/* }}} *//* {{{ proto mixed array_shift(array stack)   Pops an element off the beginning of the array */PHP_FUNCTION(array_shift){	_phpi_pop(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);}/* }}} *//* {{{ proto int array_unshift(array stack, mixed var [, mixed ...])   Pushes elements onto the beginning of the array */PHP_FUNCTION(array_unshift){	zval	  ***args,		/* Function arguments array */				*stack;		/* Input stack */	HashTable	*new_hash;	/* New hashtable for the stack */	int			 argc;		/* Number of function arguments */		/* Get the argument count and check it */		argc = ZEND_NUM_ARGS();	if (argc < 2) {		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;	}		/* Get first argument and check that it's an array */	stack = *args[0];	if (Z_TYPE_P(stack) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array");		efree(args);		RETURN_FALSE;	}	/* Use splice to insert the elements at the beginning.  Destroy old	   hashtable and replace it with new one */	new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[1], argc-1, NULL);	zend_hash_destroy(Z_ARRVAL_P(stack));	*Z_ARRVAL_P(stack) = *new_hash;	FREE_HASHTABLE(new_hash);	/* Clean up and return the number of elements in the stack */	efree(args);	RETVAL_LONG(zend_hash_num_elements(Z_ARRVAL_P(stack)));}/* }}} *//* {{{ proto array array_splice(array input, int offset [, int length [, array replacement]])   Removes the elements designated by offset and length and replace them with supplied array */PHP_FUNCTION(array_splice){	zval	  ***args,				/* Function arguments array */				*array,				/* Input array */			  ***repl = NULL;		/* Replacement elements */	HashTable	*new_hash = NULL;	/* Output array's hash */	Bucket		*p;					/* Bucket used for traversing hash */	int			 argc,				/* Number of function arguments */				 i,				 offset,				 length,				 repl_num = 0;		/* Number of replacement elements */	/* Get the argument count and check it */	argc = ZEND_NUM_ARGS();	if (argc < 2 || argc > 4) {		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;	}		/* Get first argument and check that it's an array */	array = *args[0];	if (Z_TYPE_P(array) != IS_ARRAY) {		php_error_docref(NULL TSRMLS_CC, E_WARNING, "The first argument should be an array");		efree(args);		return;	}		/* Get the next two arguments.  If length is omitted,	   it's assumed to be until the end of the array */	convert_to_long_ex(args[1]);	offset = Z_LVAL_PP(args[1]);	if (argc > 2) {		convert_to_long_ex(args[2]);		length = Z_LVAL_PP(args[2]);	} else		length = zend_hash_num_elements(Z_ARRVAL_P(array));	if (argc == 4) {		/* Make sure the last argument, if passed, is an array */		convert_to_array_ex(args[3]);				/* Create the array of replacement elements */		repl_num = zend_hash_num_elements(Z_ARRVAL_PP(args[3]));		repl = (zval ***)safe_emalloc(sizeof(zval **), repl_num, 0);		for (p=Z_ARRVAL_PP(args[3])->pListHead, i=0; p; p=p->pListNext, i++) {			repl[i] = ((zval **)p->pData);		}	}		/* Initialize return value */	array_init(return_value);		/* Perform splice */	new_hash = php_splice(Z_ARRVAL_P(array), offset, length,							repl, repl_num,							&Z_ARRVAL_P(return_value));		/* Replace input array's hashtable with the new one */	zend_hash_destroy(Z_ARRVAL_P(array));	*Z_ARRVAL_P(array) = *new_hash;	FREE_HASHTABLE(new_hash);		/* Clean up */	if (argc == 4)		efree(repl);	efree(args);}/* }}} *//* {{{ proto array array_slice(array input, int offset [, int length])   Returns elements specified by offset and length */PHP_FUNCTION(array_slice){	zval	   **input,			/* Input array */			   **offset,		/* Offset to get elements from */

⌨️ 快捷键说明

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