From: Etienne Kneuss Date: Sat, 19 Jul 2008 11:20:18 +0000 (+0000) Subject: MFH: Implement DirectoryIterator::seek X-Git-Tag: php-5.3.0alpha1~278 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8dafec40be1b2f7f0606e911fa5735b397a24a76;p=php MFH: Implement DirectoryIterator::seek --- diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 4ae4babdf1..bee85e6d12 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -703,6 +703,43 @@ SPL_METHOD(DirectoryIterator, next) } /* }}} */ +/* {{{ proto void DirectoryIterator::seek(int position) + Seek to the given position */ +SPL_METHOD(DirectoryIterator, seek) +{ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + zval *retval = NULL; + long pos; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &pos) == FAILURE) { + return; + } + + if (intern->u.dir.index > pos) { + /* we first rewind */ + zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_rewind, "rewind", &retval); + if (retval) { + zval_ptr_dtor(&retval); + } + } + + while (intern->u.dir.index < pos) { + int valid = 0; + zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_valid, "valid", &retval); + if (retval) { + valid = zend_is_true(retval); + zval_ptr_dtor(&retval); + } + if (!valid) { + break; + } + zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.dir.func_next, "next", &retval); + if (retval) { + zval_ptr_dtor(&retval); + } + } +} /* }}} */ + /* {{{ proto string DirectoryIterator::valid() Check whether dir contains more entries */ SPL_METHOD(DirectoryIterator, valid) @@ -1619,6 +1656,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) ZEND_ARG_INFO(0, path) ZEND_END_ARG_INFO() +static +ZEND_BEGIN_ARG_INFO(arginfo_dir_it_seek, 0) + ZEND_ARG_INFO(0, position) +ZEND_END_ARG_INFO(); + /* the method table */ /* each method can have its own parameters and visibility */ static const zend_function_entry spl_DirectoryIterator_functions[] = { @@ -1631,6 +1673,7 @@ static const zend_function_entry spl_DirectoryIterator_functions[] = { SPL_ME(DirectoryIterator, key, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, current, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, seek, arginfo_dir_it_seek, ZEND_ACC_PUBLIC) SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2560,12 +2603,13 @@ PHP_MINIT_FUNCTION(spl_directory) { REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_SplFileInfo_functions); memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; - spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast; - spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info; + spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone; + spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast; + spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info; REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions); zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator); + REGISTER_SPL_IMPLEMENTS(DirectoryIterator, SeekableIterator); spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator; diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index eecfbe1f68..68d3a4fce5 100755 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -80,6 +80,9 @@ struct _spl_filesystem_object { int sub_path_len; int index; int is_recursive; + zend_function *func_rewind; + zend_function *func_next; + zend_function *func_valid; } dir; struct { php_stream *stream; diff --git a/ext/spl/tests/dit_006.phpt b/ext/spl/tests/dit_006.phpt new file mode 100644 index 0000000000..1e627a20e0 --- /dev/null +++ b/ext/spl/tests/dit_006.phpt @@ -0,0 +1,50 @@ +--TEST-- +SPL: DirectoryIterator and seek +--FILE-- +seek(2); + +$n = 0; +while ($di->valid()) { + $n++; + $di->next(); +} + +echo "With seek(2) we get $n\n"; +$di->seek(0); + +$m = 0; +while ($di->valid()) { + $m++; + $di->next(); +} +echo "With seek(0) we get $m\n"; + +$o = 0; +$di->rewind(); +while ($di->valid()) { + $o++; + $di->next(); +} + +echo "Without seek we get $o\n"; + +$p = 0; +$di->seek($o+1); +while ($di->valid()) { + $p++; + $di->next(); +} + +var_dump($n !== $m, $m === $o, $p === 0); +?> +===DONE=== +--EXPECTF-- +With seek(2) we get %d +With seek(0) we get %d +Without seek we get %d +bool(true) +bool(true) +bool(true) +===DONE===