All pastes #1091668 Raw Edit

rewbs

public diff v1 · immutable
#1091668 ·published 2008-08-03 10:03 UTC
rendered paste body
Index: spl_array.c===================================================================RCS file: /repository/php-src/ext/spl/spl_array.c,vretrieving revision 1.71.2.17.2.13.2.19diff -u -w -p -r1.71.2.17.2.13.2.19 spl_array.c--- spl_array.c	26 Jul 2008 12:34:10 -0000	1.71.2.17.2.13.2.19+++ spl_array.c	3 Aug 2008 09:59:32 -0000@@ -924,50 +924,16 @@ zend_object_iterator *spl_array_get_iter } /* }}} */ -/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])-       proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0])- Cronstructs a new array iterator from a path. */-SPL_METHOD(Array, __construct)-{-	zval *object = getThis();-	spl_array_object *intern;-	zval **array;-	long ar_flags = 0;-	char *class_name;-	int class_name_len;-	zend_class_entry ** pce_get_iterator;--	if (ZEND_NUM_ARGS() == 0) {-		return; /* nothing to do */-	}-	php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC);--	intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);--	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {-		php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);-		return;-	}+/* {{{ spl_array_set_array */+static void spl_array_set_array(zval *object, spl_array_object *intern, zval **array, long ar_flags, int just_array TSRMLS_DC) {  	if (Z_TYPE_PP(array) == IS_ARRAY) { 		SEPARATE_ZVAL_IF_NOT_REF(array); 	} -	if (ZEND_NUM_ARGS() > 2) {-		if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {-			zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);-			php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);-			return;-		}-		intern->ce_get_iterator = *pce_get_iterator;-	}--	ar_flags &= ~SPL_ARRAY_INT_MASK;- 	if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) { 		zval_ptr_dtor(&intern->array);-		if (ZEND_NUM_ARGS() == 1)-		{+		if (just_array)	{ 			spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC); 			ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK; 		}		@@ -996,9 +962,50 @@ SPL_METHOD(Array, __construct) 		|| !spl_array_get_hash_table(intern, 0 TSRMLS_CC)) { 			php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); 			zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "Overloaded object of type %s is not compatible with %s", Z_OBJCE_PP(array)->name, intern->std.ce->name);+		}+	}++	spl_array_rewind(intern TSRMLS_CC);+}+/* }}} */++/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])+       proto void ArrayIterator::__construct(array|object ar = array() [, int flags = 0])+ Cronstructs a new array iterator from a path. */+SPL_METHOD(Array, __construct)+{+	zval *object = getThis();+	spl_array_object *intern;+	zval **array;+	long ar_flags = 0;+	char *class_name;+	int class_name_len;+	zend_class_entry ** pce_get_iterator;++	if (ZEND_NUM_ARGS() == 0) {+		return; /* nothing to do */+	}+	php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC);++	intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);++	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ls", &array, &ar_flags, &class_name, &class_name_len) == FAILURE) {+		php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); 			return; 		}++	if (ZEND_NUM_ARGS() > 2) {+		if (zend_lookup_class(class_name, class_name_len, &pce_get_iterator TSRMLS_CC) == FAILURE) {+			zend_throw_exception(spl_ce_InvalidArgumentException, "A class that implements Iterator must be specified", 0 TSRMLS_CC);+			php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);+			return; 	}+		intern->ce_get_iterator = *pce_get_iterator;+	}++	ar_flags &= ~SPL_ARRAY_INT_MASK;++	spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1 TSRMLS_CC);  	spl_array_rewind(intern TSRMLS_CC); @@ -1081,31 +1088,9 @@ SPL_METHOD(Array, exchangeArray) 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) { 		return; 	}-	if (Z_TYPE_PP(array) == IS_OBJECT && intern == (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC)) {-		zval_ptr_dtor(&intern->array);-		array = &object;-		intern->array = object;-	} else if (Z_TYPE_PP(array) == IS_OBJECT && (Z_OBJ_HT_PP(array) == &spl_handler_ArrayObject || Z_OBJ_HT_PP(array) == &spl_handler_ArrayIterator)) {-		spl_array_object *other  = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);-		zval_ptr_dtor(&intern->array);-		intern->array = other->array;-	} else {-		if (Z_TYPE_PP(array) != IS_OBJECT && !HASH_OF(*array)) {-			zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);-			return;-		}-		zval_ptr_dtor(&intern->array);-		intern->array = *array;-		intern->ar_flags &= ~SPL_ARRAY_USE_OTHER;-	}-	if (object == *array) {-		intern->ar_flags |= SPL_ARRAY_IS_SELF;-	} else {-		intern->ar_flags &= ~SPL_ARRAY_IS_SELF;-	}-	Z_ADDREF_P(intern->array); -	spl_array_rewind(intern TSRMLS_CC);+	spl_array_set_array(object, intern, array, 0L, 1 TSRMLS_CC);+ } /* }}} */ Index: tests/arrayObject_exchange_basic1.phpt===================================================================RCS file: tests/arrayObject_exchange_basic1.phptdiff -N tests/arrayObject_exchange_basic1.phpt--- /dev/null	1 Jan 1970 00:00:00 -0000+++ tests/arrayObject_exchange_basic1.phpt	3 Aug 2008 09:44:39 -0000@@ -0,0 +1,40 @@+--TEST--+ArrayObject::exchange() and copy-on-write references+--FILE--+<?php+$ao = new ArrayObject();+$swapIn = array();+$cowRef = $swapIn; // create a copy-on-write ref to $swapIn+$ao->exchangeArray($swapIn);++$ao['a'] = 'adding element to $ao';+$swapIn['b'] = 'adding element to $swapIn';+$ao['c'] = 'adding another element to $ao';++echo "\n--> swapIn:  ";+var_dump($swapIn);++echo "\n--> cowRef:  ";+var_dump($cowRef);++echo "\n--> ao:  ";+var_dump($ao);+?>+--EXPECTF--+--> swapIn:  array(1) {+  ["b"]=>+  string(25) "adding element to $swapIn"+}++--> cowRef:  array(0) {+}++--> ao:  object(ArrayObject)#%d (1) {+  ["storage":"ArrayObject":private]=>+  array(2) {+    ["a"]=>+    string(21) "adding element to $ao"+    ["c"]=>+    string(29) "adding another element to $ao"+  }+}Index: tests/arrayObject_exchange_basic2.phpt===================================================================RCS file: tests/arrayObject_exchange_basic2.phptdiff -N tests/arrayObject_exchange_basic2.phpt--- /dev/null	1 Jan 1970 00:00:00 -0000+++ tests/arrayObject_exchange_basic2.phpt	3 Aug 2008 09:48:20 -0000@@ -0,0 +1,33 @@+--TEST--+ArrayObject::exchangeArray(object)+--FILE--+<?php+echo "--> exchangeArray(array):\n";+$ao = new ArrayObject();+$ao->exchangeArray(array('original'));+var_dump($ao);++echo "\n--> exchangeArray(object):\n";+$obj = new stdClass;+$obj->newProp = 'changed';+$ao->exchangeArray($obj);+var_dump($ao);+?>+--EXPECTF--+--> exchangeArray(array):+object(ArrayObject)#%d (1) {+  ["storage":"ArrayObject":private]=>+  array(1) {+    [0]=>+    string(8) "original"+  }+}++--> exchangeArray(object):+object(ArrayObject)#%d (1) {+  ["storage":"ArrayObject":private]=>+  object(stdClass)#%d (1) {+    ["newProp"]=>+    string(7) "changed"+  }+}\ No newline at end of file