#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;
if (intern->dirp) {
php_stream_close(intern->dirp);
}
+ if (intern->path_name) {
+ efree(intern->path_name);
+ }
efree(object);
}
/* }}} */
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;
+ }
}
/* }}} */
}
/* }}} */
+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)
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);
}
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);
}
/* }}} */
}
/* }}} */
-/* {{{ 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()
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;
+ }
}
/* }}} */
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);
}
}
/* }}} */
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);
}
/* }}} */
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;
+ }
}
/* }}} */
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;
}
/* }}} */
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;
+ }
}
/* }}} */
}
/* }}} */
+/* 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)