summaryrefslogtreecommitdiff
path: root/ext/spl/spl_iterators.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl/spl_iterators.c')
-rwxr-xr-xext/spl/spl_iterators.c58
1 files changed, 46 insertions, 12 deletions
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index daf228496..f55a199fd 100755
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: spl_iterators.c 293036 2010-01-03 09:23:27Z sebastian $ */
+/* $Id: spl_iterators.c 301065 2010-07-07 22:46:54Z felipe $ */
#ifdef HAVE_CONFIG_H
# include "config.h"
@@ -131,7 +131,7 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
spl_recursive_it_object *object = (spl_recursive_it_object*)_iter->data;
zend_object_iterator *sub_iter;
- while (object->level) {
+ while (object->level > 0) {
sub_iter = object->iterators[object->level].iterator;
sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
zval_ptr_dtor(&object->iterators[object->level--].zobject);
@@ -139,10 +139,10 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator));
object->level = 0;
- zval_ptr_dtor(&iter->zobject);
+ zval_ptr_dtor(&iter->zobject);
efree(iter);
}
-
+
static int spl_recursive_it_valid_ex(spl_recursive_it_object *object, zval *zthis TSRMLS_DC)
{
zend_object_iterator *sub_iter;
@@ -536,6 +536,18 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
intern->iterators[0].state = RS_START;
zend_restore_error_handling(&error_handling TSRMLS_CC);
+
+ if (EG(exception)) {
+ zend_object_iterator *sub_iter;
+
+ while (intern->level >= 0) {
+ sub_iter = intern->iterators[intern->level].iterator;
+ sub_iter->funcs->dtor(sub_iter TSRMLS_CC);
+ zval_ptr_dtor(&intern->iterators[intern->level--].zobject);
+ }
+ efree(intern->iterators);
+ intern->iterators = NULL;
+ }
}
/* {{{ proto void RecursiveIteratorIterator::__construct(RecursiveIterator|IteratorAggregate it [, int mode = RIT_LEAVES_ONLY [, int flags = 0]]) throws InvalidArgumentException
@@ -778,11 +790,14 @@ static union _zend_function *spl_recursive_it_get_method(zval **object_ptr, char
}
/* {{{ spl_RecursiveIteratorIterator_dtor */
-static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+static void spl_RecursiveIteratorIterator_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
{
spl_recursive_it_object *object = (spl_recursive_it_object *)_object;
zend_object_iterator *sub_iter;
+ /* call standard dtor */
+ zend_objects_destroy_object(_object, handle TSRMLS_CC);
+
if (object->iterators) {
while (object->level >= 0) {
sub_iter = object->iterators[object->level].iterator;
@@ -792,6 +807,13 @@ static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
efree(object->iterators);
object->iterators = NULL;
}
+}
+/* }}} */
+
+/* {{{ spl_RecursiveIteratorIterator_dtor */
+static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
+{
+ spl_recursive_it_object *object = (spl_recursive_it_object *)_object;
zend_object_std_dtor(&object->std TSRMLS_CC);
smart_str_free(&object->prefix[0]);
@@ -827,7 +849,7 @@ static zend_object_value spl_RecursiveIteratorIterator_new_ex(zend_class_entry *
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
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_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
+ retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_RecursiveIteratorIterator_dtor, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC);
retval.handlers = &spl_handlers_rec_it_it;
return retval;
}
@@ -1272,7 +1294,7 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
return NULL;
}
if (intern->u.limit.offset < 0) {
- zend_throw_exception(spl_ce_OutOfRangeException, "Parameter offset must be > 0", 0 TSRMLS_CC);
+ zend_throw_exception(spl_ce_OutOfRangeException, "Parameter offset must be >= 0", 0 TSRMLS_CC);
zend_restore_error_handling(&error_handling TSRMLS_CC);
return NULL;
}
@@ -1909,16 +1931,26 @@ SPL_METHOD(RecursiveRegexIterator, getChildren)
#endif
-/* {{{ spl_dual_it_free_storage */
-static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+/* {{{ spl_dual_it_dtor */
+static void spl_dual_it_dtor(zend_object *_object, zend_object_handle handle TSRMLS_DC)
{
spl_dual_it_object *object = (spl_dual_it_object *)_object;
+ /* call standard dtor */
+ zend_objects_destroy_object(_object, handle TSRMLS_CC);
+
spl_dual_it_free(object TSRMLS_CC);
if (object->inner.iterator) {
object->inner.iterator->funcs->dtor(object->inner.iterator TSRMLS_CC);
}
+}
+/* }}} */
+
+/* {{{ spl_dual_it_free_storage */
+static void spl_dual_it_free_storage(void *_object TSRMLS_DC)
+{
+ spl_dual_it_object *object = (spl_dual_it_object *)_object;
if (object->inner.zobject) {
zval_ptr_dtor(&object->inner.zobject);
@@ -1969,7 +2001,7 @@ static zend_object_value spl_dual_it_new(zend_class_entry *class_type TSRMLS_DC)
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
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_dual_it_free_storage, NULL TSRMLS_CC);
+ retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)spl_dual_it_dtor, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC);
retval.handlers = &spl_handlers_dual_it;
return retval;
}
@@ -2080,7 +2112,7 @@ static inline void spl_limit_it_seek(spl_dual_it_object *intern, long pos TSRMLS
zend_throw_exception_ex(spl_ce_OutOfBoundsException, 0 TSRMLS_CC, "Cannot seek to %ld which is behind offset %ld plus count %ld", pos, intern->u.limit.offset, intern->u.limit.count);
return;
}
- if (instanceof_function(intern->inner.ce, spl_ce_SeekableIterator TSRMLS_CC)) {
+ if (pos != intern->current.pos && instanceof_function(intern->inner.ce, spl_ce_SeekableIterator TSRMLS_CC)) {
MAKE_STD_ZVAL(zpos);
ZVAL_LONG(zpos, pos);
spl_dual_it_free(intern TSRMLS_CC);
@@ -3035,7 +3067,9 @@ PHPAPI int spl_iterator_apply(zval *obj, spl_iterator_apply_func_t apply_func, v
}
done:
- iter->funcs->dtor(iter TSRMLS_CC);
+ if (iter) {
+ iter->funcs->dtor(iter TSRMLS_CC);
+ }
return EG(exception) ? FAILURE : SUCCESS;
}
/* }}} */