summaryrefslogtreecommitdiff
path: root/ext/spl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/spl')
-rwxr-xr-xext/spl/internal/cachingiterator.inc24
-rwxr-xr-xext/spl/spl_iterators.c27
-rwxr-xr-xext/spl/spl_sxe.c16
3 files changed, 54 insertions, 13 deletions
diff --git a/ext/spl/internal/cachingiterator.inc b/ext/spl/internal/cachingiterator.inc
index f5ca2c3..6391322 100755
--- a/ext/spl/internal/cachingiterator.inc
+++ b/ext/spl/internal/cachingiterator.inc
@@ -27,8 +27,10 @@
*/
class CachingIterator implements OuterIterator
{
- const CALL_TOSTRING = 1;
- const CATCH_GET_CHILD = 2;
+ const CALL_TOSTRING = 1;
+ const CATCH_GET_CHILD = 2;
+ const TOSTRING_USE_KEY = 4;
+ const TOSTRING_USE_CURRENT = 8;
private $it;
private $current;
@@ -44,8 +46,13 @@ class CachingIterator implements OuterIterator
*/
function __construct(Iterator $it, $flags = self::CALL_TOSTRING)
{
+ if ((($flags & self::CALL_TOSTRING) && ($flags & (self::TOSTRING_USE_KEY|self::TOSTRING_USE_CURRENT)))
+ || ((flags & (self::CIT_TOSTRING_USE_KEY|self::CIT_TOSTRING_USE_CURRENT)) == (self::CIT_TOSTRING_USE_KEY|self::CIT_TOSTRING_USE_CURRENT)))
+ {
+ throw new InvalidArgumentException('Flags must contain only one of CIT_CALL_TOSTRING, CIT_TOSTRING_USE_KEY, CIT_TOSTRING_USE_CURRENT');
+ }
$this->it = $it;
- $this->flags = $flags & (self::CALL_TOSTRING|self::CATCH_GET_CHILD);
+ $this->flags = $flags & (0x0000FFFF);
$this->next();
}
@@ -123,7 +130,16 @@ class CachingIterator implements OuterIterator
*/
function __toString()
{
- if (!$this->flags & self::CALL_TOSTRING) {
+ if ($this->flags & self::TOSTRING_USE_KEY)
+ {
+ return $this->key;
+ }
+ else if ($this->flags & self::TOSTRING_USE_CURRENT)
+ {
+ return $this->current;
+ }
+ if (!$this->flags & self::CALL_TOSTRING)
+ {
throw new exception('CachingIterator does not fetch string value (see CachingIterator::__construct)');
}
return $this->strValue;
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);
diff --git a/ext/spl/spl_sxe.c b/ext/spl/spl_sxe.c
index 5a2cd7e..5cf7c22 100755
--- a/ext/spl/spl_sxe.c
+++ b/ext/spl/spl_sxe.c
@@ -34,6 +34,7 @@
#include "spl_sxe.h"
zend_class_entry *spl_ce_SimpleXMLIterator = NULL;
+zend_class_entry *spl_ce_SimpleXMLElement;
#if HAVE_LIBXML && HAVE_SIMPLEXML
@@ -41,9 +42,10 @@ zend_class_entry *spl_ce_SimpleXMLIterator = NULL;
SPL_METHOD(SimpleXMLIterator, rewind) /* {{{ */
{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ php_sxe_iterator iter;
- php_sxe_reset_iterator(sxe TSRMLS_CC);
+ iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ spl_ce_SimpleXMLElement->iterator_funcs.funcs->rewind((zend_object_iterator*)&iter TSRMLS_CC);
}
/* }}} */
@@ -89,9 +91,10 @@ SPL_METHOD(SimpleXMLIterator, key) /* {{{ */
SPL_METHOD(SimpleXMLIterator, next) /* {{{ */
{
- php_sxe_object *sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ php_sxe_iterator iter;
- php_sxe_move_forward_iterator(sxe TSRMLS_CC);
+ iter.sxe = php_sxe_fetch_object(getThis() TSRMLS_CC);
+ spl_ce_SimpleXMLElement->iterator_funcs.funcs->move_forward((zend_object_iterator*)&iter TSRMLS_CC);
}
/* }}} */
@@ -146,16 +149,17 @@ static zend_function_entry spl_funcs_SimpleXMLIterator[] = {
SPL_API PHP_MINIT_FUNCTION(spl_sxe) /* {{{ */
{
- zend_class_entry **pce, *spl_ce_SimpleXMLElement;
+ zend_class_entry **pce;
if (zend_hash_find(CG(class_table), "simplexmlelement", sizeof("SimpleXMLElement"), (void **) &pce) == FAILURE) {
+ spl_ce_SimpleXMLElement = NULL;
spl_ce_SimpleXMLIterator = NULL;
return SUCCESS; /* SimpleXML must be initialized before */
}
spl_ce_SimpleXMLElement = *pce;
- REGISTER_SPL_SUB_CLASS_EX(SimpleXMLIterator, SimpleXMLElement, sxe_object_new, spl_funcs_SimpleXMLIterator);
+ REGISTER_SPL_SUB_CLASS_EX(SimpleXMLIterator, SimpleXMLElement, spl_ce_SimpleXMLElement->create_object, spl_funcs_SimpleXMLIterator);
REGISTER_SPL_IMPLEMENTS(SimpleXMLIterator, RecursiveIterator);
return SUCCESS;