]> granicus.if.org Git - php/commitdiff
Refactored spl_filesystem_iterator
authorXinchen Hui <laruence@gmail.com>
Fri, 28 Feb 2014 09:43:19 +0000 (17:43 +0800)
committerXinchen Hui <laruence@gmail.com>
Fri, 28 Feb 2014 11:07:54 +0000 (19:07 +0800)
ext/spl/spl_directory.c
ext/spl/spl_directory.h
ext/spl/spl_iterators.c

index 604aca7e81e889e6506cde5df36aaf7ef6037f0b..46855ef957e80950378119810dfbc9b5a0033c3b 100644 (file)
@@ -123,15 +123,10 @@ static void spl_filesystem_object_free_storage(zend_object *object TSRMLS_DC) /*
                break;
        }
 
-       {
-               zend_object_iterator *iterator;
-               iterator = (zend_object_iterator*)
-                               spl_filesystem_object_to_iterator(intern);
-               if (!ZVAL_IS_UNDEF(&iterator->data)) {
-                       ZVAL_UNDEF(&iterator->data);
-                       zend_iterator_dtor(iterator TSRMLS_CC);
-               }
-       }
+       //???if (intern->it) {
+       //zend_iterator_dtor(intern->it TSRMLS_CC);
+       //}
+
        efree(object);
 } /* }}} */
 
@@ -158,9 +153,8 @@ static zend_object *spl_filesystem_object_new_ex(zend_class_entry *class_type TS
 
        zend_object_std_init(&intern->std, class_type TSRMLS_CC);
        object_properties_init(&intern->std, class_type);
-       zend_iterator_init(&intern->it.intern TSRMLS_CC);
-
        intern->std.handlers = &spl_filesystem_object_handlers;
+
        return &intern->std;
 }
 /* }}} */
@@ -635,7 +629,7 @@ static HashTable *spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T
                if (intern->u.dir.sub_path) {
                        ZVAL_STRINGL(&tmp, intern->u.dir.sub_path, intern->u.dir.sub_path_len);
                } else {
-                       ZVAL_STRINGL(&tmp, "", 0);
+                       ZVAL_STR(&tmp, STR_EMPTY_ALLOC());
                }
                zend_symtable_update(rv, pnstr, &tmp);
                STR_RELEASE(pnstr);
@@ -1646,16 +1640,11 @@ zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval
        }
        dir_object = (spl_filesystem_object*)Z_OBJ_P(object);
        iterator = spl_filesystem_object_to_iterator(dir_object);
-
-       Z_ADDREF_P(object);
-       /* initialize iterator if it wasn't gotten before */
-       if (ZVAL_IS_UNDEF(&iterator->intern.data)) {
-               ZVAL_COPY_VALUE(&iterator->intern.data, object);
-               iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
-               /* ->current must be initialized; rewind doesn't set it and valid
-                * doesn't check whether it's set */
-               iterator->current = *object;
-       }
+       ZVAL_COPY(&iterator->intern.data, object);
+       iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
+       /* ->current must be initialized; rewind doesn't set it and valid
+        * doesn't check whether it's set */
+       iterator->current = *object;
        
        return &iterator->intern;
 }
@@ -1670,6 +1659,7 @@ static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
                zval *object = &iterator->intern.data;
                zval_ptr_dtor(object);
        }
+       efree(iter);
        /* Otherwise we were called from the owning object free storage handler as
         * it sets
         * iterator->intern.data to NULL.
@@ -1849,14 +1839,10 @@ zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zva
                zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
        }
        dir_object = (spl_filesystem_object*)Z_OBJ_P(object);
-       iterator   = spl_filesystem_object_to_iterator(dir_object);
+       iterator = spl_filesystem_object_to_iterator(dir_object);
 
-       Z_ADDREF_P(object);
-       /* initialize iterator if wasn't gotten before */
-       if (ZVAL_IS_UNDEF(&iterator->intern.data)) {
-               ZVAL_COPY_VALUE(&iterator->intern.data, object);
-               iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
-       }
+       ZVAL_COPY(&iterator->intern.data, object);
+       iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
        
        return &iterator->intern;
 }
index 0ce7815d42f941a03c122a69785eed103d8937dd..72c701d117997114e26f1e6dfdc667e8771af3b3 100644 (file)
@@ -56,6 +56,7 @@ typedef struct _spl_other_handler {
 typedef struct {
        zend_object_iterator  intern;
        zval                  current;
+       void                 *object;
 } spl_filesystem_iterator;
 
 struct _spl_filesystem_object {
@@ -101,17 +102,24 @@ struct _spl_filesystem_object {
                        char               escape;
                } file;
        } u;
-       spl_filesystem_iterator    it;
+       spl_filesystem_iterator    *it;
 };
 
-static inline spl_filesystem_iterator* spl_filesystem_object_to_iterator(spl_filesystem_object *obj)
+static inline spl_filesystem_iterator* spl_filesystem_object_to_iterator(spl_filesystem_object *obj TSRMLS_DC)
 {
-       return &obj->it;
+       if (obj->it) {
+               zend_iterator_dtor(&obj->it->intern TSRMLS_CC);
+       }
+
+       obj->it = ecalloc(1, sizeof(spl_filesystem_iterator));
+       obj->it->object = (void *)obj;
+       zend_iterator_init(&obj->it->intern TSRMLS_CC);
+       return obj->it;
 }
 
-static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_filesystem_iterator *it)
+static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_filesystem_iterator *it TSRMLS_DC)
 {
-       return (spl_filesystem_object*)((char*)it - XtOffsetOf(spl_filesystem_object, it));
+       return (spl_filesystem_object*)it->object;
 }
 
 #define SPL_FILE_OBJECT_DROP_NEW_LINE      0x00000001 /* drop new lines */
index dccf508e7e766e9f0707400a958e6a698f63c199..be2f26670984174e7558099c302f83acc7ef1c79 100644 (file)
@@ -325,9 +325,8 @@ next_step:
                                }
                                object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator) * (++object->level+1));
                                sub_iter = ce->get_iterator(ce, &child, 0 TSRMLS_CC);
-                               Z_ADDREF(child);
+                               ZVAL_COPY(&object->iterators[object->level].zobject, &child);
                                object->iterators[object->level].iterator = sub_iter;
-                               object->iterators[object->level].zobject = child;
                                object->iterators[object->level].ce = ce;
                                object->iterators[object->level].state = RS_START;
                                if (sub_iter->funcs->rewind) {
@@ -839,7 +838,7 @@ static union _zend_function *spl_recursive_it_get_method(zval *object_ptr, zend_
        if (!function_handler) {
                if ((function_handler = zend_hash_find_ptr(&Z_OBJCE_P(zobj)->function_table, method)) == NULL) {
                        if (Z_OBJ_HT_P(zobj)->get_method) {
-                               object_ptr = zobj;
+                               *object_ptr = *zobj;
                                function_handler = Z_OBJ_HT_P(object_ptr)->get_method(object_ptr, method, key TSRMLS_CC);
                        }
                }