- Iterator API was changed

This commit is contained in:
Marcus Boerger 2006-02-05 23:31:47 +00:00
parent ea00c7597f
commit c67d8b2152
7 changed files with 83 additions and 27 deletions

View file

@ -2177,10 +2177,14 @@ static int pdo_stmt_iter_valid(zend_object_iterator *iter TSRMLS_DC)
return I->fetch_ahead ? SUCCESS : FAILURE; return I->fetch_ahead ? SUCCESS : FAILURE;
} }
static void pdo_stmt_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) static void pdo_stmt_iter_get_data(zend_object_iterator *iter, zval ***data, int by_ref TSRMLS_DC)
{ {
struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data; struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
/* sanity */ /* sanity */
if (!I->fetch_ahead) { if (!I->fetch_ahead) {
*data = NULL; *data = NULL;
@ -2237,11 +2241,15 @@ static zend_object_iterator_funcs pdo_stmt_iter_funcs = {
NULL NULL
}; };
zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC) zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{ {
pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC); pdo_stmt_t *stmt = (pdo_stmt_t*)zend_object_store_get_object(object TSRMLS_CC);
struct php_pdo_iterator *I; struct php_pdo_iterator *I;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
I = ecalloc(1, sizeof(*I)); I = ecalloc(1, sizeof(*I));
I->iter.funcs = &pdo_stmt_iter_funcs; I->iter.funcs = &pdo_stmt_iter_funcs;
I->iter.data = I; I->iter.data = I;

View file

@ -42,7 +42,7 @@ extern zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC);
extern zend_function_entry pdo_dbstmt_functions[]; extern zend_function_entry pdo_dbstmt_functions[];
extern zend_class_entry *pdo_dbstmt_ce; extern zend_class_entry *pdo_dbstmt_ce;
void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC); void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC);
zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object TSRMLS_DC); zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
extern zend_object_handlers pdo_dbstmt_object_handlers; extern zend_object_handlers pdo_dbstmt_object_handlers;
int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC); int pdo_stmt_describe_columns(pdo_stmt_t *stmt TSRMLS_DC);
int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg); int pdo_stmt_setup_fetch_mode(INTERNAL_FUNCTION_PARAMETERS, pdo_stmt_t *stmt, int skip_first_arg);

View file

