diff options
-rwxr-xr-x | ext/spl/config.m4 | 2 | ||||
-rwxr-xr-x | ext/spl/php_spl.c | 2 | ||||
-rwxr-xr-x | ext/spl/php_spl.h | 2 | ||||
-rwxr-xr-x | ext/spl/spl_directory.c | 242 | ||||
-rwxr-xr-x | ext/spl/spl_functions.c | 4 | ||||
-rwxr-xr-x | ext/spl/spl_functions.h | 11 |
6 files changed, 256 insertions, 7 deletions
diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index 195a193dc5..bce2b4f43a 100755 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -39,5 +39,5 @@ fi if test "$PHP_SPL" != "no"; then AC_DEFINE(HAVE_SPL, 1, [Whether you want SPL (Standard Php Library) support]) - PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_foreach.c spl_array.c, $ext_shared) + PHP_NEW_EXTENSION(spl, php_spl.c spl_functions.c spl_engine.c spl_foreach.c spl_array.c spl_directory.c, $ext_shared) fi diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index c8a0866726..3f32948056 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -136,6 +136,8 @@ PHP_MINIT_FUNCTION(spl) REGISTER_SPL_IMPLEMENT(array_access, array_read); REGISTER_SPL_INTF_FUNC(array_access, set); + PHP_MINIT(spl_directory)(INIT_FUNC_ARGS_PASSTHRU); + return SUCCESS; } /* }}} */ diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h index e4abfd4514..36603cb0d1 100755 --- a/ext/spl/php_spl.h +++ b/ext/spl/php_spl.h @@ -95,6 +95,8 @@ PHP_FUNCTION(spl_classes); PHP_FUNCTION(class_parents); PHP_FUNCTION(class_implements); +PHP_MINIT_FUNCTION(spl_directory); + #endif /* PHP_SPL_H */ /* diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c new file mode 100755 index 0000000000..8581abdde7 --- /dev/null +++ b/ext/spl/spl_directory.c @@ -0,0 +1,242 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 4 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2003 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "zend_compile.h" +#include "zend_execute_locks.h" +#include "zend_default_classes.h" + +#include "php_spl.h" +#include "spl_functions.h" +#include "spl_engine.h" +#include "spl_foreach.h" + +#include "php.h" +#include "fopen_wrappers.h" + +SPL_CLASS_FUNCTION(dir, __construct); +SPL_CLASS_FUNCTION(dir, rewind); +SPL_CLASS_FUNCTION(dir, current); +SPL_CLASS_FUNCTION(dir, next); +SPL_CLASS_FUNCTION(dir, has_more); +SPL_CLASS_FUNCTION(dir, get_path); + +static zend_function_entry spl_dir_class_functions[] = { + SPL_CLASS_FE(dir, __construct, NULL) + SPL_CLASS_FE(dir, rewind, NULL) + SPL_CLASS_FE(dir, current, NULL) + SPL_CLASS_FE(dir, next, NULL) + SPL_CLASS_FE(dir, has_more, NULL) + SPL_CLASS_FE(dir, get_path, NULL) + {NULL, NULL, NULL} +}; + +static zend_object_handlers spl_dir_handlers; +static zend_class_entry *spl_ce_dir; + +typedef struct _spl_dir_object { + zend_object std; + php_stream *dirp; + php_stream_dirent entry; + char *path; +} spl_dir_object; + +/* {{{ spl_dir_object_dtor */ +static void spl_dir_object_dtor(void *object, zend_object_handle handle TSRMLS_DC) +{ + spl_dir_object *intern = (spl_dir_object *)object; + + zend_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + if (intern->path) { + efree(intern->path); + } + if (intern->dirp) { + php_stream_close(intern->dirp); + } + efree(object); +} +/* }}} */ + +/* {{{ spl_dir_object_clone */ +static void spl_dir_object_clone(void *object, void **object_clone TSRMLS_DC) +{ + /* TODO */ +} +/* }}} */ + +/* {{{ spl_dir_object_new */ +static zend_object_value spl_dir_object_new(zend_class_entry *class_type TSRMLS_DC) +{ + zend_object_value retval; + spl_dir_object *intern; + zval *tmp; + + intern = emalloc(sizeof(spl_dir_object)); + memset(intern, 0, sizeof(spl_dir_object)); + intern->std.ce = class_type; + + 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, spl_dir_object_dtor, spl_dir_object_clone TSRMLS_CC); + retval.handlers = &spl_dir_handlers; + return retval; +} +/* }}} */ + +/* {{{ spl_dir_get_ce */ +static zend_class_entry *spl_dir_get_ce(zval *object TSRMLS_DC) +{ + return spl_ce_dir; +} +/* }}} */ + +/* {{{ PHP_MINIT_FUNCTION(spl_directory) */ +PHP_MINIT_FUNCTION(spl_directory) +{ + REGISTER_SPL_STD_CLASS_EX(dir, spl_dir_object_new, spl_dir_class_functions); + REGISTER_SPL_IMPLEMENT(dir, sequence); + memcpy(&spl_dir_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + spl_dir_handlers.get_class_entry = spl_dir_get_ce; + + return SUCCESS; +} +/* }}} */ + +/* {{{ proto void __construct(string path) + Cronstructs a new dir iterator from a path. */ +SPL_CLASS_FUNCTION(dir, __construct) +{ + zval *object = getThis(); + spl_dir_object *intern; + char *path; + long len; + +/* exceptions do not work yet + php_set_error_handling(EH_THROW, zend_exception_get_default() TSRMLS_CC);*/ + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) { + return; + } + + intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + intern->dirp = php_stream_opendir(path, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL); + + intern->path = estrdup(path); + + if (intern->dirp == NULL) { + /* throw exception: should've been already happened */ + intern->entry.d_name[0] = '\0'; + } else { + if (!php_stream_readdir(intern->dirp, &intern->entry)) { + intern->entry.d_name[0] = '\0'; + } + } + + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto void rewind() + Rewind dir back to the start */ +SPL_CLASS_FUNCTION(dir, rewind) +{ + zval *object = getThis(); + spl_dir_object *intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + + if (intern->dirp) { + php_stream_rewinddir(intern->dirp); + } + if (!intern->dirp || !php_stream_readdir(intern->dirp, &intern->entry)) { + intern->entry.d_name[0] = '\0'; + } +} +/* }}} */ + +/* {{{ proto string current() + Return current dir entry */ +SPL_CLASS_FUNCTION(dir, current) +{ + zval *object = getThis(); + spl_dir_object *intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + + if (intern->dirp) { + RETURN_STRING(intern->entry.d_name, 1); + } else { + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto void next() + Move to next entry */ +SPL_CLASS_FUNCTION(dir, next) +{ + zval *object = getThis(); + spl_dir_object *intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + + if (intern->dirp && php_stream_readdir(intern->dirp, &intern->entry)) { + RETURN_TRUE; + } else { + intern->entry.d_name[0] = '\0'; + RETURN_FALSE; + } +} +/* }}} */ + +/* {{{ proto string has_more() + Check whether dir contains more entries */ +SPL_CLASS_FUNCTION(dir, has_more) +{ + zval *object = getThis(); + spl_dir_object *intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + + RETURN_BOOL(intern->entry.d_name[0] != '\0'); +} +/* }}} */ + +/* {{{ proto string get_path() + Return directory path */ +SPL_CLASS_FUNCTION(dir, get_path) +{ + zval *object = getThis(); + spl_dir_object *intern = (spl_dir_object*)zend_object_store_get_object(object TSRMLS_CC); + + RETURN_STRING(intern->path, 1); +} +/* }}} */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 + */ diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index 8ad81a110f..c7d695913c 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -49,11 +49,11 @@ void spl_register_interface(zend_class_entry ** ppce, char * class_name TSRMLS_D /* }}} */ /* {{{ spl_register_std_class */ -void spl_register_std_class(zend_class_entry ** ppce, char * class_name, void * obj_ctor TSRMLS_DC) +void spl_register_std_class(zend_class_entry ** ppce, char * class_name, void * obj_ctor, function_entry * function_list TSRMLS_DC) { zend_class_entry ce; - INIT_CLASS_ENTRY(ce, class_name, NULL); + INIT_CLASS_ENTRY(ce, class_name, function_list); ce.name_length = strlen(class_name); *ppce = zend_register_internal_class(&ce TSRMLS_CC); diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index 1a9794e022..ae2431df3f 100755 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -24,7 +24,10 @@ typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type TSRMLS_DC); #define REGISTER_SPL_STD_CLASS(class_name, obj_ctor) \ - spl_register_std_class(&spl_ce_ ## class_name, "spl_" # class_name, obj_ctor TSRMLS_CC); + spl_register_std_class(&spl_ce_ ## class_name, "spl_" # class_name, obj_ctor, NULL TSRMLS_CC); + +#define REGISTER_SPL_STD_CLASS_EX(class_name, obj_ctor, funcs) \ + spl_register_std_class(&spl_ce_ ## class_name, "spl_" # class_name, obj_ctor, funcs TSRMLS_CC); #define REGISTER_SPL_INTERFACE(class_name) \ spl_register_interface(&spl_ce_ ## class_name, "spl_" # class_name TSRMLS_CC); @@ -43,7 +46,7 @@ typedef zend_object_value (*create_object_func_t)(zend_class_entry *class_type T void spl_destroy_class(zend_class_entry ** ppce); -void spl_register_std_class(zend_class_entry ** ppce, char * class_name, create_object_func_t ctor TSRMLS_DC); +void spl_register_std_class(zend_class_entry ** ppce, char * class_name, create_object_func_t ctor, function_entry * function_list TSRMLS_DC); void spl_register_interface(zend_class_entry ** ppce, char * class_name TSRMLS_DC); @@ -57,10 +60,10 @@ void spl_add_interfaces(zval * list, zend_class_entry * pce TSRMLS_DC); int spl_add_classes(zend_class_entry ** ppce, zval *list TSRMLS_DC); #define SPL_CLASS_FE(class_name, function_name, arg_types) \ - PHP_NAMED_FE( function_name, spl_ ## class_name ## function_name, arg_types) + PHP_NAMED_FE( function_name, spl_ ## class_name ## _ ## function_name, arg_types) #define SPL_CLASS_FUNCTION(class_name, function_name) \ - PHP_NAMED_FUNCTION(spl_ ## class_name ## function_name) + PHP_NAMED_FUNCTION(spl_ ## class_name ## _ ## function_name) #endif /* PHP_FUNCTIONS_H */ |