From: Marcus Boerger Date: Sat, 8 Oct 2005 15:55:04 +0000 (+0000) Subject: - Add new class SplFileInfo X-Git-Tag: RELEASE_0_9_1~194 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7b330f195bd755f82ca7a2ae9e3d25de9a5abb79;p=php - Add new class SplFileInfo . Make DirectoryIterator inherit it . Make SplFileObject inherit it --- diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 1af7706f89..c6ce47175c 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -48,18 +48,26 @@ static zend_object_handlers spl_ce_dir_handlers; /* decalre the class entry */ +PHPAPI zend_class_entry *spl_ce_SplFileInfo; PHPAPI zend_class_entry *spl_ce_DirectoryIterator; PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator; PHPAPI zend_class_entry *spl_ce_SplFileObject; -static zend_object_value spl_file_object_new_ex(zend_class_entry *class_type, spl_file_object **obj TSRMLS_DC); -static int spl_file_object_open(spl_file_object *intern, int use_include_path, int silent TSRMLS_DC); +static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */ +{ + if (intern->u.file.current_line) { + efree(intern->u.file.current_line); + intern->u.file.current_line = NULL; + } + if (intern->u.file.current_zval) { + zval_ptr_dtor(&intern->u.file.current_zval); + intern->u.file.current_zval = NULL; + } +} /* }}} */ -/* {{{ spl_ce_dir_object_free_storage */ -/* close all resources and the memory allocated for the object */ -static void spl_ce_dir_object_free_storage(void *object TSRMLS_DC) +static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */ { - spl_ce_dir_object *intern = (spl_ce_dir_object *)object; + spl_filesystem_object *intern = (spl_filesystem_object*)object; zend_hash_destroy(intern->std.properties); FREE_HASHTABLE(intern->std.properties); @@ -67,19 +75,39 @@ static void spl_ce_dir_object_free_storage(void *object TSRMLS_DC) if (intern->path) { efree(intern->path); } - if (intern->dirp) { - php_stream_close(intern->dirp); - } - if (intern->path_name) { - efree(intern->path_name); + if (intern->file_name) { + efree(intern->file_name); } - if (intern->sub_path) { - efree(intern->sub_path); + switch(intern->type) { + case SPL_FS_INFO: + break; + case SPL_FS_DIR: + if (intern->u.dir.dirp) { + php_stream_close(intern->u.dir.dirp); + } + if (intern->u.dir.sub_path) { + efree(intern->u.dir.sub_path); + } + break; + case SPL_FS_FILE: + if (intern->u.file.stream) { + if (intern->u.file.zcontext) { +/* zend_list_delref(Z_RESVAL_P(intern->zcontext));*/ + } + if (!intern->u.file.stream->is_persistent) { + php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE); + } else { + php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT); + } + if (intern->u.file.open_mode) { + efree(intern->u.file.open_mode); + } + } + spl_filesystem_file_free_line(intern TSRMLS_CC); + break; } efree(object); -} -/* }}} */ - +} /* }}} */ /* {{{ spl_ce_dir_object_new */ /* creates the object by @@ -92,82 +120,138 @@ static void spl_ce_dir_object_free_storage(void *object TSRMLS_DC) - clone - new */ -static zend_object_value spl_ce_dir_object_new_ex(zend_class_entry *class_type, spl_ce_dir_object **obj TSRMLS_DC) +static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_type, spl_filesystem_object **obj TSRMLS_DC) { zend_object_value retval; - spl_ce_dir_object *intern; + spl_filesystem_object *intern; zval *tmp; - intern = emalloc(sizeof(spl_ce_dir_object)); - memset(intern, 0, sizeof(spl_ce_dir_object)); + intern = emalloc(sizeof(spl_filesystem_object)); + memset(intern, 0, sizeof(spl_filesystem_object)); intern->std.ce = class_type; + /* intern->type = SPL_FS_INFO; done by set o */ if (obj) *obj = intern; ALLOC_HASHTABLE(intern->std.properties); zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_ce_dir_object_free_storage, NULL TSRMLS_CC); + retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC); retval.handlers = &spl_ce_dir_handlers; return retval; } /* }}} */ - -/* {{{ spl_ce_dir_object_new */ -/* See spl_ce_dir_object_new_ex */ -static zend_object_value spl_ce_dir_object_new(zend_class_entry *class_type TSRMLS_DC) +/* {{{ spl_filesystem_object_new */ +/* See spl_filesystem_object_new_ex */ +static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type TSRMLS_DC) { - return spl_ce_dir_object_new_ex(class_type, NULL TSRMLS_CC); + return spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC); } /* }}} */ -/* {{{ spl_ce_dir_open */ +static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */ +{ + if (!intern->file_name) { + switch (intern->type) { + case SPL_FS_INFO: + case SPL_FS_FILE: + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized"); + break; + case SPL_FS_DIR: + intern->file_name_len = spprintf(&intern->file_name, 0, "%s/%s", intern->path, intern->u.dir.entry.d_name); + break; + } + } +} /* }}} */ + +/* {{{ spl_filesystem_dir_open */ /* open a directory resource */ -static void spl_ce_dir_open(spl_ce_dir_object* intern, char *path TSRMLS_DC) +static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path TSRMLS_DC) { - int path_len = strlen(path); - - intern->dirp = php_stream_opendir(path, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); + intern->type = SPL_FS_DIR; + intern->path_len = strlen(path); + intern->u.dir.dirp = php_stream_opendir(path, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); - if (path_len && (path[path_len-1] == '/' || path[path_len-1] == '\\')) { - intern->path = estrndup(path, --path_len); + if (intern->path_len && (path[intern->path_len-1] == '/' || path[intern->path_len-1] == '\\')) { + intern->path = estrndup(path, --intern->path_len); } else { - intern->path = estrndup(path, path_len); + intern->path = estrndup(path, intern->path_len); } - intern->index = 0; + intern->u.dir.index = 0; - if (intern->dirp == NULL) { + if (intern->u.dir.dirp == NULL) { /* throw exception: should've been already happened */ - intern->entry.d_name[0] = '\0'; + intern->u.dir.entry.d_name[0] = '\0'; } else { - if (!php_stream_readdir(intern->dirp, &intern->entry)) { - intern->entry.d_name[0] = '\0'; + if (!php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { + intern->u.dir.entry.d_name[0] = '\0'; } } } /* }}} */ -/* {{{ spl_ce_dir_object_clone */ +static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */ +{ + intern->type = SPL_FS_FILE; + intern->u.file.context = php_stream_context_from_zval(intern->u.file.zcontext, 0); + intern->u.file.stream = php_stream_open_wrapper_ex(intern->file_name, intern->u.file.open_mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, intern->u.file.context); + + if (intern->u.file.stream == NULL) { + if (!EG(exception)) { + zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Cannot open file %s", intern->file_name); + } + intern->file_name = NULL; /* until here it is not a copy */ + intern->u.file.open_mode = NULL; + return FAILURE; + } + + if (intern->u.file.zcontext) { + zend_list_addref(Z_RESVAL_P(intern->u.file.zcontext)); + } + + intern->file_name = estrndup(intern->file_name, intern->file_name_len); + intern->u.file.open_mode = estrndup(intern->u.file.open_mode, intern->u.file.open_mode_len); + + /* avoid reference counting in debug mode, thus do it manually */ + ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream)); + intern->u.file.zresource.refcount = 1; + + zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr); + + return SUCCESS; +} /* }}} */ + +/* {{{ spl_filesystem_object_clone */ /* Local zend_object_value creation (on stack) Load the 'other' object - Create a new empty object (See spl_ce_dir_object_new_ex) + Create a new empty object (See spl_filesystem_object_new_ex) Open the directory Clone other members (properties) */ -static zend_object_value spl_ce_dir_object_clone(zval *zobject TSRMLS_DC) +static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC) { zend_object_value new_obj_val; zend_object *old_object; zend_object *new_object; zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); - spl_ce_dir_object *intern; + spl_filesystem_object *intern; old_object = zend_objects_get_address(zobject TSRMLS_CC); - new_obj_val = spl_ce_dir_object_new_ex(old_object->ce, &intern TSRMLS_CC); + + new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern TSRMLS_CC); new_object = &intern->std; - spl_ce_dir_open(intern, ((spl_ce_dir_object*)old_object)->path TSRMLS_CC); + switch(((spl_filesystem_object*)old_object)->type) { + case SPL_FS_INFO: + break; + case SPL_FS_DIR: + spl_filesystem_dir_open(intern, ((spl_filesystem_object*)old_object)->path TSRMLS_CC); + break; + case SPL_FS_FILE: + php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %v cannot be cloned", old_object->ce->name); + break; + } zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC); @@ -186,8 +270,7 @@ static zend_object_value spl_ce_dir_object_clone(zval *zobject TSRMLS_DC) */ SPL_METHOD(DirectoryIterator, __construct) { - zval *object = getThis(); - spl_ce_dir_object *intern; + spl_filesystem_object *intern; char *path; int len; @@ -198,8 +281,8 @@ SPL_METHOD(DirectoryIterator, __construct) return; } - intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); - spl_ce_dir_open(intern, path TSRMLS_CC); + intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_dir_open(intern, path TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } @@ -209,15 +292,14 @@ SPL_METHOD(DirectoryIterator, __construct) Rewind dir back to the start */ SPL_METHOD(DirectoryIterator, rewind) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - intern->index = 0; - if (intern->dirp) { - php_stream_rewinddir(intern->dirp); + intern->u.dir.index = 0; + if (intern->u.dir.dirp) { + php_stream_rewinddir(intern->u.dir.dirp); } - if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { - intern->entry.d_name[0] = '\0'; + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { + intern->u.dir.entry.d_name[0] = '\0'; } } /* }}} */ @@ -226,11 +308,10 @@ SPL_METHOD(DirectoryIterator, rewind) Return current dir entry */ SPL_METHOD(DirectoryIterator, key) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (intern->dirp) { - RETURN_LONG(intern->index); + if (intern->u.dir.dirp) { + RETURN_LONG(intern->u.dir.index); } else { RETURN_FALSE; } @@ -249,16 +330,15 @@ SPL_METHOD(DirectoryIterator, current) Move to next entry */ SPL_METHOD(DirectoryIterator, next) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - intern->index++; - if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { - intern->entry.d_name[0] = '\0'; + intern->u.dir.index++; + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { + intern->u.dir.entry.d_name[0] = '\0'; } - if (intern->path_name) { - efree(intern->path_name); - intern->path_name = NULL; + if (intern->file_name) { + efree(intern->file_name); + intern->file_name = NULL; } } /* }}} */ @@ -267,10 +347,9 @@ SPL_METHOD(DirectoryIterator, next) Check whether dir contains more entries */ SPL_METHOD(DirectoryIterator, valid) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(intern->entry.d_name[0] != '\0'); + RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0'); } /* }}} */ @@ -278,8 +357,7 @@ SPL_METHOD(DirectoryIterator, valid) Return directory path */ SPL_METHOD(DirectoryIterator, getPath) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRING(intern->path, 1); } @@ -289,33 +367,29 @@ SPL_METHOD(DirectoryIterator, getPath) Return filename of current dir entry */ SPL_METHOD(DirectoryIterator, getFilename) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_STRING(intern->entry.d_name, 1); + RETURN_STRING(intern->u.dir.entry.d_name, 1); } /* }}} */ -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) +/* {{{ proto string SplFileInfo::getPathname() + Return path and filename */ +SPL_METHOD(SplFileInfo, getPathname) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (intern->entry.d_name[0]) { - spl_dir_get_path_name(intern); - RETURN_STRINGL(intern->path_name, intern->path_name_len, 1); - } else { - RETURN_BOOL(0); + switch (intern->type) { + case SPL_FS_INFO: + case SPL_FS_FILE: + RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); + case SPL_FS_DIR: + if (intern->u.dir.entry.d_name[0]) { + spl_filesystem_object_get_file_name(intern TSRMLS_CC); + RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); + } } + RETURN_BOOL(0); } /* }}} */ @@ -323,11 +397,10 @@ SPL_METHOD(DirectoryIterator, getPathname) Return path and filename of current dir entry */ SPL_METHOD(RecursiveDirectoryIterator, key) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - spl_dir_get_path_name(intern); - RETURN_STRINGL(intern->path_name, intern->path_name_len, 1); + spl_filesystem_object_get_file_name(intern TSRMLS_CC); + RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); } /* }}} */ @@ -335,136 +408,174 @@ SPL_METHOD(RecursiveDirectoryIterator, key) Returns true if current entry is '.' or '..' */ SPL_METHOD(DirectoryIterator, isDot) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(!strcmp(intern->entry.d_name, ".") || !strcmp(intern->entry.d_name, "..")); + RETURN_BOOL(!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); } /* }}} */ -/* {{{ DirectoryFunction */ -#define DirectoryFunction(func_name, func_num) \ -SPL_METHOD(DirectoryIterator, func_name) \ +/* {{{ proto void SplFileInfo::__construct(string file_name) + Cronstructs a new SplFileInfo from a path. */ +/* php_set_error_handling() is used to throw exceptions in case + the constructor fails. Here we use this to ensure the object + has a valid directory resource. + + When the constructor gets called the object is already created + by the engine, so we must only call 'additional' initializations. + */ +SPL_METHOD(SplFileInfo, __construct) +{ + spl_filesystem_object *intern; + char *path; + int len; + + php_set_error_handling(EH_THROW, U_CLASS_ENTRY(spl_ce_RuntimeException) TSRMLS_CC); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) { + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + return; + } + + intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + intern->file_name = estrdup(path); + intern->file_name_len = len; + /* intern->type = SPL_FS_INFO; already set */ + + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ FileInfoFunction */ +#define FileInfoFunction(func_name, func_num) \ +SPL_METHOD(SplFileInfo, func_name) \ { \ - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \ + spl_filesystem_object *intern = (spl_filesystem_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); \ + spl_filesystem_object_get_file_name(intern TSRMLS_CC); \ + php_stat(intern->file_name, intern->file_name_len, func_num, return_value TSRMLS_CC); \ } /* }}} */ -/* {{{ proto int DirectoryIterator::getPerms() +/* {{{ proto int SplFileInfo::getPerms() Get file permissions */ -DirectoryFunction(getPerms, FS_PERMS) +FileInfoFunction(getPerms, FS_PERMS) /* }}} */ -/* {{{ proto int DirectoryIterator::getInode() +/* {{{ proto int SplFileInfo::getInode() Get file inode */ -DirectoryFunction(getInode, FS_INODE) +FileInfoFunction(getInode, FS_INODE) /* }}} */ -/* {{{ proto int DirectoryIterator::getSize() +/* {{{ proto int SplFileInfo::getSize() Get file size */ -DirectoryFunction(getSize, FS_SIZE) +FileInfoFunction(getSize, FS_SIZE) /* }}} */ -/* {{{ proto int DirectoryIterator::getOwner() +/* {{{ proto int SplFileInfo::getOwner() Get file owner */ -DirectoryFunction(getOwner, FS_OWNER) +FileInfoFunction(getOwner, FS_OWNER) /* }}} */ -/* {{{ proto int DirectoryIterator::getGroup() +/* {{{ proto int SplFileInfo::getGroup() Get file group */ -DirectoryFunction(getGroup, FS_GROUP) +FileInfoFunction(getGroup, FS_GROUP) /* }}} */ -/* {{{ proto int DirectoryIterator::getATime() +/* {{{ proto int SplFileInfo::getATime() Get last access time of file */ -DirectoryFunction(getATime, FS_ATIME) +FileInfoFunction(getATime, FS_ATIME) /* }}} */ -/* {{{ proto int DirectoryIterator::getMTime() +/* {{{ proto int SplFileInfo::getMTime() Get last modification time of file */ -DirectoryFunction(getMTime, FS_MTIME) +FileInfoFunction(getMTime, FS_MTIME) /* }}} */ -/* {{{ proto int DirectoryIterator::getCTime() +/* {{{ proto int SplFileInfo::getCTime() Get inode modification time of file */ -DirectoryFunction(getCTime, FS_CTIME) +FileInfoFunction(getCTime, FS_CTIME) /* }}} */ -/* {{{ proto string DirectoryIterator::getType() +/* {{{ proto string SplFileInfo::getType() Get file type */ -DirectoryFunction(getType, FS_TYPE) +FileInfoFunction(getType, FS_TYPE) /* }}} */ -/* {{{ proto bool DirectoryIterator::isWritable() +/* {{{ proto bool SplFileInfo::isWritable() Returns true if file can be written */ -DirectoryFunction(isWritable, FS_IS_W) +FileInfoFunction(isWritable, FS_IS_W) /* }}} */ -/* {{{ proto bool DirectoryIterator::isReadable() +/* {{{ proto bool SplFileInfo::isReadable() Returns true if file can be read */ -DirectoryFunction(isReadable, FS_IS_R) +FileInfoFunction(isReadable, FS_IS_R) /* }}} */ -/* {{{ proto bool DirectoryIterator::isExecutable() +/* {{{ proto bool SplFileInfo::isExecutable() Returns true if file is executable */ -DirectoryFunction(isExecutable, FS_IS_X) +FileInfoFunction(isExecutable, FS_IS_X) /* }}} */ -/* {{{ proto bool DirectoryIterator::isFile() +/* {{{ proto bool SplFileInfo::isFile() Returns true if file is a regular file */ -DirectoryFunction(isFile, FS_IS_FILE) +FileInfoFunction(isFile, FS_IS_FILE) /* }}} */ -/* {{{ proto bool DirectoryIterator::isDir() +/* {{{ proto bool SplFileInfo::isDir() Returns true if file is directory */ -DirectoryFunction(isDir, FS_IS_DIR) +FileInfoFunction(isDir, FS_IS_DIR) /* }}} */ -/* {{{ proto bool DirectoryIterator::isLink() +/* {{{ proto bool SplFileInfo::isLink() Returns true if file is symbolic link */ -DirectoryFunction(isLink, FS_IS_LINK) +FileInfoFunction(isLink, FS_IS_LINK) /* }}} */ -/* {{{ proto SplFileObject DirectoryIterator::openFile([string mode = 'r' [, bool use_include_path [, resource context]]]) +/* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path [, resource context]]]) Open the current file */ -SPL_METHOD(DirectoryIterator, openFile) +SPL_METHOD(SplFileInfo, openFile) { - zval *object = getThis(); - spl_ce_dir_object *dir_obj = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); - spl_file_object *intern; + spl_filesystem_object *dir_obj = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern; zend_bool use_include_path = 0; php_set_error_handling(EH_THROW, U_CLASS_ENTRY(spl_ce_RuntimeException) TSRMLS_CC); - if (!dir_obj->entry.d_name[0]) { - zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Could not open file"); - zval_dtor(return_value); - return; + switch (intern->type) { + case SPL_FS_INFO: + case SPL_FS_FILE: + break; + case SPL_FS_DIR: + if (!dir_obj->u.dir.entry.d_name[0]) { + zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Could not open file"); + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + zval_dtor(return_value); + return; + } } + + return_value->value.obj = spl_filesystem_object_new_ex(spl_ce_SplFileObject, &intern TSRMLS_CC); - return_value->value.obj = spl_file_object_new_ex(spl_ce_SplFileObject, &intern TSRMLS_CC); - - spl_dir_get_path_name(dir_obj); - intern->file_name = dir_obj->path_name; - intern->file_name_len = dir_obj->path_name_len; + spl_filesystem_object_get_file_name(dir_obj TSRMLS_CC); + intern->file_name = dir_obj->file_name; + intern->file_name_len = dir_obj->file_name_len; - intern->open_mode = "r"; - intern->open_mode_len = 1; + intern->u.file.open_mode = "r"; + intern->u.file.open_mode_len = 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr", - &intern->open_mode, &intern->open_mode_len, - &use_include_path, &intern->zcontext) == FAILURE) { + &intern->u.file.open_mode, &intern->u.file.open_mode_len, + &use_include_path, &intern->u.file.zcontext) == FAILURE) { php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); zval_dtor(return_value); return; } - if (spl_file_object_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) { + if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) { Z_TYPE_P(return_value) = IS_OBJECT; } else { + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); zval_dtor(return_value); return; } @@ -476,18 +587,17 @@ SPL_METHOD(DirectoryIterator, openFile) Rewind dir back to the start */ SPL_METHOD(RecursiveDirectoryIterator, rewind) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - intern->index = 0; - if (intern->dirp) { - php_stream_rewinddir(intern->dirp); + intern->u.dir.index = 0; + if (intern->u.dir.dirp) { + php_stream_rewinddir(intern->u.dir.dirp); } do { - if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { - intern->entry.d_name[0] = '\0'; + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { + intern->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(intern->entry.d_name, ".") || !strcmp(intern->entry.d_name, "..")); + } while (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); } /* }}} */ @@ -495,18 +605,17 @@ SPL_METHOD(RecursiveDirectoryIterator, rewind) Move to next entry */ SPL_METHOD(RecursiveDirectoryIterator, next) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - intern->index++; + intern->u.dir.index++; do { - if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { - intern->entry.d_name[0] = '\0'; + if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) { + intern->u.dir.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; + } while (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")); + if (intern->file_name) { + efree(intern->file_name); + intern->file_name = NULL; } } /* }}} */ @@ -516,23 +625,22 @@ SPL_METHOD(RecursiveDirectoryIterator, next) SPL_METHOD(RecursiveDirectoryIterator, hasChildren) { zend_bool allow_links = 0; - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (!strcmp(intern->entry.d_name, ".") || !strcmp(intern->entry.d_name, "..")) { + if (!strcmp(intern->u.dir.entry.d_name, ".") || !strcmp(intern->u.dir.entry.d_name, "..")) { RETURN_BOOL(0); } else { if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) { return; } - spl_dir_get_path_name(intern); + spl_filesystem_object_get_file_name(intern TSRMLS_CC); if (!allow_links) { - php_stat(intern->path_name, intern->path_name_len, FS_IS_LINK, return_value TSRMLS_CC); + php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC); if (zend_is_true(return_value)) { RETURN_BOOL(0); } } - php_stat(intern->path_name, intern->path_name_len, FS_IS_DIR, return_value TSRMLS_CC); + php_stat(intern->file_name, intern->file_name_len, FS_IS_DIR, return_value TSRMLS_CC); } } /* }}} */ @@ -541,24 +649,24 @@ SPL_METHOD(RecursiveDirectoryIterator, hasChildren) Returns an iterator for the current entry if it is a directory */ 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); - spl_ce_dir_object *subdir; + zval zpath; + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *subdir; - spl_dir_get_path_name(intern); + spl_filesystem_object_get_file_name(intern TSRMLS_CC); INIT_PZVAL(&zpath); - ZVAL_STRINGL(&zpath, intern->path_name, intern->path_name_len, 0); + ZVAL_STRINGL(&zpath, intern->file_name, intern->file_name_len, 0); spl_instantiate_arg_ex1(spl_ce_RecursiveDirectoryIterator, &return_value, 0, &zpath TSRMLS_CC); - subdir = (spl_ce_dir_object*)zend_object_store_get_object(return_value TSRMLS_CC); + subdir = (spl_filesystem_object*)zend_object_store_get_object(return_value TSRMLS_CC); if (subdir) { - if (intern->sub_path && intern->sub_path[0]) { - subdir->sub_path_len = spprintf(&subdir->sub_path, 0, "%s/%s", intern->sub_path, intern->entry.d_name); + if (intern->u.dir.sub_path && intern->u.dir.sub_path[0]) { + subdir->u.dir.sub_path_len = spprintf(&subdir->u.dir.sub_path, 0, "%s/%s", intern->u.dir.sub_path, intern->u.dir.entry.d_name); } else { - subdir->sub_path_len = strlen(intern->entry.d_name); - subdir->sub_path = estrndup(intern->entry.d_name, subdir->sub_path_len); + subdir->u.dir.sub_path_len = strlen(intern->u.dir.entry.d_name); + subdir->u.dir.sub_path = estrndup(intern->u.dir.entry.d_name, subdir->u.dir.sub_path_len); } } } @@ -568,11 +676,10 @@ SPL_METHOD(RecursiveDirectoryIterator, getChildren) Get sub path */ SPL_METHOD(RecursiveDirectoryIterator, getSubPath) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (intern->sub_path) { - RETURN_STRINGL(intern->sub_path, intern->sub_path_len, 1); + if (intern->u.dir.sub_path) { + RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1); } else { RETURN_STRINGL("", 0, 1); } @@ -583,16 +690,15 @@ SPL_METHOD(RecursiveDirectoryIterator, getSubPath) Get sub path and file name */ SPL_METHOD(RecursiveDirectoryIterator, getSubPathname) { - zval *object = getThis(); - spl_ce_dir_object *intern = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char *sub_name; int len; - if (intern->sub_path) { - len = spprintf(&sub_name, 0, "%s/%s", intern->sub_path, intern->entry.d_name); + if (intern->u.dir.sub_path) { + len = spprintf(&sub_name, 0, "%s/%s", intern->u.dir.sub_path, intern->u.dir.entry.d_name); RETURN_STRINGL(sub_name, len, 0); } else { - RETURN_STRING(intern->entry.d_name, 1); + RETURN_STRING(intern->u.dir.entry.d_name, 1); } } /* }}} */ @@ -601,36 +707,36 @@ SPL_METHOD(RecursiveDirectoryIterator, getSubPathname) typedef struct { zend_object_iterator intern; zval *current; - spl_ce_dir_object *object; -} spl_ce_dir_it; + spl_filesystem_object *object; +} spl_filesystem_dir_it; /* forward declarations to the iterator handlers */ -static void spl_ce_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC); -static int spl_ce_dir_it_valid(zend_object_iterator *iter TSRMLS_DC); -static void spl_ce_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC); -static int spl_ce_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC); -static void spl_ce_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC); -static void spl_ce_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC); +static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC); +static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC); +static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC); +static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC); +static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC); +static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC); /* iterator handler table */ -zend_object_iterator_funcs spl_ce_dir_it_funcs = { - spl_ce_dir_it_dtor, - spl_ce_dir_it_valid, - spl_ce_dir_it_current_data, - spl_ce_dir_it_current_key, - spl_ce_dir_it_move_forward, - spl_ce_dir_it_rewind +zend_object_iterator_funcs spl_filesystem_dir_it_funcs = { + spl_filesystem_dir_it_dtor, + spl_filesystem_dir_it_valid, + spl_filesystem_dir_it_current_data, + spl_filesystem_dir_it_current_key, + spl_filesystem_dir_it_move_forward, + spl_filesystem_dir_it_rewind }; /* {{{ spl_ce_dir_get_iterator */ -zend_object_iterator *spl_ce_dir_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) +zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) { - spl_ce_dir_it *iterator = emalloc(sizeof(spl_ce_dir_it)); - spl_ce_dir_object *dir_object = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_dir_it *iterator = emalloc(sizeof(spl_filesystem_dir_it)); + spl_filesystem_object *dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); object->refcount++; iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_ce_dir_it_funcs; + iterator->intern.funcs = &spl_filesystem_dir_it_funcs; iterator->current = object; object->refcount++; iterator->object = dir_object; @@ -639,10 +745,10 @@ zend_object_iterator *spl_ce_dir_get_iterator(zend_class_entry *ce, zval *object } /* }}} */ -/* {{{ spl_ce_dir_it_dtor */ -static void spl_ce_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_dtor */ +static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; zval_ptr_dtor(&iterator->current); zval_ptr_dtor((zval**)&iterator->intern.data); @@ -651,139 +757,139 @@ static void spl_ce_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC) } /* }}} */ -/* {{{ spl_ce_dir_it_valid */ -static int spl_ce_dir_it_valid(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_valid */ +static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - return object->entry.d_name[0] != '\0' ? SUCCESS : FAILURE; + return object->u.dir.entry.d_name[0] != '\0' ? SUCCESS : FAILURE; } /* }}} */ -/* {{{ spl_ce_dir_it_current_data */ -static void spl_ce_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_current_data */ +static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; *data = &iterator->current; } /* }}} */ -/* {{{ spl_ce_dir_it_current_key */ -static int spl_ce_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_current_key */ +static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - *int_key = object->index; + *int_key = object->u.dir.index; return HASH_KEY_IS_LONG; } /* }}} */ -/* {{{ spl_ce_dir_it_move_forward */ -static void spl_ce_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_move_forward */ +static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - object->index++; - if (!object->dirp || !php_stream_readdir(object->dirp, &object->entry)) { - object->entry.d_name[0] = '\0'; + object->u.dir.index++; + if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { + object->u.dir.entry.d_name[0] = '\0'; } - if (object->path_name) { - efree(object->path_name); - object->path_name = NULL; + if (object->file_name) { + efree(object->file_name); + object->file_name = NULL; } } /* }}} */ -/* {{{ spl_ce_dir_it_rewind */ -static void spl_ce_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_dir_it_rewind */ +static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - object->index = 0; - if (object->dirp) { - php_stream_rewinddir(object->dirp); + object->u.dir.index = 0; + if (object->u.dir.dirp) { + php_stream_rewinddir(object->u.dir.dirp); } - if (!object->dirp || !php_stream_readdir(object->dirp, &object->entry)) { - object->entry.d_name[0] = '\0'; + if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { + object->u.dir.entry.d_name[0] = '\0'; } } /* }}} */ -/* {{{ spl_ce_dir_tree_it_current_key */ -static int spl_ce_dir_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) +/* {{{ spl_filesystem_tree_it_current_key */ +static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - spl_dir_get_path_name(object); - *str_key_len = object->path_name_len + 1; - *str_key = estrndup(object->path_name, object->path_name_len); + spl_filesystem_object_get_file_name(object TSRMLS_CC); + *str_key_len = object->file_name_len + 1; + *str_key = estrndup(object->file_name, object->file_name_len); return HASH_KEY_IS_STRING; } /* }}} */ -/* {{{ spl_ce_dir_tree_it_move_forward */ -static void spl_ce_dir_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_tree_it_move_forward */ +static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - object->index++; + object->u.dir.index++; do { - if (!object->dirp || !php_stream_readdir(object->dirp, &object->entry)) { - object->entry.d_name[0] = '\0'; + if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { + object->u.dir.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; + } while (!strcmp(object->u.dir.entry.d_name, ".") || !strcmp(object->u.dir.entry.d_name, "..")); + if (object->file_name) { + efree(object->file_name); + object->file_name = NULL; } } /* }}} */ -/* {{{ spl_ce_dir_tree_it_rewind */ -static void spl_ce_dir_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC) +/* {{{ spl_filesystem_tree_it_rewind */ +static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC) { - spl_ce_dir_it *iterator = (spl_ce_dir_it *)iter; - spl_ce_dir_object *object = iterator->object; + spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter; + spl_filesystem_object *object = iterator->object; - object->index = 0; - if (object->dirp) { - php_stream_rewinddir(object->dirp); + object->u.dir.index = 0; + if (object->u.dir.dirp) { + php_stream_rewinddir(object->u.dir.dirp); } do { - if (!object->dirp || !php_stream_readdir(object->dirp, &object->entry)) { - object->entry.d_name[0] = '\0'; + if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) { + object->u.dir.entry.d_name[0] = '\0'; } - } while (!strcmp(object->entry.d_name, ".") || !strcmp(object->entry.d_name, "..")); + } while (!strcmp(object->u.dir.entry.d_name, ".") || !strcmp(object->u.dir.entry.d_name, "..")); } /* }}} */ /* iterator handler table */ -zend_object_iterator_funcs spl_ce_dir_tree_it_funcs = { - spl_ce_dir_it_dtor, - spl_ce_dir_it_valid, - spl_ce_dir_it_current_data, - spl_ce_dir_tree_it_current_key, - spl_ce_dir_tree_it_move_forward, - spl_ce_dir_tree_it_rewind +zend_object_iterator_funcs spl_filesystem_tree_it_funcs = { + spl_filesystem_dir_it_dtor, + spl_filesystem_dir_it_valid, + spl_filesystem_dir_it_current_data, + spl_filesystem_tree_it_current_key, + spl_filesystem_tree_it_move_forward, + spl_filesystem_tree_it_rewind }; /* {{{ spl_ce_dir_get_iterator */ -zend_object_iterator *spl_ce_dir_tree_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) +zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) { - spl_ce_dir_it *iterator = emalloc(sizeof(spl_ce_dir_it)); - spl_ce_dir_object *dir_object = (spl_ce_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + spl_filesystem_dir_it *iterator = emalloc(sizeof(spl_filesystem_dir_it)); + spl_filesystem_object *dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); object->refcount++; iterator->intern.data = (void*)object; - iterator->intern.funcs = &spl_ce_dir_tree_it_funcs; + iterator->intern.funcs = &spl_filesystem_tree_it_funcs; iterator->current = object; object->refcount++; iterator->object = dir_object; @@ -792,14 +898,28 @@ zend_object_iterator *spl_ce_dir_tree_get_iterator(zend_class_entry *ce, zval *o } /* }}} */ -/* {{{ spl_ce_dir_cast */ -static int spl_ce_dir_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) +/* {{{ spl_filesystem_object_cast */ +static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) { - spl_ce_dir_object *dir_object = (spl_ce_dir_object*)zend_object_store_get_object(readobj TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC); - if (type ==IS_STRING && *dir_object->entry.d_name) { - ZVAL_STRING(writeobj, dir_object->entry.d_name, 1); - return SUCCESS; + if (type == IS_STRING) { + switch (intern->type) { + case SPL_FS_INFO: + case SPL_FS_FILE: + ZVAL_STRINGL(writeobj, intern->file_name, intern->file_name_len, 1); + return SUCCESS; + case SPL_FS_DIR: + if (intern->u.dir.is_recursive) { + spl_filesystem_object_get_file_name(intern TSRMLS_CC); + ZVAL_STRINGL(writeobj, intern->file_name, intern->file_name_len, 1); + return SUCCESS; + } else if (*intern->u.dir.entry.d_name) { + ZVAL_STRING(writeobj, intern->u.dir.entry.d_name, 1); + return SUCCESS; + } + return FAILURE; + } } return FAILURE; } @@ -808,12 +928,12 @@ static int spl_ce_dir_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) /* 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_BEGIN_ARG_INFO(arginfo_info___construct, 0) + ZEND_ARG_INFO(0, file_name) ZEND_END_ARG_INFO(); static -ZEND_BEGIN_ARG_INFO_EX(arginfo_dir_openFile, 0, 0, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_info_openFile, 0, 0, 0) ZEND_ARG_INFO(0, open_mode) ZEND_ARG_INFO(0, use_include_path) ZEND_ARG_INFO(0, context) @@ -821,38 +941,51 @@ 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[] = { +static zend_function_entry spl_filesystem_info_class_functions[] = { + SPL_ME(SplFileInfo, __construct, arginfo_info___construct, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getPerms, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getInode, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getSize, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getOwner, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getGroup, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getATime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getMTime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getCTime, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getType, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isWritable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isReadable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isExecutable, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isFile, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isDir, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isLink, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC) + SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) + {NULL, NULL, NULL} +}; + +static +ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO(); + +/* the method table */ +/* each method can have its own parameters and visibility */ +static zend_function_entry spl_filesystem_dir_class_functions[] = { SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getPath, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, valid, 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_ME(DirectoryIterator, openFile, arginfo_dir_openFile, 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[] = { +static zend_function_entry spl_filesystem_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) @@ -860,96 +993,33 @@ static zend_function_entry spl_ce_dir_tree_class_functions[] = { 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_MA(RecursiveDirectoryIterator, __toString, SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; -static void spl_file_object_free_line(spl_file_object *intern TSRMLS_DC) /* {{{ */ -{ - if (intern->current_line) { - efree(intern->current_line); - intern->current_line = NULL; - } - if (intern->current_zval) { - zval_ptr_dtor(&intern->current_zval); - intern->current_zval = NULL; - } -} /* }}} */ - -static void spl_file_object_free_storage(void *object TSRMLS_DC) /* {{{ */ -{ - spl_file_object *intern = (spl_file_object*)object; - - zend_hash_destroy(intern->std.properties); - FREE_HASHTABLE(intern->std.properties); - - if (intern->stream) { - if (intern->zcontext) { -/* zend_list_delref(Z_RESVAL_P(intern->zcontext));*/ - } - if (!intern->stream->is_persistent) { - php_stream_free(intern->stream, PHP_STREAM_FREE_CLOSE); - } else { - php_stream_free(intern->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT); - } - if (intern->file_name) { - efree(intern->file_name); - } - if (intern->open_mode) { - efree(intern->open_mode); - } - } - spl_file_object_free_line(intern TSRMLS_CC); - efree(object); -} /* }}} */ - -static zend_object_value spl_file_object_new_ex(zend_class_entry *class_type, spl_file_object **obj TSRMLS_DC) /* {{{ */ -{ - zend_object_value retval; - spl_file_object *intern; - zval *tmp; - - intern = emalloc(sizeof(spl_ce_dir_object)); - memset(intern, 0, sizeof(spl_ce_dir_object)); - intern->std.ce = class_type; - if (obj) *obj = intern; - - ALLOC_HASHTABLE(intern->std.properties); - zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - - retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_file_object_free_storage, NULL TSRMLS_CC); - retval.handlers = &spl_ce_dir_handlers; - return retval; -} /* }}} */ - -static zend_object_value spl_file_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ -{ - return spl_file_object_new_ex(class_type, NULL TSRMLS_CC); -} /* }}} */ - -static int spl_file_object_read(spl_file_object *intern, int silent TSRMLS_DC) /* {{{ */ +static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */ { char *buf; size_t line_len; int len; - long line_add = (intern->current_line || intern->current_zval) ? 1 : 0; + long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0; - spl_file_object_free_line(intern TSRMLS_CC); + spl_filesystem_file_free_line(intern TSRMLS_CC); - if (php_stream_eof(intern->stream)) { + if (php_stream_eof(intern->u.file.stream)) { if (!silent) { zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name); } return FAILURE; } - buf = php_stream_get_line(intern->stream, NULL, intern->max_line_len, &line_len); + buf = php_stream_get_line(intern->u.file.stream, NULL, intern->u.file.max_line_len, &line_len); if (!buf) { - intern->current_line = estrdup(""); - intern->current_line_len = 0; + intern->u.file.current_line = estrdup(""); + intern->u.file.current_line_len = 0; } else { - if (intern->flags & SPL_FILE_OBJECT_DROP_NEW_LINE) { + if (intern->u.file.flags & SPL_FILE_OBJECT_DROP_NEW_LINE) { line_len = strcspn(buf, "\r\n"); buf[line_len] = '\0'; } @@ -959,38 +1029,38 @@ static int spl_file_object_read(spl_file_object *intern, int silent TSRMLS_DC) / line_len = len; } - intern->current_line = buf; - intern->current_line_len = line_len; + intern->u.file.current_line = buf; + intern->u.file.current_line_len = line_len; } - intern->current_line_num += line_add; + intern->u.file.current_line_num += line_add; return SUCCESS; } /* }}} */ -static int spl_file_object_read_line(zval * this_ptr, spl_file_object *intern, int silent TSRMLS_DC) /* {{{ */ +static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */ { zval *retval; /* if overloaded call the function, otherwise do it directly */ - if (intern->func_getCurr->common.scope != spl_ce_SplFileObject) { - if (php_stream_eof(intern->stream)) { + if (intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) { + if (php_stream_eof(intern->u.file.stream)) { if (!silent) { zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name); } return FAILURE; } - zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), &intern->func_getCurr, "getCurrentLine", &retval); + zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval); if (retval) { - if (intern->current_line || intern->current_zval) { - intern->current_line_num++; + if (intern->u.file.current_line || intern->u.file.current_zval) { + intern->u.file.current_line_num++; } - spl_file_object_free_line(intern TSRMLS_CC); + spl_filesystem_file_free_line(intern TSRMLS_CC); if (Z_TYPE_P(retval) == IS_STRING) { - intern->current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); - intern->current_line_len = Z_STRLEN_P(retval); + intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); + intern->u.file.current_line_len = Z_STRLEN_P(retval); } else { - MAKE_STD_ZVAL(intern->current_zval); - ZVAL_ZVAL(intern->current_zval, retval, 1, 0); + MAKE_STD_ZVAL(intern->u.file.current_zval); + ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0); } zval_ptr_dtor(&retval); return SUCCESS; @@ -998,69 +1068,41 @@ static int spl_file_object_read_line(zval * this_ptr, spl_file_object *intern, i return FAILURE; } } else { - return spl_file_object_read(intern, silent TSRMLS_CC); + return spl_filesystem_file_read(intern, silent TSRMLS_CC); } } /* }}} */ -static void spl_file_object_rewind(spl_file_object *intern TSRMLS_DC) /* {{{ */ +static void spl_filesystem_file_rewind(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */ { - if (-1 == php_stream_rewind(intern->stream)) { + if (-1 == php_stream_rewind(intern->u.file.stream)) { zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name); } else { - spl_file_object_free_line(intern TSRMLS_CC); - intern->current_line_num = 0; + spl_filesystem_file_free_line(intern TSRMLS_CC); + intern->u.file.current_line_num = 0; } } /* }}} */ -static int spl_file_object_open(spl_file_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */ -{ - intern->context = php_stream_context_from_zval(intern->zcontext, 0); - intern->stream = php_stream_open_wrapper_ex(intern->file_name, intern->open_mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, intern->context); - - if (intern->stream == NULL) { - if (!EG(exception)) { - zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_RuntimeException), 0 TSRMLS_CC, "Cannot open file %s", intern->file_name); - } - return FAILURE; - } - - if (intern->zcontext) { - zend_list_addref(Z_RESVAL_P(intern->zcontext)); - } - - intern->file_name = estrndup(intern->file_name, intern->file_name_len); - intern->open_mode = estrndup(intern->open_mode, intern->open_mode_len); - - /* avoid reference counting in debug mode, thus do it manually */ - ZVAL_RESOURCE(&intern->zresource, php_stream_get_resource_id(intern->stream)); - intern->zresource.refcount = 1; - - zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->func_getCurr); - - return SUCCESS; -} /* }}} */ - /* {{{ proto void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path [, resource context]]]]) Construct a new file reader */ SPL_METHOD(SplFileObject, __construct) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_bool use_include_path = 0; php_set_error_handling(EH_THROW, U_CLASS_ENTRY(spl_ce_RuntimeException) TSRMLS_CC); - intern->open_mode = "r"; - intern->open_mode_len = 1; + intern->u.file.open_mode = "r"; + intern->u.file.open_mode_len = 1; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sbr", &intern->file_name, &intern->file_name_len, - &intern->open_mode, &intern->open_mode_len, - &use_include_path, &intern->zcontext) == FAILURE) { + &intern->u.file.open_mode, &intern->u.file.open_mode_len, + &use_include_path, &intern->u.file.zcontext) == FAILURE) { php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); return; } - spl_file_object_open(intern, use_include_path, 0 TSRMLS_CC); + spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); } /* }}} */ @@ -1069,16 +1111,16 @@ SPL_METHOD(SplFileObject, __construct) Rewind the file and read the first line */ SPL_METHOD(SplFileObject, rewind) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - spl_file_object_rewind(intern TSRMLS_CC); + spl_filesystem_file_rewind(intern TSRMLS_CC); } /* }}} */ /* {{{ proto string SplFileObject::getFilename() Return the filename */ SPL_METHOD(SplFileObject, getFilename) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); RETURN_STRINGL(intern->file_name, intern->file_name_len, 1); } /* }}} */ @@ -1087,45 +1129,45 @@ SPL_METHOD(SplFileObject, getFilename) Return whether end of file is reached */ SPL_METHOD(SplFileObject, eof) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(php_stream_eof(intern->stream)); + RETURN_BOOL(php_stream_eof(intern->u.file.stream)); } /* }}} */ /* {{{ proto void SplFileObject::valid() Return !eof() */ SPL_METHOD(SplFileObject, valid) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETVAL_BOOL(!php_stream_eof(intern->stream)); + RETVAL_BOOL(!php_stream_eof(intern->u.file.stream)); } /* }}} */ /* {{{ proto string SplFileObject::fgets() Rturn next line from file */ SPL_METHOD(SplFileObject, fgets) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (spl_file_object_read(intern, 0 TSRMLS_CC) == FAILURE) { + if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) { RETURN_FALSE; } - RETURN_STRINGL(intern->current_line, intern->current_line_len, 1); + RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1); } /* }}} */ /* {{{ proto string SplFileObject::current() Return current line from file */ SPL_METHOD(SplFileObject, current) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (!intern->current_line) { - spl_file_object_read_line(getThis(), intern, 1 TSRMLS_CC); + if (!intern->u.file.current_line) { + spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } - if (intern->current_line) { - RETURN_STRINGL(intern->current_line, intern->current_line_len, 1); - } else if (intern->current_zval) { - RETURN_ZVAL(intern->current_zval, 1, 0); + if (intern->u.file.current_line) { + RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1); + } else if (intern->u.file.current_zval) { + RETURN_ZVAL(intern->u.file.current_zval, 1, 0); } RETURN_FALSE; } /* }}} */ @@ -1134,41 +1176,41 @@ SPL_METHOD(SplFileObject, current) Return line number */ SPL_METHOD(SplFileObject, key) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); /* Do not read the next line to support correct counting with fgetc() if (!intern->current_line) { - spl_file_object_read_line(getThis(), intern, 1 TSRMLS_CC); + spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } */ - RETURN_LONG(intern->current_line_num); + RETURN_LONG(intern->u.file.current_line_num); } /* }}} */ /* {{{ proto void SplFileObject::next() Read next line */ SPL_METHOD(SplFileObject, next) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - spl_file_object_free_line(intern TSRMLS_CC); - intern->current_line_num++; + spl_filesystem_file_free_line(intern TSRMLS_CC); + intern->u.file.current_line_num++; } /* }}} */ /* {{{ proto void SplFileObject::setFlags(int flags) Set file handling flags */ SPL_METHOD(SplFileObject, setFlags) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags); + zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->u.file.flags); } /* }}} */ /* {{{ proto int SplFileObject::getFlags() Get file handling flags */ SPL_METHOD(SplFileObject, getFlags) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_LONG(intern->flags); + RETURN_LONG(intern->u.file.flags); } /* }}} */ /* {{{ proto void SplFileObject::setMaxLineLen(int max_len) @@ -1177,7 +1219,7 @@ SPL_METHOD(SplFileObject, setMaxLineLen) { long max_len; - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_len) == FAILURE) { return; @@ -1188,16 +1230,16 @@ SPL_METHOD(SplFileObject, setMaxLineLen) return; } - intern->max_line_len = max_len; + intern->u.file.max_line_len = max_len; } /* }}} */ /* {{{ proto int SplFileObject::getMaxLineLen() Get maximum line length */ SPL_METHOD(SplFileObject, getMaxLineLen) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_LONG((long)intern->max_line_len); + RETURN_LONG((long)intern->u.file.max_line_len); } /* }}} */ /* {{{ proto bool SplFileObject>>hasChildren() @@ -1214,12 +1256,12 @@ SPL_METHOD(SplFileObject, getChildren) /* return NULL */ } /* }}} */ -static int spl_file_object_call(INTERNAL_FUNCTION_PARAMETERS, spl_file_object *intern, zend_function *func_ptr, zval *arg2) /* {{{ */ +static int spl_filesystem_file_call(INTERNAL_FUNCTION_PARAMETERS, spl_filesystem_object *intern, zend_function *func_ptr, zval *arg2) /* {{{ */ { zend_fcall_info fci; zend_fcall_info_cache fcic; zval z_fname; - zval * zresource_ptr = &intern->zresource, *retval; + zval * zresource_ptr = &intern->u.file.zresource, *retval; int result; zval ***params = (zval***)safe_emalloc(ZEND_NUM_ARGS(), sizeof(zval**), (arg2 ? 2 : 1) * sizeof(zval**)); @@ -1261,14 +1303,14 @@ static int spl_file_object_call(INTERNAL_FUNCTION_PARAMETERS, spl_file_object *i { \ zend_function *func_ptr; \ zend_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \ - spl_file_object_call(INTERNAL_FUNCTION_PARAM_PASSTHRU, intern, func_ptr, arg2); \ + spl_filesystem_file_call(INTERNAL_FUNCTION_PARAM_PASSTHRU, intern, func_ptr, arg2); \ } /* {{{ FileFunction */ #define FileFunction(func_name) \ SPL_METHOD(SplFileObject, func_name) \ { \ - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \ + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \ FileFunctionCall(func_name, NULL); \ } /* }}} */ @@ -1277,13 +1319,13 @@ SPL_METHOD(SplFileObject, func_name) \ Return current line as csv */ SPL_METHOD(SplFileObject, fgetcsv) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *arg2 = NULL; MAKE_STD_ZVAL(arg2); - ZVAL_LONG(arg2, intern->max_line_len); + ZVAL_LONG(arg2, intern->u.file.max_line_len); - spl_file_object_free_line(intern TSRMLS_CC); - intern->current_line_num++; + spl_filesystem_file_free_line(intern TSRMLS_CC); + intern->u.file.current_line_num++; FileFunctionCall(fgetcsv, arg2); @@ -1300,9 +1342,9 @@ FileFunction(flock) Flush the file */ SPL_METHOD(SplFileObject, fflush) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(!php_stream_flush(intern->stream)); + RETURN_BOOL(!php_stream_flush(intern->u.file.stream)); } /* }}} */ @@ -1310,8 +1352,8 @@ SPL_METHOD(SplFileObject, fflush) Return current file position */ SPL_METHOD(SplFileObject, ftell) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - long ret = php_stream_tell(intern->stream); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + long ret = php_stream_tell(intern->u.file.stream); if (ret == -1) { RETURN_FALSE; @@ -1324,34 +1366,34 @@ SPL_METHOD(SplFileObject, ftell) Return current file position */ SPL_METHOD(SplFileObject, fseek) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long pos, whence = SEEK_SET; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pos, &whence) == FAILURE) { return; } - spl_file_object_free_line(intern TSRMLS_CC); - RETURN_LONG(php_stream_seek(intern->stream, pos, whence)); + spl_filesystem_file_free_line(intern TSRMLS_CC); + RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence)); } /* }}} */ /* {{{ proto int SplFileObject::fgetc() Get a character form the file */ SPL_METHOD(SplFileObject, fgetc) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char buf[2]; int result; - spl_file_object_free_line(intern TSRMLS_CC); + spl_filesystem_file_free_line(intern TSRMLS_CC); - result = php_stream_getc(intern->stream); + result = php_stream_getc(intern->u.file.stream); if (result == EOF) { RETVAL_FALSE; } else { if (result == '\n') { - intern->current_line_num++; + intern->u.file.current_line_num++; } buf[0] = result; buf[1] = '\0'; @@ -1364,13 +1406,13 @@ SPL_METHOD(SplFileObject, fgetc) Get a line from file pointer and strip HTML tags */ SPL_METHOD(SplFileObject, fgetss) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zval *arg2 = NULL; MAKE_STD_ZVAL(arg2); - ZVAL_LONG(arg2, intern->max_line_len); + ZVAL_LONG(arg2, intern->u.file.max_line_len); - spl_file_object_free_line(intern TSRMLS_CC); - intern->current_line_num++; + spl_filesystem_file_free_line(intern TSRMLS_CC); + intern->u.file.current_line_num++; FileFunctionCall(fgetss, arg2); @@ -1381,19 +1423,19 @@ SPL_METHOD(SplFileObject, fgetss) Output all remaining data from a file pointer */ SPL_METHOD(SplFileObject, fpassthru) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_LONG(php_stream_passthru(intern->stream)); + RETURN_LONG(php_stream_passthru(intern->u.file.stream)); } /* }}} */ /* {{{ proto bool SplFileObject::fscanf(string format [, string ...]) Implements a mostly ANSI compatible fscanf() */ SPL_METHOD(SplFileObject, fscanf) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - spl_file_object_free_line(intern TSRMLS_CC); - intern->current_line_num++; + spl_filesystem_file_free_line(intern TSRMLS_CC); + intern->u.file.current_line_num++; FileFunctionCall(fscanf, NULL); } @@ -1403,7 +1445,7 @@ SPL_METHOD(SplFileObject, fscanf) Binary-safe file write */ SPL_METHOD(SplFileObject, fwrite) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); char *str; int str_len; int ret; @@ -1423,12 +1465,12 @@ SPL_METHOD(SplFileObject, fwrite) if (PG(magic_quotes_runtime)) { str = estrndup(str, str_len); php_stripslashes(str, &str_len TSRMLS_CC); - ret = php_stream_write(intern->stream, str, str_len); + ret = php_stream_write(intern->u.file.stream, str, str_len); efree(str); RETURN_LONG(ret); } - RETURN_LONG(php_stream_write(intern->stream, str, str_len)); + RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len)); } /* }}} */ /* {{{ proto bool SplFileObject::fstat() @@ -1440,26 +1482,26 @@ FileFunction(fstat) Truncate file to 'size' length */ SPL_METHOD(SplFileObject, ftruncate) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long size; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) { return; } - if (!php_stream_truncate_supported(intern->stream)) { + if (!php_stream_truncate_supported(intern->u.file.stream)) { zend_throw_exception_ex(U_CLASS_ENTRY(spl_ce_LogicException), 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name); RETURN_FALSE; } - RETURN_BOOL(0 == php_stream_truncate_set_size(intern->stream, size)); + RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size)); } /* }}} */ /* {{{ proto void SplFileObject::seek(int line_pos) Seek to specified line */ SPL_METHOD(SplFileObject, seek) { - spl_file_object *intern = (spl_file_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); long line_pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) { @@ -1470,10 +1512,10 @@ SPL_METHOD(SplFileObject, seek) RETURN_FALSE; } - spl_file_object_rewind(intern TSRMLS_CC); + spl_filesystem_file_rewind(intern TSRMLS_CC); - while(intern->current_line_num < line_pos) { - spl_file_object_read_line(getThis(), intern, 1 TSRMLS_CC); + while(intern->u.file.current_line_num < line_pos) { + spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC); } } @@ -1539,7 +1581,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1) ZEND_ARG_INFO(0, line_pos) ZEND_END_ARG_INFO(); -static zend_function_entry spl_file_object_class_functions[] = { +static zend_function_entry spl_filesystem_file_class_functions[] = { SPL_ME(SplFileObject, __construct, arginfo_file_object___construct, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, getFilename, NULL, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, rewind, NULL, ZEND_ACC_PUBLIC) @@ -1578,20 +1620,22 @@ static zend_function_entry spl_file_object_class_functions[] = { */ PHP_MINIT_FUNCTION(spl_directory) { - REGISTER_SPL_STD_CLASS_EX(DirectoryIterator, spl_ce_dir_object_new, spl_ce_dir_class_functions); + REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_filesystem_info_class_functions); + + REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_filesystem_dir_class_functions); zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator); memcpy(&spl_ce_dir_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - spl_ce_dir_handlers.clone_obj = spl_ce_dir_object_clone; - spl_ce_dir_handlers.cast_object = spl_ce_dir_cast; + spl_ce_dir_handlers.clone_obj = spl_filesystem_object_clone; + spl_ce_dir_handlers.cast_object = spl_filesystem_object_cast; - spl_ce_DirectoryIterator->get_iterator = spl_ce_dir_get_iterator; + spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator; - REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, DirectoryIterator, spl_ce_dir_object_new, spl_ce_dir_tree_class_functions); + REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, DirectoryIterator, spl_filesystem_object_new, spl_filesystem_tree_class_functions); REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator); - spl_ce_RecursiveDirectoryIterator->get_iterator = spl_ce_dir_tree_get_iterator; + spl_ce_RecursiveDirectoryIterator->get_iterator = spl_filesystem_tree_get_iterator; - REGISTER_SPL_STD_CLASS_EX(SplFileObject, spl_file_object_new, spl_file_object_class_functions); + REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new, spl_filesystem_file_class_functions); REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator); REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator); diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 10922da6d2..2d1ab9ca2b 100755 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -24,42 +24,52 @@ #include "php.h" #include "php_spl.h" +extern PHPAPI zend_class_entry *spl_ce_SplFileInfo; extern PHPAPI zend_class_entry *spl_ce_DirectoryIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator; extern PHPAPI zend_class_entry *spl_ce_SplFileObject; PHP_MINIT_FUNCTION(spl_directory); -typedef struct _spl_ce_dir_object { - zend_object std; - php_stream *dirp; - php_stream_dirent entry; - char *path; - char *path_name; - int path_name_len; - char *sub_path; - int sub_path_len; - int index; -} spl_ce_dir_object; +typedef enum { + SPL_FS_INFO, + SPL_FS_DIR, + SPL_FS_FILE, +} SPL_FS_OBJ_TYPE; -typedef struct _spl_file_object { +typedef struct _spl_filesystem_object { zend_object std; - php_stream *stream; - php_stream_context *context; - zval *zcontext; + char *path; + int path_len; char *file_name; - int file_name_len; - char *open_mode; - int open_mode_len; - zval *current_zval; - char *current_line; - size_t current_line_len; - size_t max_line_len; - long current_line_num; - long flags; - zval zresource; - zend_function *func_getCurr; -} spl_file_object; + int file_name_len; + SPL_FS_OBJ_TYPE type; + union { + struct { + php_stream *dirp; + php_stream_dirent entry; + char *sub_path; + int sub_path_len; + int index; + int is_recursive; + } dir; + struct { + php_stream *stream; + php_stream_context *context; + zval *zcontext; + char *open_mode; + int open_mode_len; + zval *current_zval; + char *current_line; + size_t current_line_len; + size_t max_line_len; + long current_line_num; + long flags; + zval zresource; + zend_function *func_getCurr; + } file; + } u; +} spl_filesystem_object; #define SPL_FILE_OBJECT_DROP_NEW_LINE 0x00000001 /* drop new lines */