summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xext/spl/config.m42
-rwxr-xr-xext/spl/php_spl.c2
-rwxr-xr-xext/spl/php_spl.h2
-rwxr-xr-xext/spl/spl_directory.c242
-rwxr-xr-xext/spl/spl_functions.c4
-rwxr-xr-xext/spl/spl_functions.h11
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 */