Patch impl-54587 for SPL related Bug #54587
Patch version 2011-04-21 14:49 UTC
Return to Bug #54587 |
Download this patch
Patch Revisions:
Developer: jinmoku@hotmail.com
Index: ext/spl/spl_iterators.c
===================================================================
--- ext/spl/spl_iterators.c (revision 310425)
+++ ext/spl/spl_iterators.c (working copy)
@@ -117,6 +115,7 @@
zend_function *nextElement;
zend_class_entry *ce;
smart_str prefix[6];
+ smart_str postfix[6];
} spl_recursive_it_object;
typedef struct _spl_recursive_it_iterator {
@@ -911,6 +878,12 @@
smart_str_free(&object->prefix[3]);
smart_str_free(&object->prefix[4]);
smart_str_free(&object->prefix[5]);
+ smart_str_free(&object->postfix[0]);
+ smart_str_free(&object->postfix[1]);
+ smart_str_free(&object->postfix[2]);
+ smart_str_free(&object->postfix[3]);
+ smart_str_free(&object->postfix[4]);
+ smart_str_free(&object->postfix[5]);
efree(object);
}
@@ -934,8 +908,17 @@
smart_str_appendl(&intern->prefix[5], "", 0);
}
+ if (init_prefix) {
+ smart_str_appendl(&intern->postfix[0], "", 0);
+ smart_str_appendl(&intern->postfix[1], "", 0);
+ smart_str_appendl(&intern->postfix[2], "", 0);
+ smart_str_appendl(&intern->postfix[3], "", 0);
+ smart_str_appendl(&intern->postfix[4], "", 0);
+ smart_str_appendl(&intern->postfix[5], "", 0);
+ }
+
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
@@ -1051,7 +1034,37 @@
static void spl_recursive_tree_iterator_get_postfix(spl_recursive_it_object * object, zval * return_value TSRMLS_DC)
{
- RETVAL_STRINGL("", 0, 1);
+ smart_str str = {0};
+ zval *has_next;
+ int level;
+
+ smart_str_appendl(&str, object->postfix[0].c, object->postfix[0].len);
+
+ for (level = 0; level < object->level; ++level) {
+ zend_call_method_with_0_params(&object->iterators[level].zobject, object->iterators[level].ce, NULL, "hasnext", &has_next);
+ if (has_next) {
+ if (Z_LVAL_P(has_next)) {
+ smart_str_appendl(&str, object->postfix[1].c, object->postfix[1].len);
+ } else {
+ smart_str_appendl(&str, object->postfix[2].c, object->postfix[2].len);
+ }
+ zval_ptr_dtor(&has_next);
+ }
+ }
+ zend_call_method_with_0_params(&object->iterators[level].zobject, object->iterators[level].ce, NULL, "hasnext", &has_next);
+ if (has_next) {
+ if (Z_LVAL_P(has_next)) {
+ smart_str_appendl(&str, object->postfix[3].c, object->postfix[3].len);
+ } else {
+ smart_str_appendl(&str, object->postfix[4].c, object->postfix[4].len);
+ }
+ zval_ptr_dtor(&has_next);
+ }
+
+ smart_str_appendl(&str, object->postfix[5].c, object->postfix[5].len);
+ smart_str_0(&str);
+
+ RETVAL_STRINGL(str.c, str.len, 0);
}
/* {{{ proto void RecursiveTreeIterator::__construct(RecursiveIterator|IteratorAggregate it [, int flags = RTIT_BYPASS_KEY [, int cit_flags = CIT_CATCH_GET_CHILD [, mode = RIT_SELF_FIRST ]]]) throws InvalidArgumentException
@@ -1107,6 +1120,27 @@
spl_recursive_tree_iterator_get_entry(object, return_value TSRMLS_CC);
} /* }}} */
+/* {{{ proto void RecursiveTreeIterator::setPostfixPart(int part, string postfix) throws OutOfRangeException
+ Sets postfix parts as used in getPostfix() */
+SPL_METHOD(RecursiveTreeIterator, setPostfixPart)
+{
+ spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ long part;
+ char* postfix;
+ int postfix_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &part, &postfix, &postfix_len) == FAILURE) {
+ return;
+ }
+ if (0 > part || part > 5) {
+ zend_throw_exception_ex(spl_ce_OutOfRangeException, 0 TSRMLS_CC, "Use RecursiveTreeIterator::PREFIX_* constant");
+ return;
+ }
+
+ smart_str_free(&object->postfix[part]);
+ smart_str_appendl(&object->postfix[part], postfix, postfix_len);
+} /* }}} */
+
/* {{{ proto string RecursiveTreeIterator::getPostfix()
Returns the string to place after the current element */
SPL_METHOD(RecursiveTreeIterator, getPostfix)
@@ -1250,6 +1284,11 @@
ZEND_ARG_INFO(0, value)
ZEND_END_ARG_INFO();
+ZEND_BEGIN_ARG_INFO_EX(arginfo_recursive_tree_it_setPostfixPart, 0, 0, 2)
+ ZEND_ARG_INFO(0, part)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO();
+
static const zend_function_entry spl_funcs_RecursiveTreeIterator[] = {
SPL_ME(RecursiveTreeIterator, __construct, arginfo_recursive_tree_it___construct, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveIteratorIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
@@ -1268,6 +1307,7 @@
SPL_ME(RecursiveTreeIterator, setPrefixPart, arginfo_recursive_tree_it_setPrefixPart, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveTreeIterator, getEntry, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveTreeIterator, getPostfix, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
+ SPL_ME(RecursiveTreeIterator, setPostfixPart, arginfo_recursive_tree_it_setPostfixPart, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
@@ -3735,6 +3630,12 @@
REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "PREFIX_END_HAS_NEXT", 3);
REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "PREFIX_END_LAST", 4);
REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "PREFIX_RIGHT", 5);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_LEFT", 0);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_MID_HAS_NEXT", 1);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_MID_LAST", 2);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_END_HAS_NEXT", 3);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_END_LAST", 4);
+ REGISTER_SPL_CLASS_CONST_LONG(RecursiveTreeIterator, "POSTFIX_RIGHT", 5);
return SUCCESS;
}
|