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

Reply via email to