summaryrefslogtreecommitdiff
path: root/ext/spl
diff options
context:
space:
mode:
authorJani Taskinen <jani@php.net>2007-11-02 19:40:39 +0000
committerJani Taskinen <jani@php.net>2007-11-02 19:40:39 +0000
commitb48925117750da2a7fb7cff629e3852d13917f2f (patch)
tree44671e4afbcd83803757998784821a6cc19007b5 /ext/spl
parent0d7479891444f46d1c30cf875037e5099f8f782b (diff)
downloadphp-git-b48925117750da2a7fb7cff629e3852d13917f2f.tar.gz
- MFH from HEAD:
. Folding tags . Parameter parsing . SPL debug info . array function improvements (not all yet) . Improvements to function calling with call_user_* functions . Improvements to debugging info in var_dump/print_r # I propably forgot already something but this all was pretty close tied # to each other so it wasn't possible to do it in parts.
Diffstat (limited to 'ext/spl')
-rwxr-xr-xext/spl/php_spl.c28
-rwxr-xr-xext/spl/php_spl.h2
-rwxr-xr-xext/spl/spl_array.c34
-rwxr-xr-xext/spl/spl_directory.c52
-rwxr-xr-xext/spl/spl_functions.c29
-rwxr-xr-xext/spl/spl_functions.h5
-rwxr-xr-xext/spl/spl_iterators.c29
-rwxr-xr-xext/spl/spl_observer.c38
8 files changed, 186 insertions, 31 deletions
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index cc88d91906..b4cd28144b 100755
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -19,7 +19,7 @@
/* $Id$ */
#ifdef HAVE_CONFIG_H
- #include "config.h"
+#include "config.h"
#endif
#include "php.h"
@@ -153,7 +153,7 @@ PHP_FUNCTION(class_implements)
/* }}} */
#define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \
- spl_add_classes(&spl_ce_ ## class_name, z_list, sub, allow, ce_flags TSRMLS_CC)
+ spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags TSRMLS_CC)
#define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \
SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \
@@ -607,26 +607,36 @@ PHP_FUNCTION(spl_autoload_functions)
PHP_FUNCTION(spl_object_hash)
{
zval *obj;
- int len;
- char *hash;
- char md5str[33];
- PHP_MD5_CTX context;
- unsigned char digest[16];
+ char* md5str;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
return;
}
+
+ md5str = emalloc(33);
+ php_spl_object_hash(obj, md5str TSRMLS_CC);
+
+ RETVAL_STRING(md5str, 0);
+}
+/* }}} */
+
+PHPAPI void php_spl_object_hash(zval *obj, char *md5str TSRMLS_DC) /* {{{*/
+{
+ int len;
+ char *hash;
+ PHP_MD5_CTX context;
+ unsigned char digest[16];
len = spprintf(&hash, 0, "%p:%d", Z_OBJ_HT_P(obj), Z_OBJ_HANDLE_P(obj));
-
+
md5str[0] = '\0';
PHP_MD5Init(&context);
PHP_MD5Update(&context, (unsigned char*)hash, len);
PHP_MD5Final(digest, &context);
make_digest(md5str, digest);
- RETVAL_STRING(md5str, 1);
efree(hash);
}
+/* }}} */
int spl_build_class_list_string(zval **entry, char **list TSRMLS_DC) /* {{{ */
{
diff --git a/ext/spl/php_spl.h b/ext/spl/php_spl.h
index 7c44f58550..e28578dcc1 100755
--- a/ext/spl/php_spl.h
+++ b/ext/spl/php_spl.h
@@ -74,6 +74,8 @@ PHP_FUNCTION(spl_classes);
PHP_FUNCTION(class_parents);
PHP_FUNCTION(class_implements);
+PHPAPI void php_spl_object_hash(zval *obj, char* md5str TSRMLS_DC);
+
#endif /* PHP_SPL_H */
/*
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index d9d7cd7e27..74e0999687 100755
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -614,6 +614,39 @@ static HashTable *spl_array_get_properties(zval *object TSRMLS_DC) /* {{{ */
return spl_array_get_hash_table(intern, 1 TSRMLS_CC);
} /* }}} */
+static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */
+{
+ spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(obj TSRMLS_CC);
+ HashTable *rv;
+ zval *tmp, *storage;
+ int name_len;
+ char *zname;
+ zend_class_entry *base;
+
+ if (HASH_OF(intern->array) == intern->std.properties) {
+ *is_temp = 0;
+ return intern->std.properties;
+ } else {
+ *is_temp = 1;
+
+ ALLOC_HASHTABLE(rv);
+ ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0);
+
+ zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
+ storage = intern->array;
+ zval_add_ref(&storage);
+
+ base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject;
+ zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC);
+ zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL);
+ efree(zname);
+
+ return rv;
+ }
+}
+/* }}} */
+
static zval *spl_array_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */
{
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
@@ -1514,6 +1547,7 @@ PHP_MINIT_FUNCTION(spl_array)
spl_handler_ArrayObject.count_elements = spl_array_object_count_elements;
spl_handler_ArrayObject.get_properties = spl_array_get_properties;
+ spl_handler_ArrayObject.get_debug_info = spl_array_get_debug_info;
spl_handler_ArrayObject.read_property = spl_array_read_property;
spl_handler_ArrayObject.write_property = spl_array_write_property;
spl_handler_ArrayObject.get_property_ptr_ptr = spl_array_get_property_ptr_ptr;
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index bf3eb83f5a..6ee18d335c 100755
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -459,6 +459,57 @@ static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */
}
/* }}} */
+static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{{ */
+{
+ spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(obj TSRMLS_CC);
+ HashTable *rv;
+ zval *tmp, zrv;
+ char *pnstr;
+ int pnlen;
+ char stmp[2];
+
+ *is_temp = 1;
+
+ ALLOC_HASHTABLE(rv);
+ ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 3, 0);
+
+ INIT_PZVAL(&zrv);
+ Z_ARRVAL(zrv) = rv;
+
+ zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
+ pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "pathName", sizeof("pathName")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->path, intern->path_len, 1);
+ efree(pnstr);
+ if (intern->file_name) {
+ pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "fileName", sizeof("fileName")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->file_name, intern->file_name_len, 1);
+ efree(pnstr);
+ }
+ if (intern->type == SPL_FS_DIR && intern->u.dir.sub_path) {
+ pnstr = spl_gen_private_prop_name(spl_ce_RecursiveDirectoryIterator, "subPathName", sizeof("subPathName")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
+ efree(pnstr);
+ }
+ if (intern->type == SPL_FS_FILE) {
+ pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "openMode", sizeof("openMode")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, intern->u.file.open_mode, intern->u.file.open_mode_len, 1);
+ efree(pnstr);
+ stmp[1] = '\0';
+ stmp[0] = intern->u.file.delimiter;
+ pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "delimiter", sizeof("delimiter")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1);
+ efree(pnstr);
+ stmp[0] = intern->u.file.enclosure;
+ pnstr = spl_gen_private_prop_name(spl_ce_SplFileObject, "enclosure", sizeof("enclosure")-1, &pnlen TSRMLS_CC);
+ add_assoc_stringl_ex(&zrv, pnstr, pnlen+1, stmp, 1, 1);
+ efree(pnstr);
+ }
+
+ return rv;
+}
+/* }}}} */
+
/* {{{ proto void DirectoryIterator::__construct(string path)
Cronstructs a new dir iterator from a path. */
SPL_METHOD(DirectoryIterator, __construct)
@@ -2349,6 +2400,7 @@ PHP_MINIT_FUNCTION(spl_directory)
memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
+ spl_filesystem_object_handlers.get_debug_info = spl_filesystem_object_get_debug_info;
REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions);
zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator);
diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c
index 31acfee436..16bda2fcec 100755
--- a/ext/spl/spl_functions.c
+++ b/ext/spl/spl_functions.c
@@ -40,8 +40,7 @@ void spl_register_interface(zend_class_entry ** ppce, char * class_name, const z
{
zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, class_name, functions);
- ce.name_length = strlen(class_name);
+ INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), functions);
*ppce = zend_register_internal_interface(&ce TSRMLS_CC);
}
/* }}} */
@@ -51,8 +50,7 @@ PHPAPI void spl_register_std_class(zend_class_entry ** ppce, char * class_name,
{
zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, class_name, function_list);
- ce.name_length = strlen(class_name);
+ INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), function_list);
*ppce = zend_register_internal_class(&ce TSRMLS_CC);
/* entries changed by initialize */
@@ -67,8 +65,7 @@ PHPAPI void spl_register_sub_class(zend_class_entry ** ppce, zend_class_entry *
{
zend_class_entry ce;
- INIT_CLASS_ENTRY(ce, class_name, function_list);
- ce.name_length = strlen(class_name);
+ INIT_CLASS_ENTRY_EX(ce, class_name, strlen(class_name), function_list);
*ppce = zend_register_internal_class_ex(&ce, parent_ce, NULL TSRMLS_CC);
/* entries changed by initialize */
@@ -105,12 +102,12 @@ void spl_register_property( zend_class_entry * class_entry, char *prop_name, int
void spl_add_class_name(zval *list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC)
{
if (!allow || (allow > 0 && pce->ce_flags & ce_flags) || (allow < 0 && !(pce->ce_flags & ce_flags))) {
- size_t len = strlen(pce->name);
+ size_t len = pce->name_length;
zval *tmp;
if (zend_hash_find(Z_ARRVAL_P(list), pce->name, len+1, (void*)&tmp) == FAILURE) {
MAKE_STD_ZVAL(tmp);
- ZVAL_STRING(tmp, pce->name, 1);
+ ZVAL_STRINGL(tmp, pce->name, pce->name_length, 1);
zend_hash_add(Z_ARRVAL_P(list), pce->name, len+1, &tmp, sizeof(zval *), NULL);
}
}
@@ -129,10 +126,8 @@ void spl_add_interfaces(zval *list, zend_class_entry * pce, int allow, int ce_fl
/* }}} */
/* {{{ spl_add_classes */
-int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC)
+int spl_add_classes(zend_class_entry *pce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC)
{
- zend_class_entry *pce = *ppce;
-
if (!pce) {
return 0;
}
@@ -141,13 +136,23 @@ int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, in
spl_add_interfaces(list, pce, allow, ce_flags TSRMLS_CC);
while (pce->parent) {
pce = pce->parent;
- spl_add_classes(&pce, list, sub, allow, ce_flags TSRMLS_CC);
+ spl_add_classes(pce, list, sub, allow, ce_flags TSRMLS_CC);
}
}
return 0;
}
/* }}} */
+char * spl_gen_private_prop_name(zend_class_entry *ce, char *prop_name, int prop_len, int *name_len TSRMLS_DC) /* {{{ */
+{
+ char *rv;
+
+ zend_mangle_property_name(&rv, name_len, ce->name, ce->name_length, prop_name, prop_len, 0);
+
+ return rv;
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h
index 0db207b754..5eab7f9f7c 100755
--- a/ext/spl/spl_functions.h
+++ b/ext/spl/spl_functions.h
@@ -73,7 +73,10 @@ void spl_register_property( zend_class_entry * class_entry, char *prop_name, int
*/
void spl_add_class_name(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC);
void spl_add_interfaces(zval * list, zend_class_entry * pce, int allow, int ce_flags TSRMLS_DC);
-int spl_add_classes(zend_class_entry ** ppce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC);
+int spl_add_classes(zend_class_entry *pce, zval *list, int sub, int allow, int ce_flags TSRMLS_DC);
+
+/* caller must efree(return) */
+char * spl_gen_private_prop_name(zend_class_entry *ce, char *prop_name, int prop_len, int *name_len TSRMLS_DC);
#define SPL_ME(class_name, function_name, arg_info, flags) \
PHP_ME( spl_ ## class_name, function_name, arg_info, flags)
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index 58bf8144f6..d806642132 100755
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -517,10 +517,16 @@ SPL_METHOD(RecursiveIteratorIterator, key)
char *str_key;
uint str_key_len;
ulong int_key;
- if (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC) == HASH_KEY_IS_LONG) {
- RETURN_LONG(int_key);
- } else {
- RETURN_STRINGL(str_key, str_key_len-1, 0);
+
+ switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
+ case HASH_KEY_IS_LONG:
+ RETURN_LONG(int_key);
+ break;
+ case HASH_KEY_IS_STRING:
+ RETURN_STRINGL(str_key, str_key_len-1, 0);
+ break;
+ default:
+ RETURN_NULL();
}
} else {
RETURN_NULL();
@@ -1126,7 +1132,7 @@ static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more T
intern->inner.iterator->funcs->get_current_data(intern->inner.iterator, &data TSRMLS_CC);
if (data && *data) {
intern->current.data = *data;
- Z_ADDREF_P(intern->current.data);
+ Z_ADDREF_P(intern->current.data);
}
if (intern->inner.iterator->funcs->get_current_key) {
intern->current.key_type = intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &intern->current.str_key, &intern->current.str_key_len, &intern->current.int_key TSRMLS_CC);
@@ -2364,10 +2370,15 @@ SPL_METHOD(NoRewindIterator, key)
char *str_key;
uint str_key_len;
ulong int_key;
- if (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC) == HASH_KEY_IS_LONG) {
- RETURN_LONG(int_key);
- } else {
- RETURN_STRINGL(str_key, str_key_len-1, 0);
+ switch (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
+ case HASH_KEY_IS_LONG:
+ RETURN_LONG(int_key);
+ break;
+ case HASH_KEY_IS_STRING:
+ RETURN_STRINGL(str_key, str_key_len-1, 0);
+ break;
+ default:
+ RETURN_NULL();
}
} else {
RETURN_NULL();
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index eeaac42bb8..f96e42b7e4 100755
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -116,6 +116,43 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type,
}
/* }}} */
+static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */
+{
+ spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
+ HashTable *rv, *props;
+ HashPosition pos;
+ zval *tmp, *storage, **entry;
+ char md5str[33];
+ int name_len;
+ char *zname;
+
+ *is_temp = 1;
+
+ props = Z_OBJPROP_P(obj);
+ ALLOC_HASHTABLE(rv);
+ ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(props) + 1, 0);
+
+ zend_hash_copy(rv, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
+ MAKE_STD_ZVAL(storage);
+ array_init(storage);
+
+ zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
+ while (zend_hash_get_current_data_ex(&intern->storage, (void **)&entry, &pos) == SUCCESS) {
+ php_spl_object_hash(*entry, md5str TSRMLS_CC);
+ zval_add_ref(entry);
+ add_assoc_zval_ex(storage, md5str, 33, *entry);
+ zend_hash_move_forward_ex(&intern->storage, &pos);
+ }
+
+ zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC);
+ zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL);
+ efree(zname);
+
+ return rv;
+}
+/* }}} */
+
/* {{{ spl_array_object_new */
static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC)
{
@@ -437,6 +474,7 @@ PHP_MINIT_FUNCTION(spl_observer)
REGISTER_SPL_STD_CLASS_EX(SplObjectStorage, spl_SplObjectStorage_new, spl_funcs_SplObjectStorage);
memcpy(&spl_handler_SplObjectStorage, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ spl_handler_SplObjectStorage.get_debug_info = spl_object_storage_debug_info;
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable);
REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator);