helly Thu Mar 3 05:45:43 2005 EDT Added files: (Branch: PHP_5_0) /php-src/ext/spl/tests bug32134.phpt
Modified files: /php-src/ext/spl spl_array.c spl_array.h /php-src/ext/spl/tests array_014.phpt Log: - MFH fix #32134 - Fix tests
http://cvs.php.net/diff.php/php-src/ext/spl/spl_array.c?r1=1.49.2.3&r2=1.49.2.4&ty=u Index: php-src/ext/spl/spl_array.c diff -u php-src/ext/spl/spl_array.c:1.49.2.3 php-src/ext/spl/spl_array.c:1.49.2.4 --- php-src/ext/spl/spl_array.c:1.49.2.3 Tue Mar 1 05:09:05 2005 +++ php-src/ext/spl/spl_array.c Thu Mar 3 05:45:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.c,v 1.49.2.3 2005/03/01 10:09:05 helly Exp $ */ +/* $Id: spl_array.c,v 1.49.2.4 2005/03/03 10:45:42 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -111,16 +111,20 @@ zend_object_handlers spl_handler_ArrayObject; -zend_class_entry * spl_ce_ArrayObject; +PHPAPI zend_class_entry *spl_ce_ArrayObject; zend_object_handlers spl_handler_ArrayIterator; -zend_class_entry * spl_ce_ArrayIterator; +PHPAPI zend_class_entry *spl_ce_ArrayIterator; typedef struct _spl_array_object { zend_object std; zval *array; HashPosition pos; int is_ref; + zend_function * fptr_offset_get; + zend_function * fptr_offset_set; + zend_function * fptr_offset_has; + zend_function * fptr_offset_del; } spl_array_object; /* {{{ spl_array_object_free_storage */ @@ -143,6 +147,8 @@ zend_object_value retval; spl_array_object *intern; zval *tmp; + zend_class_entry * parent = class_type; + int inherited = 0; intern = emalloc(sizeof(spl_array_object)); memset(intern, 0, sizeof(spl_array_object)); @@ -165,10 +171,37 @@ zend_hash_internal_pointer_reset_ex(HASH_OF(intern->array), &intern->pos); retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) spl_array_object_free_storage, NULL TSRMLS_CC); - if (class_type == spl_ce_ArrayIterator) { - retval.handlers = &spl_handler_ArrayIterator; - } else { - retval.handlers = &spl_handler_ArrayObject; + while (parent) { + if (parent == spl_ce_ArrayIterator) { + retval.handlers = &spl_handler_ArrayIterator; + break; + } else if (parent == spl_ce_ArrayObject) { + retval.handlers = &spl_handler_ArrayObject; + break; + } + parent = parent->parent; + inherited = 1; + } + if (!parent) { /* this must never happen */ + php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of ArrayObject or arrayIterator"); + } + if (inherited) { + zend_hash_find(&class_type->function_table, "offsetget", sizeof("offsetget"), (void **) &intern->fptr_offset_get); + if (intern->fptr_offset_get->common.scope == parent) { + intern->fptr_offset_get = NULL; + } + zend_hash_find(&class_type->function_table, "offsetset", sizeof("offsetset"), (void **) &intern->fptr_offset_set); + if (intern->fptr_offset_set->common.scope == parent) { + intern->fptr_offset_set = NULL; + } + zend_hash_find(&class_type->function_table, "offsetexists", sizeof("offsetexists"), (void **) &intern->fptr_offset_has); + if (intern->fptr_offset_has->common.scope == parent) { + intern->fptr_offset_has = NULL; + } + zend_hash_find(&class_type->function_table, "offsetunset", sizeof("offsetunset"), (void **) &intern->fptr_offset_del); + if (intern->fptr_offset_del->common.scope == parent) { + intern->fptr_offset_del = NULL; + } } return retval; } @@ -201,13 +234,16 @@ } /* }}} */ -/* {{{ spl_array_read_dimension */ -static zval *spl_array_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) +static zval *spl_array_read_dimension_ex(int check_inherited, zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - zval **retval; + zval **retval, *rv; long index; + if (check_inherited && intern->fptr_offset_get) { + return zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset); + } + switch(Z_TYPE_P(offset)) { case IS_STRING: if (zend_symtable_find(HASH_OF(intern->array), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **) &retval) == FAILURE) { @@ -236,14 +272,23 @@ zend_error(E_WARNING, "Illegal offset type"); return EG(uninitialized_zval_ptr); } -} -/* }}} */ +} /* }}} */ -/* {{{ spl_array_write_dimension */ -static void spl_array_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) +static zval *spl_array_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */ +{ + return spl_array_read_dimension_ex(1, object, offset, type TSRMLS_CC); +} /* }}} */ + +static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); long index; + zval *rv; + + if (check_inherited && intern->fptr_offset_set) { + zend_call_method_with_2_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_set, "offsetSet", &rv, offset, value); + return; + } if (!offset) { value->refcount++; @@ -271,20 +316,35 @@ zend_error(E_WARNING, "Illegal offset type"); return; } -} -/* }}} */ +} /* }}} */ + +static void spl_array_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */ +{ + return spl_array_write_dimension_ex(1, object, offset, value TSRMLS_CC); +} /* }}} */ -/* {{{ spl_array_unset_dimension */ -static void spl_array_unset_dimension(zval *object, zval *offset TSRMLS_DC) +static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval *offset TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); long index; + zval *rv; + + if (check_inherited && intern->fptr_offset_del) { + zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_del, "offsetUnset", &rv, offset); + return; + } switch(Z_TYPE_P(offset)) { case IS_STRING: + + + + + if (zend_symtable_del(HASH_OF(intern->array), Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1) == FAILURE) { zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset)); } + return; case IS_DOUBLE: case IS_RESOURCE: @@ -303,14 +363,28 @@ zend_error(E_WARNING, "Illegal offset type"); return; } -} -/* }}} */ +} /* }}} */ -/* {{{ spl_array_has_dimension */ -static int spl_array_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) +static void spl_array_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */ +{ + return spl_array_unset_dimension_ex(1, object, offset TSRMLS_CC); +} /* }}} */ + +static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); long index; + zval *rv; + + if (check_inherited && intern->fptr_offset_has) { + zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_has, "offsetExists", &rv, offset); + if (zend_is_true(rv)) { + zval_ptr_dtor(&rv); + return 1; + } + zval_ptr_dtor(&rv); + return 0; + } switch(Z_TYPE_P(offset)) { case IS_STRING: @@ -329,8 +403,12 @@ zend_error(E_WARNING, "Illegal offset type"); } return 0; -} -/* }}} */ +} /* }}} */ + +static int spl_array_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */ +{ + return spl_array_has_dimension_ex(1, object, offset, check_empty TSRMLS_CC); +} /* }}} */ /* {{{ proto bool ArrayObject::offsetExists(mixed $index) proto bool ArrayIterator::offsetExists(mixed $index) @@ -341,7 +419,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == FAILURE) { return; } - RETURN_BOOL(spl_array_has_dimension(getThis(), index, 1 TSRMLS_CC)); + RETURN_BOOL(spl_array_has_dimension_ex(0, getThis(), index, 1 TSRMLS_CC)); } /* }}} */ /* {{{ proto bool ArrayObject::offsetGet(mixed $index) @@ -353,7 +431,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == FAILURE) { return; } - value = spl_array_read_dimension(getThis(), index, BP_VAR_R TSRMLS_CC); + value = spl_array_read_dimension_ex(0, getThis(), index, BP_VAR_R TSRMLS_CC); RETURN_ZVAL(value, 1, 0); } /* }}} */ @@ -366,7 +444,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &index, &value) == FAILURE) { return; } - spl_array_write_dimension(getThis(), index, value TSRMLS_CC); + spl_array_write_dimension_ex(0, getThis(), index, value TSRMLS_CC); } /* }}} */ @@ -412,7 +490,7 @@ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &index) == FAILURE) { return; } - spl_array_unset_dimension(getThis(), index TSRMLS_CC); + spl_array_unset_dimension_ex(0, getThis(), index TSRMLS_CC); } /* }}} */ /* {{ proto array ArrayObject::getArrayCopy() http://cvs.php.net/diff.php/php-src/ext/spl/spl_array.h?r1=1.9&r2=1.9.2.1&ty=u Index: php-src/ext/spl/spl_array.h diff -u php-src/ext/spl/spl_array.h:1.9 php-src/ext/spl/spl_array.h:1.9.2.1 --- php-src/ext/spl/spl_array.h:1.9 Tue Jan 20 15:59:45 2004 +++ php-src/ext/spl/spl_array.h Thu Mar 3 05:45:42 2005 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.h,v 1.9 2004/01/20 20:59:45 helly Exp $ */ +/* $Id: spl_array.h,v 1.9.2.1 2005/03/03 10:45:42 helly Exp $ */ #ifndef SPL_ARRAY_H #define SPL_ARRAY_H @@ -24,8 +24,8 @@ #include "php.h" #include "php_spl.h" -extern zend_class_entry *spl_ce_ArrayObject; -extern zend_class_entry *spl_ce_ArrayIterator; +extern PHPAPI zend_class_entry *spl_ce_ArrayObject; +extern PHPAPI zend_class_entry *spl_ce_ArrayIterator; PHP_MINIT_FUNCTION(spl_array); http://cvs.php.net/diff.php/php-src/ext/spl/tests/array_014.phpt?r1=1.1.2.2&r2=1.1.2.3&ty=u Index: php-src/ext/spl/tests/array_014.phpt diff -u php-src/ext/spl/tests/array_014.phpt:1.1.2.2 php-src/ext/spl/tests/array_014.phpt:1.1.2.3 --- php-src/ext/spl/tests/array_014.phpt:1.1.2.2 Wed Sep 29 16:16:03 2004 +++ php-src/ext/spl/tests/array_014.phpt Thu Mar 3 05:45:42 2005 @@ -13,8 +13,15 @@ var_dump($it->current()); $it->seek(-1); var_dump($it->current()); -$it->seek(12); -var_dump($it->current()); +try +{ + $it->seek(12); + var_dump($it->current()); +} +catch(Exception $e) +{ + echo $e->getMessage() . "\n"; +} $pos = 0; foreach($it as $v) @@ -31,7 +38,7 @@ int(5) int(4) int(0) -NULL +Seek position 12 is out of range int(0) int(1) int(2) http://cvs.php.net/co.php/php-src/ext/spl/tests/bug32134.phpt?r=1.1&p=1 Index: php-src/ext/spl/tests/bug32134.phpt +++ php-src/ext/spl/tests/bug32134.phpt --TEST-- Bug #32134 (Overloading offsetGet/offsetSet) --FILE-- <?php class myArray extends ArrayIterator { public function __construct($array = array()) { parent::__construct($array); } public function offsetGet($index) { static $i = 0; echo __METHOD__ . "($index)\n"; if (++$i > 3) exit(1); return parent::offsetGet($index); } public function offsetSet($index, $newval) { echo __METHOD__ . "($index,$newval)\n"; return parent::offsetSet($index, $newval); } } $myArray = new myArray(); $myArray->offsetSet('one', 'one'); var_dump($myArray->offsetGet('one')); $myArray['two'] = 'two'; var_dump($myArray['two']); ?> ===DONE=== <?php exit(0); ?> --EXPECT-- myArray::offsetSet(one,one) myArray::offsetGet(one) string(3) "one" myArray::offsetSet(two,two) myArray::offsetGet(two) string(3) "two" ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php