helly Sun May 21 17:27:12 2006 UTC Added files: /php-src/ext/spl/tests iterator_043.phpt iterator_044.phpt iterator_045.phpt iterator_046.phpt iterator_047.phpt iterator_048.phpt
Modified files: /php-src/ext/spl spl_iterators.c spl_iterators.h Log: - Make code exception safe - Make RecursiveRegexIterator::getChildren pass regex to inner ctor - Fix CachingIterator::__toString() in TOSTRING_USE_KEY mode - Add CachingIterator::getCache() - Add tests
http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_iterators.c?r1=1.132&r2=1.133&diff_format=u Index: php-src/ext/spl/spl_iterators.c diff -u php-src/ext/spl/spl_iterators.c:1.132 php-src/ext/spl/spl_iterators.c:1.133 --- php-src/ext/spl/spl_iterators.c:1.132 Sun May 21 12:42:00 2006 +++ php-src/ext/spl/spl_iterators.c Sun May 21 17:27:12 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.c,v 1.132 2006/05/21 12:42:00 helly Exp $ */ +/* $Id: spl_iterators.c,v 1.133 2006/05/21 17:27:12 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -193,6 +193,13 @@ switch (object->iterators[object->level].state) { case RS_NEXT: iterator->funcs->move_forward(iterator TSRMLS_CC); + if (EG(exception)) { + if (!(object->flags & RIT_CATCH_GET_CHILD)) { + return; + } else { + zend_clear_exception(TSRMLS_C); + } + } case RS_START: if (iterator->funcs->valid(iterator TSRMLS_CC) == FAILURE) { break; @@ -207,6 +214,14 @@ } else { zend_call_method_with_0_params(&zobject, ce, NULL, "haschildren", &retval); } + if (EG(exception)) { + if (!(object->flags & RIT_CATCH_GET_CHILD)) { + object->iterators[object->level].state = RS_NEXT; + return; + } else { + zend_clear_exception(TSRMLS_C); + } + } if (retval) { has_children = zend_is_true(retval); zval_ptr_dtor(&retval); @@ -235,6 +250,13 @@ zend_call_method_with_0_params(&zthis, object->ce, &object->nextElement, "nextelement", NULL); } object->iterators[object->level].state = RS_NEXT; + if (EG(exception)) { + if (!(object->flags & RIT_CATCH_GET_CHILD)) { + return; + } else { + zend_clear_exception(TSRMLS_C); + } + } return /* self */; case RS_SELF: if (object->nextElement && (object->mode == RIT_SELF_FIRST || object->mode == RIT_CHILD_FIRST)) { @@ -292,6 +314,13 @@ } if (object->beginChildren) { zend_call_method_with_0_params(&zthis, object->ce, &object->beginChildren, "beginchildren", NULL); + if (EG(exception)) { + if (!(object->flags & RIT_CATCH_GET_CHILD)) { + return; + } else { + zend_clear_exception(TSRMLS_C); + } + } } goto next_step; } @@ -299,6 +328,13 @@ if (object->level > 0) { if (object->endChildren) { zend_call_method_with_0_params(&zthis, object->ce, &object->endChildren, "endchildren", NULL); + if (EG(exception)) { + if (!(object->flags & RIT_CATCH_GET_CHILD)) { + return; + } else { + zend_clear_exception(TSRMLS_C); + } + } } iterator->funcs->dtor(iterator TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level].zobject); @@ -317,7 +353,7 @@ sub_iter = object->iterators[object->level].iterator; sub_iter->funcs->dtor(sub_iter TSRMLS_CC); zval_ptr_dtor(&object->iterators[object->level--].zobject); - if (!object->endChildren || object->endChildren->common.scope != spl_ce_RecursiveIteratorIterator) { + if (!EG(exception) && (!object->endChildren || object->endChildren->common.scope != spl_ce_RecursiveIteratorIterator)) { zend_call_method_with_0_params(&zthis, object->ce, &object->endChildren, "endchildren", NULL); } } @@ -327,7 +363,7 @@ if (sub_iter->funcs->rewind) { sub_iter->funcs->rewind(sub_iter TSRMLS_CC); } - if (object->beginIteration && !object->in_iteration) { + if (!EG(exception) && object->beginIteration && !object->in_iteration) { zend_call_method_with_0_params(&zthis, object->ce, &object->beginIteration, "beginIteration", NULL); } object->in_iteration = 1; @@ -582,7 +618,11 @@ RETURN_FALSE; } else { zend_call_method_with_0_params(&zobject, ce, NULL, "haschildren", &retval); - RETURN_ZVAL(retval, 0, 1); + if (retval) { + RETURN_ZVAL(retval, 0, 1); + } else { + RETURN_FALSE; + } } } /* }}} */ @@ -934,6 +974,13 @@ } if (instanceof_function(ce, zend_ce_aggregate TSRMLS_CC)) { zend_call_method_with_0_params(&zobject, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval); + if (EG(exception)) { + if (retval) { + zval_ptr_dtor(&retval); + } + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + return NULL; + } if (!retval || Z_TYPE_P(retval) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(retval), zend_ce_traversable TSRMLS_CC)) { zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "%v::getIterator() must return an object that implememnts Traversable", ce->name); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); @@ -964,6 +1011,7 @@ php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); return NULL; } + intern->u.regex.regex = estrndup(regex, len); intern->u.regex.pce = pcre_get_compiled_regex_cache(regex, len, &extra, &poptions, &coptions TSRMLS_CC); intern->u.regex.pce->refcount++; break;; @@ -1252,7 +1300,11 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); - RETURN_ZVAL(retval, 0, 1); + if (retval) { + RETURN_ZVAL(retval, 0, 1); + } else { + RETURN_FALSE; + } } /* }}} */ /* {{{ proto RecursiveFilterIterator RecursiveFilterIterator::getChildren() @@ -1265,8 +1317,10 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); - zval_ptr_dtor(&retval); + if (!EG(exception)) { + spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); + zval_ptr_dtor(&retval); + } } /* }}} */ /* {{{ proto void ParentIterator::__construct(RecursiveIterator it) @@ -1286,7 +1340,11 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "haschildren", &retval); - RETURN_ZVAL(retval, 0, 1); + if (retval) { + RETURN_ZVAL(retval, 0, 1); + } else { + RETURN_FALSE; + } } /* }}} */ /* {{{ proto ParentIterator ParentIterator::getChildren() @@ -1299,8 +1357,10 @@ intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); - spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); - zval_ptr_dtor(&retval); + if (retval) { + spl_instantiate_arg_ex1(Z_OBJCE_P(getThis()), &return_value, 0, retval TSRMLS_CC); + zval_ptr_dtor(&retval); + } } /* }}} */ #if HAVE_PCRE || HAVE_BUNDLED_PCRE @@ -1360,6 +1420,28 @@ { spl_dual_it_construct(INTERNAL_FUNCTION_PARAM_PASSTHRU, spl_ce_RecursiveRegexIterator, spl_ce_RecursiveIterator, DIT_RecursiveRegexIterator); } /* }}} */ + +/* {{{ proto RecursiveRegexIterator RecursiveRegexIterator::getChildren() + Return the inner iterator's children contained in a RecursiveRegexIterator */ +SPL_METHOD(RecursiveRegexIterator, getChildren) +{ + spl_dual_it_object *intern; + zval *retval, *regex; + + intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &retval); + if (!EG(exception)) { + MAKE_STD_ZVAL(regex); + ZVAL_STRING(regex, intern->u.regex.regex, 1); + spl_instantiate_arg_ex2(Z_OBJCE_P(getThis()), &return_value, 0, retval, regex TSRMLS_CC); + zval_ptr_dtor(®ex); + } + if (retval) { + zval_ptr_dtor(&retval); + } +} /* }}} */ + #endif /* {{{ spl_dual_it_free_storage */ @@ -1396,6 +1478,9 @@ if (object->u.regex.pce) { object->u.regex.pce->refcount--; } + if (object->u.regex.regex) { + efree(object->u.regex.regex); + } } #endif @@ -1488,7 +1573,7 @@ static zend_function_entry spl_funcs_RecursiveRegexIterator[] = { SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC) SPL_ME(ParentIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(ParentIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveRegexIterator, getChildren, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; #endif @@ -1522,9 +1607,11 @@ spl_dual_it_free(intern TSRMLS_CC); zend_call_method_with_1_params(&intern->inner.zobject, intern->inner.ce, NULL, "seek", NULL, zpos); zval_ptr_dtor(&zpos); - intern->current.pos = pos; - if (spl_limit_it_valid(intern TSRMLS_CC) == SUCCESS) { - spl_dual_it_fetch(intern, 0 TSRMLS_CC); + if (!EG(exception)) { + intern->current.pos = pos; + if (spl_limit_it_valid(intern TSRMLS_CC) == SUCCESS) { + spl_dual_it_fetch(intern, 0 TSRMLS_CC); + } } } else { /* emulate the forward seek, by next() calls */ @@ -1675,25 +1762,43 @@ 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)) { - zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); - if (EG(exception)) { - if (zchildren) { + if (EG(exception)) { + if (retval) { + zval_ptr_dtor(&retval); + } + if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) { + zend_clear_exception(TSRMLS_C); + } else { + return; + } + } else { + if (zend_is_true(retval)) { + zend_call_method_with_0_params(&intern->inner.zobject, intern->inner.ce, NULL, "getchildren", &zchildren); + if (EG(exception)) { + if (zchildren) { + zval_ptr_dtor(&zchildren); + } + if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) { + zend_clear_exception(TSRMLS_C); + } else { + return; + } + } else { + INIT_PZVAL(&zflags); + ZVAL_LONG(&zflags, intern->u.caching.flags & CIT_PUBLIC); + spl_instantiate_arg_ex2(spl_ce_RecursiveCachingIterator, &intern->u.caching.zchildren, 1, zchildren, &zflags TSRMLS_CC); zval_ptr_dtor(&zchildren); } + } + zval_ptr_dtor(&retval); + if (EG(exception)) { if (intern->u.caching.flags & CIT_CATCH_GET_CHILD) { zend_clear_exception(TSRMLS_C); } else { return; } - } else { - INIT_PZVAL(&zflags); - ZVAL_LONG(&zflags, intern->u.caching.flags & CIT_PUBLIC); - spl_instantiate_arg_ex2(spl_ce_RecursiveCachingIterator, &intern->u.caching.zchildren, 1, zchildren, &zflags TSRMLS_CC); - zval_ptr_dtor(&zchildren); } } - zval_ptr_dtor(&retval); } if (intern->u.caching.flags & (CIT_TOSTRING_USE_INNER|CIT_CALL_TOSTRING)) { int use_copy; @@ -1796,9 +1901,9 @@ } if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) { if (intern->current.key_type == HASH_KEY_IS_STRING) { - RETURN_STRINGL(intern->current.str_key.s, intern->current.str_key_len, 1); + RETURN_STRINGL(intern->current.str_key.s, intern->current.str_key_len-1, 1); } else if (intern->current.key_type == HASH_KEY_IS_UNICODE) { - RETURN_UNICODEL(intern->current.str_key.u, intern->current.str_key_len, 1); + RETURN_UNICODEL(intern->current.str_key.u, intern->current.str_key_len-1, 1); } else { RETVAL_LONG(intern->current.int_key); convert_to_text(return_value); @@ -1832,6 +1937,7 @@ if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Tz", &arKey, &nKeyLength, &type, &value) == FAILURE) { @@ -1857,6 +1963,7 @@ if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "T", &arKey, &nKeyLength, &type) == FAILURE) { @@ -1885,6 +1992,7 @@ if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "T", &arKey, &nKeyLength, &type) == FAILURE) { @@ -1908,6 +2016,7 @@ if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; } if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "T", &arKey, &nKeyLength, &type) == FAILURE) { @@ -1918,6 +2027,23 @@ } /* }}} */ +/* {{{ proto bool CachingIterator::getCache() + Return the cache */ +SPL_METHOD(CachingIterator, getCache) +{ + spl_dual_it_object *intern; + + intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (!(intern->u.caching.flags & CIT_FULL_CACHE)) { + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%v does not use a full cache (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); + return; + } + + RETURN_ZVAL(intern->u.caching.zcache, 1, 0); +} +/* }}} */ + /* {{{ proto int CachingIterator::getFlags() Return the internal flags */ SPL_METHOD(CachingIterator, getFlags) @@ -2001,6 +2127,7 @@ SPL_ME(CachingIterator, offsetSet, arginfo_caching_it_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetUnset, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetExists, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, getCache, NULL, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/spl_iterators.h?r1=1.34&r2=1.35&diff_format=u Index: php-src/ext/spl/spl_iterators.h diff -u php-src/ext/spl/spl_iterators.h:1.34 php-src/ext/spl/spl_iterators.h:1.35 --- php-src/ext/spl/spl_iterators.h:1.34 Sat May 20 13:23:00 2006 +++ php-src/ext/spl/spl_iterators.h Sun May 21 17:27:12 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.h,v 1.34 2006/05/20 13:23:00 helly Exp $ */ +/* $Id: spl_iterators.h,v 1.35 2006/05/21 17:27:12 helly Exp $ */ #ifndef SPL_ITERATORS_H #define SPL_ITERATORS_H @@ -130,6 +130,7 @@ struct { int flags; pcre_cache_entry *pce; + char *regex; } regex; #endif } u; http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_043.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_043.phpt +++ php-src/ext/spl/tests/iterator_043.phpt --TEST-- SPL: RecursiveCachingIterator and uninitialized getChildren() --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php $it = new RecursiveCachingIterator(new RecursiveArrayIterator(array(1,2))); var_dump($it->getChildren()); $it->rewind(); var_dump($it->getChildren()); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- NULL NULL ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_044.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_044.phpt +++ php-src/ext/spl/tests/iterator_044.phpt --TEST-- SPL: CachingIterator and offsetGet/Exists using flag FULL_CACHE --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyFoo { function __toString() { return 'foo'; } } class MyCachingIterator extends CachingIterator { function __construct(Iterator $it, $flags = 0) { parent::__construct($it, $flags); } function test($ar) { foreach($ar as $k => $v) { echo "===$k===\n"; var_dump($v); var_dump($this->offsetExists($v)); var_dump($this->offsetGet($v)); } } } $it = new MyCachingIterator(new ArrayIterator(array(0, 'foo'=>1, 2, 'bar'=>3, 4))); try { var_dump($it->offsetExists(0)); } catch(Exception $e) { echo "Exception: " . $e->getMessage() . "\n"; } try { var_dump($it->offsetGet(0)); } catch(Exception $e) { echo "Exception: " . $e->getMessage() . "\n"; } $it = new MyCachingIterator(new ArrayIterator(array(0, 'foo'=>1, 2, 'bar'=>3, 4)), CachingIterator::FULL_CACHE); var_dump($it->offsetExists()); var_dump($it->offsetGet()); $checks = array(0, new stdClass, new MyFoo, NULL, 2, 'foo', 3); $it->test($checks); echo "===FILL===\n"; foreach($it as $v); // read all into cache $it->test($checks); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Warning: CachingIterator::offsetExists() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d NULL ===0=== int(0) bool(false) Notice: Undefined index: 0 in %siterator_044.php on line %d NULL ===1=== object(stdClass)#%d (0) { } Warning: CachingIterator::offsetExists() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL ===2=== object(MyFoo)#%d (0) { } bool(false) Notice: Undefined index: foo in %siterator_044.php on line %d NULL ===3=== NULL bool(false) Notice: Undefined index: in %siterator_044.php on line %d NULL ===4=== int(2) bool(false) Notice: Undefined index: 2 in %siterator_044.php on line %d NULL ===5=== string(3) "foo" bool(false) Notice: Undefined index: foo in %siterator_044.php on line %d NULL ===6=== int(3) bool(false) Notice: Undefined index: 3 in %siterator_044.php on line %d NULL ===FILL=== ===0=== int(0) bool(true) int(0) ===1=== object(stdClass)#1 (0) { } Warning: CachingIterator::offsetExists() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL ===2=== object(MyFoo)#2 (0) { } bool(true) int(1) ===3=== NULL bool(false) Notice: Undefined index: in %siterator_044.php on line %d NULL ===4=== int(2) bool(true) int(4) ===5=== string(3) "foo" bool(true) int(1) ===6=== int(3) bool(false) Notice: Undefined index: 3 in %siterator_044.php on line %d NULL ===DONE=== --UEXPECTF-- Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Warning: CachingIterator::offsetExists() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects exactly 1 parameter, 0 given in %s/iterator_044.php on line %d NULL ===0=== int(0) bool(false) Notice: Undefined index: 0 in %siterator_044.php on line %d NULL ===1=== object(stdClass)#%d (0) { } Warning: CachingIterator::offsetExists() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL ===2=== object(MyFoo)#%d (0) { } bool(false) Notice: Undefined index: foo in %siterator_044.php on line %d NULL ===3=== NULL bool(false) Notice: Undefined index: in %siterator_044.php on line %d NULL ===4=== int(2) bool(false) Notice: Undefined index: 2 in %siterator_044.php on line %d NULL ===5=== unicode(3) "foo" bool(false) Notice: Undefined index: foo in %siterator_044.php on line %d NULL ===6=== int(3) bool(false) Notice: Undefined index: 3 in %siterator_044.php on line %d NULL ===FILL=== ===0=== int(0) bool(true) int(0) ===1=== object(stdClass)#1 (0) { } Warning: CachingIterator::offsetExists() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL Warning: CachingIterator::offsetGet() expects parameter 1 to be string (Unicode or binary), object given in %siterator_044.php on line %d NULL ===2=== object(MyFoo)#2 (0) { } bool(true) int(1) ===3=== NULL bool(false) Notice: Undefined index: in %siterator_044.php on line %d NULL ===4=== int(2) bool(true) int(4) ===5=== unicode(3) "foo" bool(true) int(1) ===6=== int(3) bool(false) Notice: Undefined index: 3 in %siterator_044.php on line %d NULL ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_045.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_045.phpt +++ php-src/ext/spl/tests/iterator_045.phpt --TEST-- SPL: CachingIterator and offsetSet/Unset, getCache using flag FULL_CACHE --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyFoo { function __toString() { return 'foo'; } } class MyCachingIterator extends CachingIterator { function __construct(Iterator $it, $flags = 0) { parent::__construct($it, $flags); } function testSet($ar) { echo __METHOD__ . "()\n"; foreach($ar as $k => $v) { echo "set($k,$v)\n"; $this->offsetSet($k, $v); } } function testUnset($ar) { echo __METHOD__ . "()\n"; foreach($ar as $k => $v) { echo "unset($v)\n"; $this->offsetUnset($v); } } function fill() { echo __METHOD__ . "()\n"; foreach($this as $v) ; } function show() { echo __METHOD__ . "()\n"; var_dump($this->getCache()); } } $it = new MyCachingIterator(new ArrayIterator(array(0, 'foo'=>1, 2, 'bar'=>3, 4))); try { var_dump($it->offsetSet(0, 0)); } catch(Exception $e) { echo "Exception: " . $e->getMessage() . "\n"; } try { var_dump($it->offsetUnset(0)); } catch(Exception $e) { echo "Exception: " . $e->getMessage() . "\n"; } $it = new MyCachingIterator(new ArrayIterator(array(0, 1, 2, 3)), CachingIterator::FULL_CACHE); var_dump($it->offsetSet()); var_dump($it->offsetSet(0)); var_dump($it->offsetUnset()); $checks = array(0 => 25, 1 => 42, 3 => 'FooBar'); $unsets = array(0, 2); $it->testSet($checks); $it->show(); $it->testUnset($unsets); $it->show(); $it->fill(); $it->show(); $it->testSet($checks); $it->show(); $it->testUnset($unsets); $it->show(); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Warning: CachingIterator::offsetSet() expects exactly 2 parameters, 0 given in %siterator_045.php on line %d NULL Warning: CachingIterator::offsetSet() expects exactly 2 parameters, 1 given in %siterator_045.php on line %d NULL Warning: CachingIterator::offsetUnset() expects exactly 1 parameter, 0 given in %siterator_045.php on line %d NULL MyCachingIterator::testSet() set(0,25) set(1,42) set(3,FooBar) MyCachingIterator::show() array(3) { [0]=> int(25) [1]=> int(42) [3]=> string(6) "FooBar" } MyCachingIterator::testUnset() unset(0) unset(2) MyCachingIterator::show() array(2) { [1]=> int(42) [3]=> string(6) "FooBar" } MyCachingIterator::fill() MyCachingIterator::show() array(4) { [0]=> int(0) [1]=> int(1) [2]=> int(2) [3]=> int(3) } MyCachingIterator::testSet() set(0,25) set(1,42) set(3,FooBar) MyCachingIterator::show() array(4) { [0]=> int(25) [1]=> int(42) [2]=> int(2) [3]=> string(6) "FooBar" } MyCachingIterator::testUnset() unset(0) unset(2) MyCachingIterator::show() array(2) { [1]=> int(42) [3]=> string(6) "FooBar" } ===DONE=== --UEXPECTF-- Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct) Warning: CachingIterator::offsetSet() expects exactly 2 parameters, 0 given in %siterator_045.php on line %d NULL Warning: CachingIterator::offsetSet() expects exactly 2 parameters, 1 given in %siterator_045.php on line %d NULL Warning: CachingIterator::offsetUnset() expects exactly 1 parameter, 0 given in %siterator_045.php on line %d NULL MyCachingIterator::testSet() set(0,25) set(1,42) set(3,FooBar) MyCachingIterator::show() array(3) { [0]=> int(25) [1]=> int(42) [3]=> unicode(6) "FooBar" } MyCachingIterator::testUnset() unset(0) unset(2) MyCachingIterator::show() array(2) { [1]=> int(42) [3]=> unicode(6) "FooBar" } MyCachingIterator::fill() MyCachingIterator::show() array(4) { [0]=> int(0) [1]=> int(1) [2]=> int(2) [3]=> int(3) } MyCachingIterator::testSet() set(0,25) set(1,42) set(3,FooBar) MyCachingIterator::show() array(4) { [0]=> int(25) [1]=> int(42) [2]=> int(2) [3]=> unicode(6) "FooBar" } MyCachingIterator::testUnset() unset(0) unset(2) MyCachingIterator::show() array(2) { [1]=> int(42) [3]=> unicode(6) "FooBar" } ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_046.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_046.phpt +++ php-src/ext/spl/tests/iterator_046.phpt --TEST-- SPL: CachingIterator and __toString using bypassed string keys --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyFoo { function __toString() { return 'foo'; } } class MyCachingIterator extends CachingIterator { function __construct(Iterator $it, $flags = 0) { parent::__construct($it, $flags); } function fill() { echo __METHOD__ . "()\n"; foreach($this as $v) ; } function show() { echo __METHOD__ . "()\n"; foreach($this as $v) { var_dump((string)$this); } } } $it = new MyCachingIterator(new ArrayIterator(array(0, 'foo'=>1, 'bar'=>2)), CachingIterator::TOSTRING_USE_KEY); $it->fill(); $it->show(); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- MyCachingIterator::fill() MyCachingIterator::show() string(1) "0" string(3) "foo" string(3) "bar" ===DONE=== --UEXPECTF-- MyCachingIterator::fill() MyCachingIterator::show() unicode(1) "0" unicode(3) "foo" unicode(3) "bar" ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_047.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_047.phpt +++ php-src/ext/spl/tests/iterator_047.phpt --TEST-- SPL: RecursiveCachingIterator and exception in has/getChildren --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyRecursiveArrayIterator extends RecursiveArrayIterator { static public $fail = 0; static function fail($state, $method) { if (self::$fail == $state) { throw new Exception("State $state: $method()"); } } function hasChildren() { echo __METHOD__ . "()\n"; self::fail(1, __METHOD__); return parent::hasChildren(); } function getChildren() { echo __METHOD__ . "()\n"; self::fail(2, __METHOD__); return parent::getChildren(); } } class MyRecursiveCachingIterator extends RecursiveCachingIterator { function show() { MyRecursiveArrayIterator::$fail = 0; while(MyRecursiveArrayIterator::$fail < 4) { echo "===" . MyRecursiveArrayIterator::$fail . "===\n"; try { foreach(new RecursiveIteratorIterator($this) as $k => $v) { var_dump($k); var_dump($v); } } catch (Exception $e) { echo "Exception: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n"; } MyRecursiveArrayIterator::$fail++; } } } $it = new MyRecursiveArrayIterator(array(0, array(10), 2, array(30), 4)); $it = new MyRecursiveCachingIterator($it); $it->show(); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- ===0=== MyRecursiveArrayIterator::hasChildren() int(0) int(0) MyRecursiveArrayIterator::hasChildren() MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::hasChildren() int(0) int(10) MyRecursiveArrayIterator::hasChildren() int(2) int(2) MyRecursiveArrayIterator::hasChildren() MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::hasChildren() int(0) int(30) MyRecursiveArrayIterator::hasChildren() int(4) int(4) ===1=== MyRecursiveArrayIterator::hasChildren() Exception: State 1: MyRecursiveArrayIterator::hasChildren() in %siterator_047.php on line %d ===2=== MyRecursiveArrayIterator::hasChildren() int(0) int(0) MyRecursiveArrayIterator::hasChildren() MyRecursiveArrayIterator::getChildren() Exception: State 2: MyRecursiveArrayIterator::getChildren() in %siterator_047.php on line %d ===3=== MyRecursiveArrayIterator::hasChildren() int(0) int(0) MyRecursiveArrayIterator::hasChildren() MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::hasChildren() int(0) int(10) MyRecursiveArrayIterator::hasChildren() int(2) int(2) MyRecursiveArrayIterator::hasChildren() MyRecursiveArrayIterator::getChildren() MyRecursiveArrayIterator::hasChildren() int(0) int(30) MyRecursiveArrayIterator::hasChildren() int(4) int(4) ===DONE=== http://cvs.php.net/viewcvs.cgi/php-src/ext/spl/tests/iterator_048.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/iterator_048.phpt +++ php-src/ext/spl/tests/iterator_048.phpt --TEST-- SPL: RecursiveCachingIterator and exception in has/getChildren --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class MyRecursiveRegexIterator extends RecursiveRegexIterator { function show() { foreach(new RecursiveIteratorIterator($this) as $k => $v) { var_dump($k); var_dump($v); } } function accept() { return $this->hasChildren() || parent::accept(); } } $ar = new RecursiveArrayIterator(array('Foo', array('Bar'), 'FooBar', array('Baz'), 'Biz')); $it = new MyRecursiveRegexIterator($ar, '/Bar/'); $it->show(); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- int(0) string(3) "Bar" int(2) string(6) "FooBar" ===DONE=== --UEXPECTF-- int(0) unicode(3) "Bar" int(2) unicode(6) "FooBar" ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php