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