@ -1769,9 +1769,14 @@ static xmlNodePtr php_sxe_reset_iterator(php_sxe_object *sxe, int use_data TSRML
return NULL; return NULL;
} }
zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) zend_object_iterator *php_sxe_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{ {
php_sxe_iterator *iterator = emalloc(sizeof(php_sxe_iterator)); php_sxe_iterator *iterator;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
iterator = emalloc(sizeof(php_sxe_iterator));
object->refcount++; object->refcount++;
iterator->intern.data = (void*)object; iterator->intern.data = (void*)object;

View file

@ -757,10 +757,27 @@ zend_object_iterator_funcs spl_array_it_funcs = {
spl_array_it_rewind spl_array_it_rewind
}; };
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) /* {{{ */ zend_object_iterator *spl_array_obj_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
{ {
spl_array_it *iterator = emalloc(sizeof(spl_array_it)); /* disable by_ref check */
spl_array_object *array_object = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC); /* We enable by ref if the returned thing does. If it is an ArrayIterator */
/* or derived then it does if it's current() method is not overloaded. */
return zend_user_it_get_new_iterator(ce, object, 0 TSRMLS_CC);
}
/* }}} */
zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
{
spl_array_it *iterator;
spl_array_object *array_object;
#if MBO_0
if (by_ref && /* check current() is overloaded, else it works */) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
#endif
iterator = emalloc(sizeof(spl_array_it));
array_object = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
object->refcount++; object->refcount++;
iterator->intern.data = (void*)object; iterator->intern.data = (void*)object;
@ -1392,6 +1409,8 @@ PHP_MINIT_FUNCTION(spl_array)
REGISTER_SPL_IMPLEMENTS(ArrayObject, Aggregate); REGISTER_SPL_IMPLEMENTS(ArrayObject, Aggregate);
REGISTER_SPL_IMPLEMENTS(ArrayObject, ArrayAccess); REGISTER_SPL_IMPLEMENTS(ArrayObject, ArrayAccess);
memcpy(&spl_handler_ArrayObject, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); memcpy(&spl_handler_ArrayObject, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
spl_ce_ArrayObject->get_iterator = spl_array_obj_get_iterator;
spl_handler_ArrayObject.clone_obj = spl_array_object_clone; spl_handler_ArrayObject.clone_obj = spl_array_object_clone;
spl_handler_ArrayObject.read_dimension = spl_array_read_dimension; spl_handler_ArrayObject.read_dimension = spl_array_read_dimension;
spl_handler_ArrayObject.write_dimension = spl_array_write_dimension; spl_handler_ArrayObject.write_dimension = spl_array_write_dimension;

View file

@ -963,10 +963,16 @@ zend_object_iterator_funcs spl_filesystem_dir_it_funcs = {
}; };
/* {{{ spl_ce_dir_get_iterator */ /* {{{ spl_ce_dir_get_iterator */
zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{ {
spl_filesystem_dir_it *iterator = emalloc(sizeof(spl_filesystem_dir_it)); spl_filesystem_dir_it *iterator;
spl_filesystem_object *dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); spl_filesystem_object *dir_object;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
iterator = emalloc(sizeof(spl_filesystem_dir_it));
dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
object->refcount += 2;; object->refcount += 2;;
iterator->intern.data = (void*)object; iterator->intern.data = (void*)object;
@ -1168,10 +1174,16 @@ zend_object_iterator_funcs spl_filesystem_tree_it_funcs = {
}; };
/* {{{ spl_ce_dir_get_iterator */ /* {{{ spl_ce_dir_get_iterator */
zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{ {
spl_filesystem_dir_it *iterator = emalloc(sizeof(spl_filesystem_dir_it)); spl_filesystem_dir_it *iterator;
spl_filesystem_object *dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC); spl_filesystem_object *dir_object;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
iterator = emalloc(sizeof(spl_filesystem_dir_it));
dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
object->refcount++; object->refcount++;
iterator->intern.data = (void*)object; iterator->intern.data = (void*)object;

View file

@ -278,7 +278,7 @@ next_step:
object->iterators[object->level].state = RS_NEXT; object->iterators[object->level].state = RS_NEXT;
} }
object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator) * (++object->level+1)); object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator) * (++object->level+1));
sub_iter = ce->get_iterator(ce, child TSRMLS_CC); sub_iter = ce->get_iterator(ce, child, 0 TSRMLS_CC);
object->iterators[object->level].iterator = sub_iter; object->iterators[object->level].iterator = sub_iter;
object->iterators[object->level].zobject = child; object->iterators[object->level].zobject = child;
object->iterators[object->level].ce = ce; object->iterators[object->level].ce = ce;
@ -340,10 +340,16 @@ static void spl_recursive_it_rewind(zend_object_iterator *iter TSRMLS_DC)
spl_recursive_it_rewind_ex((spl_recursive_it_object*)iter->data, ((spl_recursive_it_iterator*)iter)->zobject TSRMLS_CC); spl_recursive_it_rewind_ex((spl_recursive_it_object*)iter->data, ((spl_recursive_it_iterator*)iter)->zobject TSRMLS_CC);
} }
static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, zval *zobject TSRMLS_DC) static zend_object_iterator *spl_recursive_it_get_iterator(zend_class_entry *ce, zval *zobject, int by_ref TSRMLS_DC)
{ {
spl_recursive_it_iterator *iterator = emalloc(sizeof(spl_recursive_it_iterator)); spl_recursive_it_iterator *iterator;
spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(zobject TSRMLS_CC); spl_recursive_it_object *object;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
iterator = emalloc(sizeof(spl_recursive_it_iterator));
object = (spl_recursive_it_object*)zend_object_store_get_object(zobject TSRMLS_CC);
zobject->refcount++; zobject->refcount++;
iterator->intern.data = (void*)object; iterator->intern.data = (void*)object;
@ -430,7 +436,7 @@ SPL_METHOD(RecursiveIteratorIterator, __construct)
intern->nextElement = NULL; intern->nextElement = NULL;
} }
ce_iterator = Z_OBJCE_P(iterator); /* respect inheritance, don't use spl_ce_RecursiveIterator */ ce_iterator = Z_OBJCE_P(iterator); /* respect inheritance, don't use spl_ce_RecursiveIterator */
intern->iterators[0].iterator = ce_iterator->get_iterator(ce_iterator, iterator TSRMLS_CC); intern->iterators[0].iterator = ce_iterator->get_iterator(ce_iterator, iterator, 0 TSRMLS_CC);
if (inc_refcount) { if (inc_refcount) {
iterator->refcount++; iterator->refcount++;
} }
@ -918,7 +924,7 @@ static inline spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAME
case DIT_AppendIterator: case DIT_AppendIterator:
spl_instantiate(U_CLASS_ENTRY(spl_ce_ArrayIterator), &intern->u.append.zarrayit, 1 TSRMLS_CC); spl_instantiate(U_CLASS_ENTRY(spl_ce_ArrayIterator), &intern->u.append.zarrayit, 1 TSRMLS_CC);
zend_call_method_with_0_params(&intern->u.append.zarrayit, U_CLASS_ENTRY(spl_ce_ArrayIterator), &U_CLASS_ENTRY(spl_ce_ArrayIterator)->constructor, "__construct", NULL); zend_call_method_with_0_params(&intern->u.append.zarrayit, U_CLASS_ENTRY(spl_ce_ArrayIterator), &U_CLASS_ENTRY(spl_ce_ArrayIterator)->constructor, "__construct", NULL);
intern->u.append.iterator = U_CLASS_ENTRY(spl_ce_ArrayIterator)->get_iterator(U_CLASS_ENTRY(spl_ce_ArrayIterator), intern->u.append.zarrayit TSRMLS_CC); intern->u.append.iterator = U_CLASS_ENTRY(spl_ce_ArrayIterator)->get_iterator(U_CLASS_ENTRY(spl_ce_ArrayIterator), intern->u.append.zarrayit, 0 TSRMLS_CC);
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
return intern; return intern;
#if HAVE_PCRE || HAVE_BUNDLED_PCRE #if HAVE_PCRE || HAVE_BUNDLED_PCRE
@ -954,7 +960,7 @@ static inline spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAME
intern->inner.zobject = zobject; intern->inner.zobject = zobject;
intern->inner.ce = dit_type == DIT_IteratorIterator ? ce : Z_OBJCE_P(zobject); intern->inner.ce = dit_type == DIT_IteratorIterator ? ce : Z_OBJCE_P(zobject);
intern->inner.object = zend_object_store_get_object(zobject TSRMLS_CC); intern->inner.object = zend_object_store_get_object(zobject TSRMLS_CC);
intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, zobject TSRMLS_CC); intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, zobject, 0 TSRMLS_CC);
php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC); php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
return intern; return intern;
@ -2209,7 +2215,7 @@ int spl_append_it_next_iterator(spl_dual_it_object *intern TSRMLS_DC) /* {{{*/
intern->inner.zobject = *it; intern->inner.zobject = *it;
intern->inner.ce = Z_OBJCE_PP(it); intern->inner.ce = Z_OBJCE_PP(it);
intern->inner.object = zend_object_store_get_object(*it TSRMLS_CC); intern->inner.object = zend_object_store_get_object(*it TSRMLS_CC);
intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, *it TSRMLS_CC); intern->inner.iterator = intern->inner.ce->get_iterator(intern->inner.ce, *it, 0 TSRMLS_CC);
spl_dual_it_rewind(intern TSRMLS_CC); spl_dual_it_rewind(intern TSRMLS_CC);
return SUCCESS; return SUCCESS;
} else { } else {
@ -2362,7 +2368,7 @@ PHP_FUNCTION(iterator_to_array)
array_init(return_value); array_init(return_value);
iter = Z_OBJCE_P(obj)->get_iterator(Z_OBJCE_P(obj), obj TSRMLS_CC); iter = Z_OBJCE_P(obj)->get_iterator(Z_OBJCE_P(obj), obj, 0 TSRMLS_CC);
if (iter->funcs->rewind) { if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC); iter->funcs->rewind(iter TSRMLS_CC);
@ -2406,7 +2412,7 @@ PHP_FUNCTION(iterator_count)
RETURN_FALSE; RETURN_FALSE;
} }
iter = Z_OBJCE_P(obj)->get_iterator(Z_OBJCE_P(obj), obj TSRMLS_CC); iter = Z_OBJCE_P(obj)->get_iterator(Z_OBJCE_P(obj), obj, 0 TSRMLS_CC);
if (iter->funcs->rewind) { if (iter->funcs->rewind) {
iter->funcs->rewind(iter TSRMLS_CC); iter->funcs->rewind(iter TSRMLS_CC);

View file

@ -239,10 +239,16 @@ zend_object_iterator_funcs text_iter_cp_funcs = {
text_iter_rewind, text_iter_rewind,
}; };
static zend_object_iterator* text_iter_get_iterator(zend_class_entry *ce, zval *object TSRMLS_DC) static zend_object_iterator* text_iter_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
{ {
text_iter_it* iterator = emalloc(sizeof(text_iter_it)); text_iter_it* iterator;
text_iter_obj* iter_object = (text_iter_obj *) zend_object_store_get_object(object TSRMLS_CC); text_iter_obj* iter_object;
if (by_ref) {
zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
}
iterator = emalloc(sizeof(text_iter_it));
iter_object = (text_iter_obj *) zend_object_store_get_object(object TSRMLS_CC);
ZVAL_ADDREF(object); ZVAL_ADDREF(object);
iterator->intern.data = (void *) object; iterator->intern.data = (void *) object;