Index: ext/spl/spl_array.c =================================================================== RCS file: /repository/php-src/ext/spl/spl_array.c,v retrieving revision 1.71.2.17.2.13.2.14 diff -u -p -r1.71.2.17.2.13.2.14 spl_array.c --- ext/spl/spl_array.c 6 May 2008 23:08:06 -0000 1.71.2.17.2.13.2.14 +++ ext/spl/spl_array.c 6 Jul 2008 22:07:53 -0000 @@ -65,10 +65,11 @@ typedef struct _spl_array_object { HashPosition pos; int ar_flags; int is_self; - zend_function * fptr_offset_get; - zend_function * fptr_offset_set; - zend_function * fptr_offset_has; - zend_function * fptr_offset_del; + zend_function *fptr_offset_get; + zend_function *fptr_offset_set; + zend_function *fptr_offset_has; + zend_function *fptr_offset_del; + zend_function *fptr_count; zend_class_entry* ce_get_iterator; } spl_array_object; @@ -201,6 +202,10 @@ static zend_object_value spl_array_objec if (intern->fptr_offset_del->common.scope == parent) { intern->fptr_offset_del = NULL; } + zend_hash_find(&class_type->function_table, "count", sizeof("count"), (void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } } /* Cache iterator functions if ArrayIterator or derived. Check current's */ /* cache since only current is always required */ @@ -1171,9 +1176,8 @@ SPL_METHOD(Array, seek) zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "Seek position %ld is out of range", opos); } /* }}} */ -int spl_array_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ +int inline spl_array_object_count_elements_helper(spl_array_object *intern, long *count TSRMLS_DC) /* {{{ */ { - spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC); HashPosition pos; @@ -1200,14 +1204,37 @@ int spl_array_object_count_elements(zval } } /* }}} */ +int spl_array_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */ +{ + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); + + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv); + if (rv) { + zval_ptr_dtor(&intern->retval); + MAKE_STD_ZVAL(intern->retval); + ZVAL_ZVAL(intern->retval, rv, 1, 1); + convert_to_long(intern->retval); + *count = (long) Z_LVAL_P(intern->retval); + return SUCCESS; + } + *count = 0; + return FAILURE; + } + return spl_array_object_count_elements_helper(intern, count TSRMLS_CC); +} /* }}} */ + /* {{{ proto int ArrayObject::count() proto int ArrayIterator::count() Return the number of elements in the Iterator. */ SPL_METHOD(Array, count) { long count; + spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + spl_array_object_count_elements_helper(intern, &count TSRMLS_CC); - spl_array_object_count_elements(getThis(), &count TSRMLS_CC); RETURN_LONG(count); } /* }}} */ @@ -1226,9 +1253,9 @@ static void spl_array_method(INTERNAL_FU zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0 TSRMLS_CC); return; } - zend_call_method(NULL, NULL, NULL, fname, fname_len, &return_value, 2, &tmp, arg TSRMLS_CC); + zend_call_method(NULL, NULL, NULL, fname, fname_len, return_value_ptr, 2, &tmp, arg TSRMLS_CC); } else { - zend_call_method(NULL, NULL, NULL, fname, fname_len, &return_value, 1, &tmp, NULL TSRMLS_CC); + zend_call_method(NULL, NULL, NULL, fname, fname_len, return_value_ptr, 1, &tmp, NULL TSRMLS_CC); } } /* }}} */ Index: ext/spl/spl_dllist.c =================================================================== RCS file: /repository/php-src/ext/spl/spl_dllist.c,v retrieving revision 1.1.2.12 diff -u -p -r1.1.2.12 spl_dllist.c --- ext/spl/spl_dllist.c 6 Jun 2008 23:53:43 -0000 1.1.2.12 +++ ext/spl/spl_dllist.c 6 Jul 2008 22:07:54 -0000 @@ -92,6 +92,7 @@ struct _spl_dllist_object { zend_function *fptr_offset_set; zend_function *fptr_offset_has; zend_function *fptr_offset_del; + zend_function *fptr_count; zend_class_entry *ce_get_iterator; }; @@ -434,6 +435,10 @@ static zend_object_value spl_dllist_obje if (intern->fptr_offset_del->common.scope == parent) { intern->fptr_offset_del = NULL; } + zend_hash_find(&class_type->function_table, "count", sizeof("count"), (void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } } return retval; @@ -469,8 +474,22 @@ static int spl_dllist_object_count_eleme { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(object TSRMLS_CC); - *count = spl_ptr_llist_count(intern->llist); + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv); + if (rv) { + zval_ptr_dtor(&intern->retval); + MAKE_STD_ZVAL(intern->retval); + ZVAL_ZVAL(intern->retval, rv, 1, 1); + convert_to_long(intern->retval); + *count = (long) Z_LVAL_P(intern->retval); + return SUCCESS; + } + *count = 0; + return FAILURE; + } + *count = spl_ptr_llist_count(intern->llist); return SUCCESS; } /* }}} */ @@ -657,12 +676,13 @@ SPL_METHOD(SplDoublyLinkedList, bottom) SPL_METHOD(SplDoublyLinkedList, count) { long count; + spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { return; } - spl_dllist_object_count_elements(getThis(), &count TSRMLS_CC); + count = spl_ptr_llist_count(intern->llist); RETURN_LONG(count); } /* }}} */ Index: ext/spl/spl_fixedarray.c =================================================================== RCS file: /repository/php-src/ext/spl/spl_fixedarray.c,v retrieving revision 1.1.2.2 diff -u -p -r1.1.2.2 spl_fixedarray.c --- ext/spl/spl_fixedarray.c 18 Jun 2008 14:54:39 -0000 1.1.2.2 +++ ext/spl/spl_fixedarray.c 6 Jul 2008 22:07:54 -0000 @@ -61,6 +61,7 @@ typedef struct _spl_fixedarray_object { zend_function *fptr_it_current; zend_function *fptr_it_key; zend_function *fptr_it_valid; + zend_function *fptr_count; int current; zend_class_entry *ce_get_iterator; } spl_fixedarray_object; @@ -292,6 +293,10 @@ static zend_object_value spl_fixedarray_ if (intern->fptr_it_valid->common.scope == parent) { intern->fptr_it_valid = NULL; } + zend_hash_find(&class_type->function_table, "count", sizeof("count"), (void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } } return retval; @@ -512,12 +517,23 @@ static int spl_fixedarray_object_count_e spl_fixedarray_object *intern; intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC); - if (intern->array) { + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv); + if (rv) { + zval_ptr_dtor(&intern->retval); + MAKE_STD_ZVAL(intern->retval); + ZVAL_ZVAL(intern->retval, rv, 1, 1); + convert_to_long(intern->retval); + *count = (long) Z_LVAL_P(intern->retval); + return SUCCESS; + } + } else if (intern->array) { *count = intern->array->size; - } else { - *count = 0; + return SUCCESS; } + *count = 0; return SUCCESS; } /* }}} */ @@ -945,7 +961,6 @@ PHP_MINIT_FUNCTION(spl_fixedarray) memcpy(&spl_handler_SplFixedArray, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); spl_handler_SplFixedArray.clone_obj = spl_fixedarray_object_clone; - spl_handler_SplFixedArray.count_elements = spl_fixedarray_object_count_elements; spl_handler_SplFixedArray.read_dimension = spl_fixedarray_object_read_dimension; spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension; spl_handler_SplFixedArray.unset_dimension = spl_fixedarray_object_unset_dimension; Index: ext/spl/spl_heap.c =================================================================== RCS file: /repository/php-src/ext/spl/spl_heap.c,v retrieving revision 1.1.2.5 diff -u -p -r1.1.2.5 spl_heap.c --- ext/spl/spl_heap.c 24 May 2008 14:38:04 -0000 1.1.2.5 +++ ext/spl/spl_heap.c 6 Jul 2008 22:07:54 -0000 @@ -75,6 +75,7 @@ struct _spl_heap_object { int flags; zend_class_entry *ce_get_iterator; zend_function *fptr_cmp; + zend_function *fptr_count; }; /* define an overloaded iterator structure */ @@ -441,10 +442,13 @@ static zend_object_value spl_heap_object if (inherited) { zend_hash_find(&class_type->function_table, "compare", sizeof("compare"), (void **) &intern->fptr_cmp); - if (intern->fptr_cmp->common.scope == parent) { intern->fptr_cmp = NULL; } + zend_hash_find(&class_type->function_table, "count", sizeof("count"), (void **) &intern->fptr_count); + if (intern->fptr_count->common.scope == parent) { + intern->fptr_count = NULL; + } } return retval; @@ -480,6 +484,21 @@ static int spl_heap_object_count_element { spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(object TSRMLS_CC); + if (intern->fptr_count) { + zval *rv; + zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv); + if (rv) { + zval_ptr_dtor(&intern->retval); + MAKE_STD_ZVAL(intern->retval); + ZVAL_ZVAL(intern->retval, rv, 1, 1); + convert_to_long(intern->retval); + *count = (long) Z_LVAL_P(intern->retval); + return SUCCESS; + } + *count = 0; + return FAILURE; + } + *count = spl_ptr_heap_count(intern->heap); return SUCCESS; @@ -545,12 +564,13 @@ static HashTable* spl_pqueue_object_get_ SPL_METHOD(SplHeap, count) { long count; + spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { return; } - spl_heap_object_count_elements(getThis(), &count TSRMLS_CC); + count = spl_ptr_heap_count(intern->heap); RETURN_LONG(count); } /* }}} */ @@ -559,14 +579,13 @@ SPL_METHOD(SplHeap, count) Return true if the heap is empty. */ SPL_METHOD(SplHeap, isEmpty) { - long count; + spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) { return; } - spl_heap_object_count_elements(getThis(), &count TSRMLS_CC); - RETURN_BOOL(count==0); + RETURN_BOOL(spl_ptr_heap_count(intern->heap)==0); } /* }}} */ Index: ext/spl/tests/array_024.phpt =================================================================== RCS file: ext/spl/tests/array_024.phpt diff -N ext/spl/tests/array_024.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ext/spl/tests/array_024.phpt 6 Jul 2008 22:07:54 -0000 @@ -0,0 +1,17 @@ +--TEST-- +SPL: ArrayObject with overriden count() +--FILE-- + +--EXPECT-- +int(2) +int(-2) Index: ext/spl/tests/dllist_008.phpt =================================================================== RCS file: ext/spl/tests/dllist_008.phpt diff -N ext/spl/tests/dllist_008.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ext/spl/tests/dllist_008.phpt 6 Jul 2008 22:07:54 -0000 @@ -0,0 +1,21 @@ +--TEST-- +SPL: SplDoublyLinkedList with overriden count() +--FILE-- + +--EXPECT-- +int(2) +int(-2) Index: ext/spl/tests/fixedarray_018.phpt =================================================================== RCS file: ext/spl/tests/fixedarray_018.phpt diff -N ext/spl/tests/fixedarray_018.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ext/spl/tests/fixedarray_018.phpt 6 Jul 2008 22:07:54 -0000 @@ -0,0 +1,17 @@ +--TEST-- +SPL: SplFixedArray with overriden count() +--FILE-- + +--EXPECT-- +int(2) +int(-2) Index: ext/spl/tests/heap_010.phpt =================================================================== RCS file: ext/spl/tests/heap_010.phpt diff -N ext/spl/tests/heap_010.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ ext/spl/tests/heap_010.phpt 6 Jul 2008 22:07:54 -0000 @@ -0,0 +1,21 @@ +--TEST-- +SPL: SplHeap with overriden count() +--FILE-- +insert(1); +$obj->insert(2); +var_dump(count($obj)); +class SplMaxHeap2 extends SplMaxHeap{ + public function count() { + return -parent::count(); + } +} +$obj = new SplMaxHeap2(); +$obj->insert(1); +$obj->insert(2); +var_dump(count($obj)); +?> +--EXPECT-- +int(2) +int(-2) Index: ext/spl/tests/sxe_004.phpt =================================================================== RCS file: /repository/php-src/ext/spl/tests/sxe_004.phpt,v retrieving revision 1.2.2.2.4.2 diff -u -p -r1.2.2.2.4.2 sxe_004.phpt --- ext/spl/tests/sxe_004.phpt 24 May 2008 14:10:44 -0000 1.2.2.2.4.2 +++ ext/spl/tests/sxe_004.phpt 6 Jul 2008 22:07:54 -0000 @@ -1,5 +1,5 @@ --TEST-- -SPL: SimpleXMLIterator and getChildren() +SPL: SimpleXMLIterator and overridden iterator methods() --SKIPIF--