<?php
-/** @file cachingrecursiveiterator.inc
+/** @file recursivecachingiterator.inc
* @ingroup SPL
- * @brief class CachingRecursiveIterator
+ * @brief class RecursiveCachingIterator
* @author Marcus Boerger
* @date 2003 - 2005
*
/**
* @brief Cached recursive iteration over another Iterator
* @author Marcus Boerger
- * @version 1.1
- * @since PHP 5.0
+ * @version 1.2
+ * @since PHP 5.1
*
* @see CachingIterator
*/
-class CachingRecursiveIterator extends CachingIterator implements RecursiveIterator
+class RecursiveCachingIterator extends CachingIterator implements RecursiveIterator
{
private $hasChildren;
private $getChildren;
*/
function next()
{
- if ($this->hasChildren = $this->it->hasChildren()) {
- try {
- //$this->getChildren = new CachingRecursiveIterator($this->it->getChildren(), $this->flags);
- // workaround memleaks...
+ if ($this->hasChildren = $this->it->hasChildren())
+ {
+ try
+ {
$child = $this->it->getChildren();
- $this->getChildren = new CachingRecursiveIterator($child, $this->flags);
+ if (!$this->ref)
+ {
+ $this->ref = new ReflectionClass($this);
+ }
+ $this->getChildren = $ref->newInstance($child, $this->flags);
}
- catch(Exception $e) {
- if (!$this->flags & self::CATCH_GET_CHILD) {
+ catch(Exception $e)
+ {
+ if (!$this->flags & self::CATCH_GET_CHILD)
+ {
throw $e;
}
$this->hasChildren = false;
$this->getChildren = NULL;
}
- } else {
+ } else
+ {
$this->getChildren = NULL;
}
parent::next();
}
+
+ private $ref;
/** @return whether the current element has children
* @note The check whether the Iterator for the children can be created was
SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \
- SPL_ADD_CLASS(CachingRecursiveIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(Countable, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \
+ SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \
+ SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \
- SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \
SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \
PHPAPI zend_class_entry *spl_ce_SeekableIterator;
PHPAPI zend_class_entry *spl_ce_LimitIterator;
PHPAPI zend_class_entry *spl_ce_CachingIterator;
-PHPAPI zend_class_entry *spl_ce_CachingRecursiveIterator;
+PHPAPI zend_class_entry *spl_ce_RecursiveCachingIterator;
PHPAPI zend_class_entry *spl_ce_OuterIterator;
PHPAPI zend_class_entry *spl_ce_IteratorIterator;
PHPAPI zend_class_entry *spl_ce_NoRewindIterator;
break;
}
case DIT_CachingIterator:
- case DIT_CachingRecursiveIterator: {
+ case DIT_RecursiveCachingIterator: {
long flags = CIT_CALL_TOSTRING;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|l", &zobject, ce_inner, &flags) == FAILURE) {
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
efree(intern->current.str_key);
intern->current.str_key = NULL;
}
- if (intern->dit_type == DIT_CachingIterator || intern->dit_type == DIT_CachingRecursiveIterator) {
+ if (intern->dit_type == DIT_CachingIterator || intern->dit_type == DIT_RecursiveCachingIterator) {
if (intern->u.caching.zstr) {
zval_ptr_dtor(&intern->u.caching.zstr);
intern->u.caching.zstr = NULL;
zval_ptr_dtor(&object->u.append.zarrayit);
}
- if (object->dit_type == DIT_CachingIterator || object->dit_type == DIT_CachingRecursiveIterator) {
+ if (object->dit_type == DIT_CachingIterator || object->dit_type == DIT_RecursiveCachingIterator) {
if (object->u.caching.zcache) {
zval_ptr_dtor(&object->u.caching.zcache);
object->u.caching.zcache = NULL;
}
}
/* Recursion ? */
- if (intern->dit_type == DIT_CachingRecursiveIterator) {
+ if (intern->dit_type == DIT_RecursiveCachingIterator) {
zval *retval, *zchildren, zflags;
zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval);
if (zend_is_true(retval)) {
} else {
INIT_PZVAL(&zflags);
ZVAL_LONG(&zflags, intern->u.caching.flags & CIT_PUBLIC);
- spl_instantiate_arg_ex2(U_CLASS_ENTRY(spl_ce_CachingRecursiveIterator), &intern->u.caching.zchildren, 1, zchildren, &zflags TSRMLS_CC);
+ spl_instantiate_arg_ex2(U_CLASS_ENTRY(spl_ce_RecursiveCachingIterator), &intern->u.caching.zchildren, 1, zchildren, &zflags TSRMLS_CC);
zval_ptr_dtor(&zchildren);
}
}
{NULL, NULL, NULL}
};
-/* {{{ proto CachingRecursiveIterator::__construct(RecursiveIterator it [, flags = CIT_CALL_TOSTRING])
+/* {{{ proto RecursiveCachingIterator::__construct(RecursiveIterator it [, flags = CIT_CALL_TOSTRING])
Create an iterator from a RecursiveIterator */
-SPL_METHOD(CachingRecursiveIterator, __construct)
+SPL_METHOD(RecursiveCachingIterator, __construct)
{
- spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, U_CLASS_ENTRY(spl_ce_RecursiveIterator), DIT_CachingRecursiveIterator);
+ spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, U_CLASS_ENTRY(spl_ce_RecursiveIterator), DIT_RecursiveCachingIterator);
} /* }}} */
-/* {{{ proto bolean CachingRecursiveIterator::hasChildren()
+/* {{{ proto bolean RecursiveCachingIterator::hasChildren()
Check whether the current element of the inner iterator has children */
-SPL_METHOD(CachingRecursiveIterator, hasChildren)
+SPL_METHOD(RecursiveCachingIterator, hasChildren)
{
spl_dual_it_object *intern;
RETURN_BOOL(intern->u.caching.zchildren);
} /* }}} */
-/* {{{ proto CachingRecursiveIterator CachingRecursiveIterator::getChildren()
- Return the inner iterator's children as a CachingRecursiveIterator */
-SPL_METHOD(CachingRecursiveIterator, getChildren)
+/* {{{ proto RecursiveCachingIterator RecursiveCachingIterator::getChildren()
+ Return the inner iterator's children as a RecursiveCachingIterator */
+SPL_METHOD(RecursiveCachingIterator, getChildren)
{
spl_dual_it_object *intern;
ZEND_ARG_INFO(0, flags)
ZEND_END_ARG_INFO();
-static zend_function_entry spl_funcs_CachingRecursiveIterator[] = {
- SPL_ME(CachingRecursiveIterator, __construct, arginfo_caching_rec_it___construct, ZEND_ACC_PUBLIC)
- SPL_ME(CachingRecursiveIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
- SPL_ME(CachingRecursiveIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
+static zend_function_entry spl_funcs_RecursiveCachingIterator[] = {
+ SPL_ME(RecursiveCachingIterator, __construct, arginfo_caching_rec_it___construct, ZEND_ACC_PUBLIC)
+ SPL_ME(RecursiveCachingIterator, hasChildren, NULL, ZEND_ACC_PUBLIC)
+ SPL_ME(RecursiveCachingIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD);
REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "FULL_CACHE", CIT_FULL_CACHE);
- REGISTER_SPL_SUB_CLASS_EX(CachingRecursiveIterator, CachingIterator, spl_dual_it_new, spl_funcs_CachingRecursiveIterator);
- REGISTER_SPL_IMPLEMENTS(CachingRecursiveIterator, RecursiveIterator);
+ REGISTER_SPL_SUB_CLASS_EX(RecursiveCachingIterator, CachingIterator, spl_dual_it_new, spl_funcs_RecursiveCachingIterator);
+ REGISTER_SPL_IMPLEMENTS(RecursiveCachingIterator, RecursiveIterator);
REGISTER_SPL_STD_CLASS_EX(IteratorIterator, spl_dual_it_new, spl_funcs_IteratorIterator);
REGISTER_SPL_ITERATOR(IteratorIterator);