diff options
Diffstat (limited to 'ext/spl/spl_iterators.c')
-rwxr-xr-x | ext/spl/spl_iterators.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index c89b1eb..99e2641 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -764,6 +764,12 @@ static INLINE spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAME php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); return NULL; } + if (((flags & CIT_CALL_TOSTRING) && (flags & (CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT))) + || ((flags & (CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT)) == (CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT))) { + php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); + zend_throw_exception(spl_ce_InvalidArgumentException, "Flags must contain only one of CIT_CALL_TOSTRING, CIT_TOSTRING_USE_KEY, CIT_TOSTRING_USE_CURRENT", 0 TSRMLS_CC); + return NULL; + } intern->u.caching.flags |= flags & CIT_PUBLIC; break; } @@ -1517,9 +1523,22 @@ SPL_METHOD(CachingIterator, __toString) intern = (spl_dual_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC); - if (!(intern->u.caching.flags & CIT_CALL_TOSTRING)) { + if (!(intern->u.caching.flags & (CIT_CALL_TOSTRING|CIT_TOSTRING_USE_KEY|CIT_TOSTRING_USE_CURRENT))) { zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "%s does not fetch string value (see CachingIterator::__construct)", Z_OBJCE_P(getThis())->name); } + if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) { + if (intern->current.key_type == HASH_KEY_IS_STRING) { + RETURN_STRINGL(intern->current.str_key, intern->current.str_key_len, 1); + } else { + RETVAL_LONG(intern->current.int_key); + convert_to_string(return_value); + return; + } + } else if (intern->u.caching.flags & CIT_TOSTRING_USE_CURRENT) { + RETVAL_ZVAL(intern->current.data, 1, 0); + + return; + } if (intern->u.caching.zstr) { RETURN_STRINGL(Z_STRVAL_P(intern->u.caching.zstr), Z_STRLEN_P(intern->u.caching.zstr), 1); } else { @@ -2018,8 +2037,10 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_STD_CLASS_EX(CachingIterator, spl_dual_it_new, spl_funcs_CachingIterator); REGISTER_SPL_ITERATOR(CachingIterator); - REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); - REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "TOSTRING_USE_KEY", CIT_TOSTRING_USE_KEY); + REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "TOSTRING_USE_CURRENT", CIT_TOSTRING_USE_CURRENT); REGISTER_SPL_SUB_CLASS_EX(RecursiveCachingIterator, CachingIterator, spl_dual_it_new, spl_funcs_RecursiveCachingIterator); REGISTER_SPL_IMPLEMENTS(RecursiveCachingIterator, RecursiveIterator); |