helly Sun Mar 5 17:39:49 2006 UTC Added files: (Branch: PHP_5_1) /php-src/ext/spl/tests array_019.phpt iterator_030.phpt iterator_031.phpt iterator_032.phpt iterator_033.phpt iterator_034.phpt sxe_005.phpt
Modified files: /php-src/ext/spl spl.php spl_array.c spl_directory.c spl_engine.c spl_engine.h spl_iterators.c spl_iterators.h spl_sxe.c Log: - Fix issues with not/double calling of constructors of SPL iterators - Fix issues with info-class/file-class in SPL directory handling classes - Add SimpleXMLElement::count() - Drop erroneous RecursiveDirectoryIterator::getSubPathInfo() - Drop dead code - Add tests - Update docu
http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl.php?r1=1.49.2.10&r2=1.49.2.11&diff_format=u Index: php-src/ext/spl/spl.php diff -u php-src/ext/spl/spl.php:1.49.2.10 php-src/ext/spl/spl.php:1.49.2.11 --- php-src/ext/spl/spl.php:1.49.2.10 Mon Feb 20 22:21:54 2006 +++ php-src/ext/spl/spl.php Sun Mar 5 17:39:49 2006 @@ -887,8 +887,8 @@ */ function setFileClass(string class_name = "SplFileObject"); - /** @param class_name name of class used with getFileInfo(), getPathInfo(), - * getSubPathInfo(). Must be derived from SplFileInfo. + /** @param class_name name of class used with getFileInfo(), getPathInfo(). + * Must be derived from SplFileInfo. */ function setInfoClass(string class_name = "SplFileInfo"); } @@ -971,13 +971,6 @@ /** @return the current sub path */ function getSubPathname(); - - /** @return SplFileInfo created for the current sub path - * @param class_name name of class to instantiate - * @see SplFileInfo::setInfoClass() - */ - function getSubPathInfo(string $class_name = NULL); - } /** @ingroup SPL http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_array.c?r1=1.71.2.9&r2=1.71.2.10&diff_format=u Index: php-src/ext/spl/spl_array.c diff -u php-src/ext/spl/spl_array.c:1.71.2.9 php-src/ext/spl/spl_array.c:1.71.2.10 --- php-src/ext/spl/spl_array.c:1.71.2.9 Sun Feb 12 16:44:36 2006 +++ php-src/ext/spl/spl_array.c Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.c,v 1.71.2.9 2006/02/12 16:44:36 helly Exp $ */ +/* $Id: spl_array.c,v 1.71.2.10 2006/03/05 17:39:49 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -472,6 +472,7 @@ if (Z_TYPE_P(intern->array) == IS_OBJECT) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot append properties to objects, use %s::offsetSet() instead", Z_OBJCE_P(object)->name); + return; } spl_array_write_dimension(object, NULL, append_value TSRMLS_CC); @@ -701,7 +702,6 @@ { spl_array_it *iterator = (spl_array_it *)iter; spl_array_object *object = iterator->object; - HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC); if (!aht) { @@ -909,8 +909,8 @@ { zval *object = getThis(), *tmp, **array; spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); - - array_init(return_value); + + array_init(return_value); zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*)); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) { @@ -1195,7 +1195,7 @@ if (zend_hash_get_current_data_ex(aht, (void **) &entry, &intern->pos) == FAILURE) { return; } - + if (Z_TYPE_PP(entry) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(entry), Z_OBJCE_P(getThis()) TSRMLS_CC)) { RETURN_ZVAL(*entry, 0, 0); } @@ -1303,6 +1303,7 @@ REGISTER_SPL_IMPLEMENTS(ArrayObject, Aggregate); REGISTER_SPL_IMPLEMENTS(ArrayObject, ArrayAccess); memcpy(&spl_handler_ArrayObject, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + spl_handler_ArrayObject.clone_obj = spl_array_object_clone; spl_handler_ArrayObject.read_dimension = spl_array_read_dimension; spl_handler_ArrayObject.write_dimension = spl_array_write_dimension; http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_directory.c?r1=1.45.2.21&r2=1.45.2.22&diff_format=u Index: php-src/ext/spl/spl_directory.c diff -u php-src/ext/spl/spl_directory.c:1.45.2.21 php-src/ext/spl/spl_directory.c:1.45.2.22 --- php-src/ext/spl/spl_directory.c:1.45.2.21 Tue Feb 28 01:33:32 2006 +++ php-src/ext/spl/spl_directory.c Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.c,v 1.45.2.21 2006/02/28 01:33:32 helly Exp $ */ +/* $Id: spl_directory.c,v 1.45.2.22 2006/03/05 17:39:49 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -748,26 +748,30 @@ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = spl_ce_SplFileObject; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == FAILURE) { - return; + php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { + intern->file_class = ce; } - intern->file_class = ce; + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } /* }}} */ /* {{{ proto SplFileObject SplFileInfo::setInfoClass([string class_name]) - Class to use in getFileInfo(), getPathInfo(), getSubPathInfo() */ + Class to use in getFileInfo(), getPathInfo() */ SPL_METHOD(SplFileInfo, setInfoClass) { spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = spl_ce_SplFileInfo; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == FAILURE) { - return; + php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { + intern->info_class = ce; } - intern->info_class = ce; + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } /* }}} */ @@ -778,11 +782,13 @@ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = intern->info_class; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == FAILURE) { - return; + php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { + spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC); } - spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC); + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } /* }}} */ @@ -793,11 +799,13 @@ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_class_entry *ce = intern->info_class; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == FAILURE) { - return; + php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) { + spl_filesystem_object_create_info(intern, intern->path, intern->path_len, 1, ce, return_value TSRMLS_CC); } - spl_filesystem_object_create_info(intern, intern->path, intern->path_len, 1, ce, return_value TSRMLS_CC); + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } /* }}} */ @@ -810,7 +818,7 @@ int len; long flags = SPL_FILE_DIR_CURRENT_AS_FILEINFO; - php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC); + php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &len, &flags) == FAILURE) { php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); @@ -950,28 +958,6 @@ } /* }}} */ -/* {{{ proto SplFileInfo RecursiveDirectoryIterator::getSubPathInfo([string $class_info]) - Create SplFileInfo for sub path */ -SPL_METHOD(RecursiveDirectoryIterator, getSubPathInfo) -{ - spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - char *sub_name; - int len; - zend_class_entry *ce = intern->info_class; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == FAILURE) { - return; - } - - if (intern->u.dir.sub_path) { - len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, DEFAULT_SLASH, intern->u.dir.entry.d_name); - spl_filesystem_object_create_info(intern, sub_name, len, 0, ce, return_value TSRMLS_CC); - } else { - spl_filesystem_object_create_info(intern, intern->path, intern->path_len, 1, ce, return_value TSRMLS_CC); - } -} -/* }}} */ - /* define an overloaded iterator structure */ typedef struct { zend_object_iterator intern; @@ -1329,7 +1315,6 @@ SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, getSubPath, NULL, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, getSubPathname,NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, getSubPathInfo,arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_engine.c?r1=1.20.2.1&r2=1.20.2.2&diff_format=u Index: php-src/ext/spl/spl_engine.c diff -u php-src/ext/spl/spl_engine.c:1.20.2.1 php-src/ext/spl/spl_engine.c:1.20.2.2 --- php-src/ext/spl/spl_engine.c:1.20.2.1 Sun Jan 1 12:50:13 2006 +++ php-src/ext/spl/spl_engine.c Sun Mar 5 17:39:49 2006 @@ -43,20 +43,6 @@ } /* }}} */ -/* {{{ spl_is_instance_of */ -int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC) -{ - /* Ensure everything needed is available before checking for the type. - */ - zend_class_entry *instance_ce; - - if (obj && (instance_ce = spl_get_class_entry(*obj TSRMLS_CC)) != NULL) { - return instanceof_function(instance_ce, ce TSRMLS_CC); - } - return 0; -} -/* }}} */ - /* * Local variables: * tab-width: 4 http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_engine.h?r1=1.19.2.1&r2=1.19.2.2&diff_format=u Index: php-src/ext/spl/spl_engine.h diff -u php-src/ext/spl/spl_engine.h:1.19.2.1 php-src/ext/spl/spl_engine.h:1.19.2.2 --- php-src/ext/spl/spl_engine.h:1.19.2.1 Sun Jan 1 12:50:13 2006 +++ php-src/ext/spl/spl_engine.h Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_engine.h,v 1.19.2.1 2006/01/01 12:50:13 sniper Exp $ */ +/* $Id: spl_engine.h,v 1.19.2.2 2006/03/05 17:39:49 helly Exp $ */ #ifndef SPL_ENGINE_H #define SPL_ENGINE_H @@ -58,8 +58,6 @@ } /* }}} */ -int spl_is_instance_of(zval **obj, zend_class_entry *ce TSRMLS_DC); - #endif /* SPL_ENGINE_H */ /* http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_iterators.c?r1=1.73.2.22&r2=1.73.2.23&diff_format=u Index: php-src/ext/spl/spl_iterators.c diff -u php-src/ext/spl/spl_iterators.c:1.73.2.22 php-src/ext/spl/spl_iterators.c:1.73.2.23 --- php-src/ext/spl/spl_iterators.c:1.73.2.22 Mon Feb 6 11:28:41 2006 +++ php-src/ext/spl/spl_iterators.c Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.c,v 1.73.2.22 2006/02/06 11:28:41 tony2001 Exp $ */ +/* $Id: spl_iterators.c,v 1.73.2.23 2006/03/05 17:39:49 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -815,18 +815,32 @@ } #endif +#define SPL_CHECK_CTOR(intern, classname) \ + if (intern->dit_type == DIT_Unknown) { \ + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Classes derived from %v must call %v::__construct()", \ + (spl_ce_##classname)->name, (spl_ce_##classname)->name); \ + return; \ + } + +#define APPENDIT_CHECK_CTOR(intern) SPL_CHECK_CTOR(intern, AppendIterator) + static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more TSRMLS_DC); -static inline spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_inner, dual_it_type dit_type) +static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_class_entry *ce_base, zend_class_entry *ce_inner, dual_it_type dit_type) { zval *zobject, *retval; spl_dual_it_object *intern; zend_class_entry *ce = NULL; int inc_refcount = 1; - php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC); - intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (intern->dit_type != DIT_Unknown) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v::getIterator() must be called exactly once per instance", ce_base->name); + return NULL; + } + + php_set_error_handling(EH_THROW, spl_ce_InvalidArgumentException TSRMLS_CC); intern->dit_type = dit_type; switch (dit_type) { @@ -931,9 +945,9 @@ /* {{{ proto FilterIterator::__construct(Iterator it) Create an Iterator from another iterator */ -SPL_METHOD(dual_it, __construct) +SPL_METHOD(FilterIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_Default); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_FilterIterator, zend_ce_iterator, DIT_FilterIterator); } /* }}} */ /* {{{ proto Iterator FilterIterator::getInnerIterator() @@ -1173,7 +1187,7 @@ Create a RecursiveFilterIterator from a RecursiveIterator */ SPL_METHOD(RecursiveFilterIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveIterator, DIT_Default); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveFilterIterator, spl_ce_RecursiveIterator, DIT_RecursiveFilterIterator); } /* }}} */ /* {{{ proto boolean RecursiveFilterIterator::hasChildren() @@ -1199,7 +1213,7 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - spl_instantiate_arg_ex1(spl_ce_RecursiveFilterIterator, &return_value, 0, retval TSRMLS_CC); + spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); zval_ptr_dtor(&retval); } /* }}} */ @@ -1207,7 +1221,7 @@ Create a ParentIterator from a RecursiveIterator */ SPL_METHOD(ParentIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveIterator, DIT_Default); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_ParentIterator, spl_ce_RecursiveIterator, DIT_ParentIterator); } /* }}} */ /* {{{ proto boolean ParentIterator::hasChildren() @@ -1233,7 +1247,7 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - spl_instantiate_arg_ex1(spl_ce_ParentIterator, &return_value, 0, retval TSRMLS_CC); + spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); zval_ptr_dtor(&retval); } /* }}} */ @@ -1274,6 +1288,7 @@ intern = emalloc(sizeof(spl_dual_it_object)); memset(intern, 0, sizeof(spl_dual_it_object)); intern->std.ce = class_type; + intern->dit_type = DIT_Unknown; ALLOC_HASHTABLE(intern->std.properties); zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); @@ -1291,7 +1306,7 @@ ZEND_END_ARG_INFO(); static zend_function_entry spl_funcs_FilterIterator[] = { - SPL_ME(dual_it, __construct, arginfo_filter_it___construct, ZEND_ACC_PUBLIC) + SPL_ME(FilterIterator, __construct, arginfo_filter_it___construct, ZEND_ACC_PUBLIC) SPL_ME(FilterIterator, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(dual_it, valid, NULL, ZEND_ACC_PUBLIC) SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) @@ -1343,7 +1358,7 @@ zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "Cannot seek to %ld which is below the offset %ld", pos, intern->u.limit.offset); return; } - if (pos > intern->u.limit.offset + intern->u.limit.count && intern->u.limit.count != -1) { + if (pos >= intern->u.limit.offset + intern->u.limit.count && intern->u.limit.count != -1) { zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "Cannot seek to %ld which is behind offest %ld plus count %ld", pos, intern->u.limit.offset, intern->u.limit.count); return; } @@ -1376,7 +1391,7 @@ Construct a LimitIterator from an Iterator with a given starting offset and optionally a maximum count */ SPL_METHOD(LimitIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_LimitIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_LimitIterator, zend_ce_iterator, DIT_LimitIterator); } /* }}} */ /* {{{ proto void LimitIterator::rewind() @@ -1568,7 +1583,7 @@ Construct a CachingIterator from an Iterator */ SPL_METHOD(CachingIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_CachingIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_CachingIterator, zend_ce_iterator, DIT_CachingIterator); } /* }}} */ /* {{{ proto void CachingIterator::rewind() @@ -1669,7 +1684,7 @@ Create an iterator from a RecursiveIterator */ SPL_METHOD(RecursiveCachingIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveIterator, DIT_RecursiveCachingIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveCachingIterator, spl_ce_RecursiveIterator, DIT_RecursiveCachingIterator); } /* }}} */ /* {{{ proto bolean RecursiveCachingIterator::hasChildren() @@ -1715,7 +1730,7 @@ Create an iterator from anything that is traversable */ SPL_METHOD(IteratorIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_traversable, DIT_IteratorIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_IteratorIterator, zend_ce_traversable, DIT_IteratorIterator); } /* }}} */ static @@ -1738,7 +1753,7 @@ Create an iterator from another iterator */ SPL_METHOD(NoRewindIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_NoRewindIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_NoRewindIterator, zend_ce_iterator, DIT_NoRewindIterator); } /* }}} */ /* {{{ proto void NoRewindIterator::rewind() @@ -1822,7 +1837,7 @@ Create an iterator from another iterator */ SPL_METHOD(InfiniteIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_InfiniteIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_InfiniteIterator, zend_ce_iterator, DIT_InfiniteIterator); } /* }}} */ /* {{{ proto InfiniteIterator::next() @@ -1916,7 +1931,6 @@ intern->inner.object = zend_object_store_get_object(*it TSRMLS_CC); intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, *it TSRMLS_CC); spl_dual_it_rewind(intern TSRMLS_CC); - intern->u.append.iterator->funcs->move_forward(intern->u.append.iterator TSRMLS_CC); return SUCCESS; } else { return FAILURE; @@ -1926,6 +1940,7 @@ void spl_append_it_fetch(spl_dual_it_object *intern TSRMLS_DC) /* {{{*/ { while (spl_dual_it_valid(intern TSRMLS_CC) != SUCCESS) { + intern->u.append.iterator->funcs->move_forward(intern->u.append.iterator TSRMLS_CC); if (spl_append_it_next_iterator(intern TSRMLS_CC) != SUCCESS) { return; } @@ -1945,7 +1960,7 @@ Create an AppendIterator */ SPL_METHOD(AppendIterator, __construct) { - spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, zend_ce_iterator, DIT_AppendIterator); + spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_AppendIterator, zend_ce_iterator, DIT_AppendIterator); } /* }}} */ /* {{{ proto void AppendIterator::append(Iterator it) @@ -1956,8 +1971,10 @@ zval *it; intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + APPENDIT_CHECK_CTOR(intern); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &it, zend_ce_iterator) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &it, zend_ce_iterator) == FAILURE) { return; } spl_array_iterator_append(intern->u.append.zarrayit, it TSRMLS_CC); @@ -2071,7 +2088,7 @@ } /* }}} */ -/* {{{ int iterator_count(Travesable it) +/* {{{ int iterator_count(Traversable it) Count the elements in an iterator */ PHP_FUNCTION(iterator_count) { http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_iterators.h?r1=1.18.2.6&r2=1.18.2.7&diff_format=u Index: php-src/ext/spl/spl_iterators.h diff -u php-src/ext/spl/spl_iterators.h:1.18.2.6 php-src/ext/spl/spl_iterators.h:1.18.2.7 --- php-src/ext/spl/spl_iterators.h:1.18.2.6 Sun Jan 1 12:50:14 2006 +++ php-src/ext/spl/spl_iterators.h Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.h,v 1.18.2.6 2006/01/01 12:50:14 sniper Exp $ */ +/* $Id: spl_iterators.h,v 1.18.2.7 2006/03/05 17:39:49 helly Exp $ */ #ifndef SPL_ITERATORS_H #define SPL_ITERATORS_H @@ -53,6 +53,9 @@ typedef enum { DIT_Default = 0, + DIT_FilterIterator = DIT_Default, + DIT_RecursiveFilterIterator = DIT_Default, + DIT_ParentIterator = DIT_Default, DIT_LimitIterator, DIT_CachingIterator, DIT_RecursiveCachingIterator, @@ -60,6 +63,7 @@ DIT_NoRewindIterator, DIT_InfiniteIterator, DIT_AppendIterator, + DIT_Unknown = ~0 } dual_it_type; enum { http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_sxe.c?r1=1.8.2.3&r2=1.8.2.4&diff_format=u Index: php-src/ext/spl/spl_sxe.c diff -u php-src/ext/spl/spl_sxe.c:1.8.2.3 php-src/ext/spl/spl_sxe.c:1.8.2.4 --- php-src/ext/spl/spl_sxe.c:1.8.2.3 Sun Jan 1 12:50:14 2006 +++ php-src/ext/spl/spl_sxe.c Sun Mar 5 17:39:49 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_sxe.c,v 1.8.2.3 2006/01/01 12:50:14 sniper Exp $ */ +/* $Id: spl_sxe.c,v 1.8.2.4 2006/03/05 17:39:49 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -32,6 +32,7 @@ #include "spl_engine.h" #include "spl_iterators.h" #include "spl_sxe.h" +#include "spl_array.h" zend_class_entry *spl_ce_SimpleXMLIterator = NULL; zend_class_entry *spl_ce_SimpleXMLElement; @@ -85,7 +86,7 @@ RETURN_STRINGL((char*)curnode->name, xmlStrlen(curnode->name), 1); } - RETURN_FALSE; + RETURN_FALSE; } /* }}} */ @@ -106,7 +107,7 @@ php_sxe_object *child; xmlNodePtr node; - if (!sxe->iter.data) { + if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) { RETURN_FALSE; } child = php_sxe_fetch_object(sxe->iter.data TSRMLS_CC); @@ -128,13 +129,22 @@ { php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC); - if (!sxe->iter.data) { + if (!sxe->iter.data || sxe->iter.type == SXE_ITER_ATTRLIST) { return; /* return NULL */ } return_value->type = IS_OBJECT; return_value->value.obj = zend_objects_store_clone_obj(sxe->iter.data TSRMLS_CC); } +SPL_METHOD(SimpleXMLIterator, count) /* {{{ */ +{ + long count = 0; + + Z_OBJ_HANDLER_P(getThis(), count_elements)(getThis(), &count TSRMLS_CC); + + RETURN_LONG(count); +} + static zend_function_entry spl_funcs_SimpleXMLIterator[] = { SPL_ME(SimpleXMLIterator, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(SimpleXMLIterator, valid, NULL, ZEND_ACC_PUBLIC) @@ -143,6 +153,7 @@ SPL_ME(SimpleXMLIterator, next, NULL, ZEND_ACC_PUBLIC) SPL_ME(SimpleXMLIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) SPL_ME(SimpleXMLIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SimpleXMLIterator, count, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ @@ -150,17 +161,18 @@ SPL_API PHP_MINIT_FUNCTION(spl_sxe) /* {{{ */ { zend_class_entry **pce; - + if (zend_hash_find(CG(class_table), "simplexmlelement", sizeof("SimpleXMLElement"), (void **) &pce) == FAILURE) { spl_ce_SimpleXMLElement = NULL; spl_ce_SimpleXMLIterator = NULL; return SUCCESS; /* SimpleXML must be initialized before */ } - + spl_ce_SimpleXMLElement = *pce; REGISTER_SPL_SUB_CLASS_EX(SimpleXMLIterator, SimpleXMLElement, spl_ce_SimpleXMLElement->create_object, spl_funcs_SimpleXMLIterator); REGISTER_SPL_IMPLEMENTS(SimpleXMLIterator, RecursiveIterator); + REGISTER_SPL_IMPLEMENTS(SimpleXMLIterator, Countable); return SUCCESS; } http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/array_019.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/array_019.phpt +++ php-src/ext/spl/tests/array_019.phpt --TEST-- SPL: ArrayIterator and foreach by reference --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $ar = new ArrayObject(array(1)); foreach($ar as &$v) var_dump($v); $ar = new ArrayIterator(array(2)); foreach($ar as &$v) var_dump($v); $ar = new RecursiveArrayIterator(array(3)); foreach($ar as &$v) var_dump($v); class ArrayIteratorEx extends ArrayIterator { function current() { return ArrayIterator::current(); } } $ar = new ArrayIteratorEx(array(4)); foreach($ar as $v) var_dump($v); $ar = new ArrayIteratorEx(array(5)); foreach($ar as &$v) var_dump($v); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- int(1) int(2) int(3) int(4) Fatal error: An iterator cannot be used with foreach by reference in %sarray_019.php on line %d http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_030.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_030.phpt +++ php-src/ext/spl/tests/iterator_030.phpt --TEST-- SPL: EmptyIterator access --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $it = new EmptyIterator; var_dump($it->valid()); $it->rewind(); var_dump($it->valid()); $it->next(); var_dump($it->valid()); try { var_dump($it->key()); } catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } try { var_dump($it->current()); } catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } var_dump($it->valid()); ?> ===DONE=== <?php exit(0); ?> --EXPECT-- bool(false) bool(false) bool(false) Accessing the key of an EmptyIterator Accessing the value of an EmptyIterator bool(false) ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_031.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_031.phpt +++ php-src/ext/spl/tests/iterator_031.phpt --TEST-- SPL: AppendIterator::append() rewinds when neccessary --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyArrayIterator extends ArrayIterator { function rewind() { echo __METHOD__ . "\n"; parent::rewind(); } } $it = new MyArrayIterator(array(1,2)); foreach($it as $k=>$v) { echo "$k=>$v\n"; } class MyAppendIterator extends AppendIterator { function __construct() { echo __METHOD__ . "\n"; } function rewind() { echo __METHOD__ . "\n"; parent::rewind(); } function valid() { echo __METHOD__ . "\n"; return parent::valid(); } function append(Iterator $what) { echo __METHOD__ . "\n"; parent::append($what); } function parent__construct() { parent::__construct(); } } $ap = new MyAppendIterator; try { $ap->append($it); } catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } $ap->parent__construct(); try { $ap->parent__construct($it); } catch(BadMethodCallException $e) { echo $e->getMessage() . "\n"; } $ap->append($it); $ap->append($it); $ap->append($it); foreach($ap as $k=>$v) { echo "$k=>$v\n"; } ?> ===DONE=== <?php exit(0); ?> --EXPECT-- MyArrayIterator::rewind 0=>1 1=>2 MyAppendIterator::__construct MyAppendIterator::append Classes derived from AppendIterator must call AppendIterator::__construct() AppendIterator::getIterator() must be called exactly once per instance MyAppendIterator::append MyArrayIterator::rewind MyAppendIterator::append MyAppendIterator::append MyAppendIterator::rewind MyArrayIterator::rewind MyAppendIterator::valid 0=>1 MyAppendIterator::valid 1=>2 MyArrayIterator::rewind MyAppendIterator::valid 0=>1 MyAppendIterator::valid 1=>2 MyArrayIterator::rewind MyAppendIterator::valid 0=>1 MyAppendIterator::valid 1=>2 MyAppendIterator::valid ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_032.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_032.phpt +++ php-src/ext/spl/tests/iterator_032.phpt --TEST-- SPL: LimitIterator::getPosition() --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $it = new LimitIterator(new ArrayIterator(array(1,2,3,4)), 1, 2); foreach($it as $k=>$v) { echo "$k=>$v\n"; var_dump($it->getPosition()); } try { $it->seek(0); } catch(OutOfBoundsException $e) { echo $e->getMessage() . "\n"; } $it->seek(2); var_dump($it->current()); try { $it->seek(3); } catch(OutOfBoundsException $e) { echo $e->getMessage() . "\n"; } ?> ===DONE=== <?php exit(0); ?> --EXPECT-- 1=>2 int(1) 2=>3 int(2) Cannot seek to 0 which is below the offset 1 int(3) Cannot seek to 3 which is behind offest 1 plus count 2 ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_033.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_033.phpt +++ php-src/ext/spl/tests/iterator_033.phpt --TEST-- SPL: ParentIterator --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $it = new ParentIterator(new RecursiveArrayIterator(array(1,array(21,22, array(231)),3))); foreach(new RecursiveIteratorIterator($it) as $k=>$v) { var_dump($k); var_dump($v); } echo "==SECOND==\n"; foreach(new RecursiveIteratorIterator($it, 1) as $k=>$v) { var_dump($k); var_dump($v); } ?> ===DONE=== <?php exit(0); ?> --EXPECT-- ==SECOND== int(1) array(3) { [0]=> int(21) [1]=> int(22) [2]=> array(1) { [0]=> int(231) } } int(2) array(1) { [0]=> int(231) } ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_034.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_034.phpt +++ php-src/ext/spl/tests/iterator_034.phpt --TEST-- SPL: RecursiveIteratorIterator and break deep --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyRecursiveArrayIterator extends RecursiveArrayIterator { function valid() { if (!parent::valid()) { echo __METHOD__ . "() = false\n"; return false; } else { return true; } } function getChildren() { echo __METHOD__ . "()\n"; return parent::getChildren(); } function rewind() { echo __METHOD__ . "()\n"; parent::rewind(); } } class RecursiveArrayIteratorIterator extends RecursiveIteratorIterator { private $max_depth; private $over = 0; function __construct($it, $max_depth) { $this->max_depth = $max_depth; parent::__construct($it); } function rewind() { echo __METHOD__ . "() - BEGIN\n"; parent::rewind(); echo __METHOD__ . "() - DONE\n"; } function valid() { echo __METHOD__ . "()\n"; return parent::valid(); } function current() { echo __METHOD__ . "()\n"; return parent::current(); } function key() { echo __METHOD__ . "()\n"; return parent::key(); } function next() { echo __METHOD__ . "()\n"; parent::next(); } function callHasChildren() { $has = parent::callHasChildren(); $res = $this->getDepth() < $this->max_depth && $has; echo __METHOD__ . "(".$this->getDepth().") = ".($res?"yes":"no")."/".($has?"yes":"no")."\n"; return $res; } function beginChildren() { echo __METHOD__ . "(".$this->getDepth().")\n"; parent::beginChildren(); } function endChildren() { echo __METHOD__ . "(".$this->getDepth().")\n"; parent::endChildren(); } } $p = 0; $it = new RecursiveArrayIteratorIterator(new MyRecursiveArrayIterator(array("a", array("ba", array("bba", "bbb"), array(array("bcaa"), array("bcba"))), array("ca"), "d")), 2); foreach($it as $k=>$v) { if (is_array($v)) $v = join('',$v); echo "$k=>$v\n"; if ($p++ == 5) { echo "===BREAK===\n"; break; } } echo "===FOREND===\n"; $it->rewind(); echo "===CHECK===\n"; var_dump($it->valid()); var_dump($it->current()); ?> ===DONE=== <?php exit(0); ?> --EXPECT-- RecursiveArrayIteratorIterator::rewind() - BEGIN MyRecursiveArrayIterator::rewind() RecursiveArrayIteratorIterator::callHasChildren(0) = no/no RecursiveArrayIteratorIterator::rewind() - DONE RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 0=>a RecursiveArrayIteratorIterator::next() RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::rewind() RecursiveArrayIteratorIterator::beginChildren(1) RecursiveArrayIteratorIterator::callHasChildren(1) = no/no RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 0=>ba RecursiveArrayIteratorIterator::next() RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::rewind() RecursiveArrayIteratorIterator::beginChildren(2) RecursiveArrayIteratorIterator::callHasChildren(2) = no/no RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 0=>bba RecursiveArrayIteratorIterator::next() RecursiveArrayIteratorIterator::callHasChildren(2) = no/no RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 1=>bbb RecursiveArrayIteratorIterator::next() MyRecursiveArrayIterator::valid() = false RecursiveArrayIteratorIterator::endChildren(2) RecursiveArrayIteratorIterator::callHasChildren(1) = yes/yes MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::rewind() RecursiveArrayIteratorIterator::beginChildren(2) RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 0=>bcaa RecursiveArrayIteratorIterator::next() RecursiveArrayIteratorIterator::callHasChildren(2) = no/yes RecursiveArrayIteratorIterator::valid() RecursiveArrayIteratorIterator::current() RecursiveArrayIteratorIterator::key() 1=>bcba ===BREAK=== ===FOREND=== RecursiveArrayIteratorIterator::rewind() - BEGIN RecursiveArrayIteratorIterator::endChildren(1) RecursiveArrayIteratorIterator::endChildren(0) MyRecursiveArrayIterator::rewind() RecursiveArrayIteratorIterator::callHasChildren(0) = no/no RecursiveArrayIteratorIterator::rewind() - DONE ===CHECK=== RecursiveArrayIteratorIterator::valid() bool(true) RecursiveArrayIteratorIterator::current() string(1) "a" ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/sxe_005.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/sxe_005.phpt +++ php-src/ext/spl/tests/sxe_005.phpt --TEST-- SPL: SimpleXMLIterator and getChildren() --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; if (!extension_loaded('simplexml')) print 'skip'; if (!extension_loaded("libxml")) print "skip LibXML not present"; if (!class_exists('RecursiveIteratorIterator')) print 'skip RecursiveIteratorIterator not available'; ?> --FILE-- <?php $xml =<<<EOF <?xml version='1.0'?> <sxe> <elem1/> <elem2/> <elem2/> </sxe> EOF; class SXETest extends SimpleXMLIterator { function count() { echo __METHOD__ . "\n"; return parent::count(); } } $sxe = new SXETest($xml); var_dump(count($sxe)); var_dump(count($sxe->elem1)); var_dump(count($sxe->elem2)); ?> ===DONE=== --EXPECT-- SXETest::count int(3) SXETest::count int(1) SXETest::count int(2) ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php