Advertising
Paste Description for rewbs
Patch to make ArrayObject::exchangeArray use the same logic as ArrayObject::__construct
- rewbs
- Sunday, August 3rd, 2008 at 4:03:49am MDT
- Index: spl_array.c
- ===================================================================
- RCS file: /repository/php-src/ext/spl/spl_array.c,v
- retrieving revision 1.71.2.17.2.13.2.19
- diff -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.phpt
- diff -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.phpt
- diff -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
Paste Details
Tags: php arrayobject exchangearray
advertising
Update the Post
Either update this post and resubmit it with changes, or make a new post.
You may also comment on this post.
Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.