From: Marcus Boerger Date: Sat, 13 Dec 2003 14:40:56 +0000 (+0000) Subject: Add standard file info functions to DirectoryIterator X-Git-Tag: php-5.0.0b3RC1~94 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9a98ff3ab50dfd705e296def33347c52e237559d;p=php Add standard file info functions to DirectoryIterator --- diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index f049ac4737..bf563457f4 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -41,62 +41,6 @@ #include "ext/standard/basic_functions.h" #include "ext/standard/php_filestat.h" -/* forward declaration for all methods use (class-name, method-name) */ -SPL_METHOD(DirectoryIterator, __construct); -SPL_METHOD(DirectoryIterator, rewind); -SPL_METHOD(DirectoryIterator, hasMore); -SPL_METHOD(DirectoryIterator, key); -SPL_METHOD(DirectoryIterator, current); -SPL_METHOD(DirectoryIterator, next); -SPL_METHOD(DirectoryIterator, getPath); -SPL_METHOD(DirectoryIterator, getFilename); -SPL_METHOD(DirectoryIterator, getPathname); -SPL_METHOD(DirectoryIterator, isDot); -SPL_METHOD(DirectoryIterator, isDir); - -SPL_METHOD(RecursiveDirectoryIterator, rewind); -SPL_METHOD(RecursiveDirectoryIterator, next); -SPL_METHOD(RecursiveDirectoryIterator, key); -SPL_METHOD(RecursiveDirectoryIterator, hasChildren); -SPL_METHOD(RecursiveDirectoryIterator, getChildren); - - -/* declare method parameters */ -/* supply a name and default to call by parameter */ -static -ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) - ZEND_ARG_INFO(0, path) /* parameter name */ -ZEND_END_ARG_INFO(); - - -/* the method table */ -/* each method can have its own parameters and visibility */ -static zend_function_entry spl_ce_dir_class_functions[] = { - SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, hasMore, NULL, ZEND_ACC_PUBLIC) - 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, getPath, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, getPathname, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, isDir, NULL, ZEND_ACC_PUBLIC) - SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - -static zend_function_entry spl_ce_dir_tree_class_functions[] = { - SPL_ME(RecursiveDirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC) - {NULL, NULL, NULL} -}; - - /* declare the class handlers */ static zend_object_handlers spl_ce_dir_handlers; @@ -121,6 +65,9 @@ static void spl_ce_dir_object_dtor(void *object, zend_object_handle handle TSRML if (intern->dirp) { php_stream_close(intern->dirp); } + if (intern->path_name) { + efree(intern->path_name); + } efree(object); } /* }}} */ @@ -297,6 +244,10 @@ SPL_METHOD(DirectoryIterator, next) if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { intern->entry.d_name[0] = '\0'; } + if (intern->path_name) { + efree(intern->path_name); + intern->path_name = NULL; + } } /* }}} */ @@ -333,6 +284,13 @@ SPL_METHOD(DirectoryIterator, getFilename) } /* }}} */ +static inline void spl_dir_get_path_name(spl_ce_dir_object *intern) +{ + if (!intern->path_name) { + intern->path_name_len = spprintf(&intern->path_name, 0, "%s/%s", intern->path, intern->entry.d_name); + } +} + /* {{{ proto string DirectoryIterator::getPathname() Return path and filename of current dir entry */ SPL_METHOD(DirectoryIterator, getPathname) @@ -341,9 +299,8 @@ SPL_METHOD(DirectoryIterator, getPathname) spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); if (intern->entry.d_name[0]) { - char *filename; - int filename_len = spprintf(&filename, 0, "%s/%s", intern->path, intern->entry.d_name); - RETURN_STRINGL(filename, filename_len, 0); + spl_dir_get_path_name(intern); + RETURN_STRINGL(intern->path_name, intern->path_name_len, 1); } else { RETURN_BOOL(0); } @@ -357,9 +314,8 @@ SPL_METHOD(RecursiveDirectoryIterator, key) zval *object = getThis(); spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); - char *filename; - int filename_len = spprintf(&filename, 0, "%s/%s", intern->path, intern->entry.d_name); - RETURN_STRINGL(filename, filename_len, 0); + spl_dir_get_path_name(intern); + RETURN_STRINGL(intern->path_name, intern->path_name_len, 1); } /* }}} */ @@ -374,20 +330,90 @@ SPL_METHOD(DirectoryIterator, isDot) } /* }}} */ -/* {{{ proto bool DirectoryIterator::isDir() - Returns whether current entry is a directory */ -SPL_METHOD(DirectoryIterator, isDir) -{ - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); - char *filename; - - php_stat_len filename_len = spprintf(&filename, 0, "%s/%s", intern->path, intern->entry.d_name); +/* {{{ FileFunction */ +#define FileFunction(func_name, func_num) \ +SPL_METHOD(DirectoryIterator, func_name) \ +{ \ + spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \ + \ + spl_dir_get_path_name(intern); \ + php_stat(intern->path_name, intern->path_name_len, func_num, return_value TSRMLS_CC); \ +} +/* }}} */ - php_stat(filename, filename_len, /*funcnum*/FS_IS_DIR, return_value TSRMLS_CC); +/* {{{ proto int DirectoryIterator::filePerms() + Get file permissions */ +FileFunction(getPerms, FS_PERMS) +/* }}} */ - efree(filename); -} +/* {{{ proto int DirectoryIterator::fileInode() + Get file inode */ +FileFunction(getInode, FS_INODE) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileSize() + Get file size */ +FileFunction(getSize, FS_SIZE) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileOwner() + Get file owner */ +FileFunction(getOwner, FS_OWNER) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileGroup() + Get file group */ +FileFunction(getGroup, FS_GROUP) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileATime() + Get last access time of file */ +FileFunction(getATime, FS_ATIME) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileMTime() + Get last modification time of file */ +FileFunction(getMTime, FS_MTIME) +/* }}} */ + +/* {{{ proto int DirectoryIterator::fileCTime() + Get inode modification time of file */ +FileFunction(getCTime, FS_CTIME) +/* }}} */ + +/* {{{ proto string DirectoryIterator::fileType() + Get file type */ +FileFunction(getType, FS_TYPE) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isWritable() + Returns true if file can be written */ +FileFunction(isWritable, FS_IS_W) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isReadable() + Returns true if file can be read */ +FileFunction(isReadable, FS_IS_R) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isExecutable() + Returns true if file is executable */ +FileFunction(isExecutable, FS_IS_X) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isFile() + Returns true if file is a regular file */ +FileFunction(isFile, FS_IS_FILE) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isDir() + Returns true if file is directory */ +FileFunction(isDir, FS_IS_DIR) +/* }}} */ + +/* {{{ proto bool DirectoryIterator::isLink() + Returns true if file is symbolic link */ +FileFunction(isLink, FS_IS_LINK) /* }}} */ /* {{{ proto void RecursiveDirectoryIterator::rewind() @@ -422,6 +448,10 @@ SPL_METHOD(RecursiveDirectoryIterator, next) intern->entry.d_name[0] = '\0'; } } while (!strcmp(intern->entry.d_name, ".") || !strcmp(intern->entry.d_name, "..")); + if (intern->path_name) { + efree(intern->path_name); + intern->path_name = NULL; + } } /* }}} */ @@ -435,11 +465,8 @@ SPL_METHOD(RecursiveDirectoryIterator, hasChildren) if (!strcmp(intern->entry.d_name, ".") || !strcmp(intern->entry.d_name, "..")) { RETURN_BOOL(0); } else { - char *filename; - php_stat_len filename_len = spprintf(&filename, 0, "%s/%s", intern->path, intern->entry.d_name); - - php_stat(filename, filename_len, FS_IS_DIR, return_value TSRMLS_CC); - efree(filename); + spl_dir_get_path_name(intern); + php_stat(intern->path_name, intern->path_name_len, FS_IS_DIR, return_value TSRMLS_CC); } } /* }}} */ @@ -451,14 +478,12 @@ SPL_METHOD(RecursiveDirectoryIterator, getChildren) zval *object = getThis(), zpath; spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); - char *path; - int path_len = spprintf(&path, 0, "%s/%s", intern->path, intern->entry.d_name); + spl_dir_get_path_name(intern); INIT_PZVAL(&zpath); - ZVAL_STRINGL(&zpath, path, path_len, 0); + ZVAL_STRINGL(&zpath, intern->path_name, intern->path_name_len, 0); spl_instantiate_arg_ex1(spl_ce_RecursiveDirectoryIterator, &return_value, 0, &zpath TSRMLS_CC); - zval_dtor(&zpath); } /* }}} */ @@ -563,6 +588,10 @@ static void spl_ce_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC) if (!object->dirp || !php_stream_readdir(object->dirp, &object->entry)) { object->entry.d_name[0] = '\0'; } + if (object->path_name) { + efree(object->path_name); + object->path_name = NULL; + } } /* }}} */ @@ -590,7 +619,9 @@ static int spl_ce_dir_tree_it_current_key(zend_object_iterator *iter, char **str spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; spl_ce_dir_object *object = iterator->object; - *str_key_len = spprintf(str_key, 0, "%s/%s", object->path, object->entry.d_name) + 1; + spl_dir_get_path_name(object); + *str_key_len = object->path_name_len + 1; + *str_key = estrndup(object->path_name, object->path_name_len); return HASH_KEY_IS_STRING; } /* }}} */ @@ -608,6 +639,10 @@ static void spl_ce_dir_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC object->entry.d_name[0] = '\0'; } } while (!strcmp(object->entry.d_name, ".") || !strcmp(object->entry.d_name, "..")); + if (object->path_name) { + efree(object->path_name); + object->path_name = NULL; + } } /* }}} */ @@ -676,6 +711,56 @@ static int spl_ce_dir_cast(zval *readobj, zval *writeobj, int type, int should_f } /* }}} */ +/* declare method parameters */ +/* supply a name and default to call by parameter */ +static +ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) + ZEND_ARG_INFO(0, path) /* parameter name */ +ZEND_END_ARG_INFO(); + + +/* the method table */ +/* each method can have its own parameters and visibility */ +static zend_function_entry spl_ce_dir_class_functions[] = { + SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, hasMore, NULL, ZEND_ACC_PUBLIC) + 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, getPath, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getPathname, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getPerms, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getInode, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getSize, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getOwner, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getGroup, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getATime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getMTime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getCTime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getType, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isWritable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isReadable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isExecutable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isFile, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isDir, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isLink, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC) + SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +static zend_function_entry spl_ce_dir_tree_class_functions[] = { + SPL_ME(RecursiveDirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, key, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + + /* {{{ PHP_MINIT_FUNCTION(spl_directory) */ PHP_MINIT_FUNCTION(spl_directory) diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 8fc14d9946..4e94ec20b0 100755 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -31,6 +31,8 @@ typedef struct _spl_ce_dir_object { php_stream *dirp; php_stream_dirent entry; char *path; + char *path_name; + int path_name_len; int index; } spl_ce_dir_object;