From: Andrei Zmievski Date: Sat, 4 Feb 2006 00:23:52 +0000 (+0000) Subject: Abstract the iterator interface so that we can add new types. X-Git-Tag: RELEASE_1_2~293 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4a3bf22b811ec9245239002cf1039608becfafb6;p=php Abstract the iterator interface so that we can add new types. --- diff --git a/ext/unicode/unicode_iterators.c b/ext/unicode/unicode_iterators.c index aeef2df723..dc4feb0c12 100644 --- a/ext/unicode/unicode_iterators.c +++ b/ext/unicode/unicode_iterators.c @@ -34,8 +34,15 @@ typedef struct { uint32_t text_len; text_iter_type type; zval* current; - int32_t offset; - int32_t index; + union { + struct { + int32_t offset; + int32_t index; + } cp; + struct { + int32_t index; + } cu; + } u; } text_iter_obj; typedef struct { @@ -43,17 +50,30 @@ typedef struct { text_iter_obj* object; } text_iter_it; +typedef struct { + int (*valid) (text_iter_obj* object TSRMLS_DC); + void (*current)(text_iter_obj* object TSRMLS_DC); + int (*key) (text_iter_obj* object TSRMLS_DC); + void (*next) (text_iter_obj* object TSRMLS_DC); + void (*rewind) (text_iter_obj* object TSRMLS_DC); +} text_iter_ops; + PHPAPI zend_class_entry* text_iterator_aggregate_ce; PHPAPI zend_class_entry* text_iterator_ce; +/* Code unit ops */ + +static text_iter_ops text_iter_cu_ops = { +}; + /* Code point ops */ static int text_iter_cp_valid(text_iter_obj* object TSRMLS_DC) { - return (object->offset < object->text_len); + return (object->u.cp.offset < object->text_len); } -static void text_iter_cp_get_current_data(text_iter_obj* object TSRMLS_DC) +static void text_iter_cp_current(text_iter_obj* object TSRMLS_DC) { UChar32 cp; int32_t tmp, buf_len; @@ -62,7 +82,7 @@ static void text_iter_cp_get_current_data(text_iter_obj* object TSRMLS_DC) MAKE_STD_ZVAL(object->current); Z_USTRVAL_P(object->current) = eumalloc(3); Z_TYPE_P(object->current) = IS_UNICODE; - tmp = object->offset; + tmp = object->u.cp.offset; U16_NEXT(object->text, tmp, object->text_len, cp); buf_len = zend_codepoint_to_uchar(cp, Z_USTRVAL_P(object->current)); Z_USTRVAL_P(object->current)[buf_len] = 0; @@ -70,15 +90,15 @@ static void text_iter_cp_get_current_data(text_iter_obj* object TSRMLS_DC) } } -static int text_iter_cp_get_current_key(text_iter_obj* object TSRMLS_DC) +static int text_iter_cp_key(text_iter_obj* object TSRMLS_DC) { - return object->index; + return object->u.cp.index; } -static void text_iter_cp_move_forward(text_iter_obj* object TSRMLS_DC) +static void text_iter_cp_next(text_iter_obj* object TSRMLS_DC) { - U16_FWD_1(object->text, object->offset, object->text_len); - object->index++; + U16_FWD_1(object->text, object->u.cp.offset, object->text_len); + object->u.cp.index++; if (object->current) { zval_ptr_dtor(&object->current); object->current = NULL; @@ -87,14 +107,26 @@ static void text_iter_cp_move_forward(text_iter_obj* object TSRMLS_DC) static void text_iter_cp_rewind(text_iter_obj *object TSRMLS_DC) { - object->offset = 0; - object->index = 0; + object->u.cp.offset = 0; + object->u.cp.index = 0; if (object->current) { zval_ptr_dtor(&object->current); object->current = NULL; } } +static text_iter_ops text_iter_cp_ops = { + text_iter_cp_valid, + text_iter_cp_current, + text_iter_cp_key, + text_iter_cp_next, + text_iter_cp_rewind, +}; + +static text_iter_ops* iter_ops[2] = { + &text_iter_cu_ops, + &text_iter_cp_ops, +}; /* Iterator Funcs */ @@ -110,7 +142,7 @@ static int text_iter_valid(zend_object_iterator* iter TSRMLS_DC) text_iter_it* iterator = (text_iter_it *) iter; text_iter_obj* object = iterator->object; - if (text_iter_cp_valid(object TSRMLS_CC)) + if (iter_ops[object->type]->valid(object TSRMLS_CC)) return SUCCESS; else return FAILURE; @@ -121,7 +153,7 @@ static void text_iter_get_current_data(zend_object_iterator* iter, zval*** data text_iter_it* iterator = (text_iter_it *) iter; text_iter_obj* object = iterator->object; - text_iter_cp_get_current_data(object TSRMLS_CC); + iter_ops[object->type]->current(object TSRMLS_CC); *data = &object->current; } @@ -130,7 +162,7 @@ static int text_iter_get_current_key(zend_object_iterator* iter, char **str_key, text_iter_it* iterator = (text_iter_it *) iter; text_iter_obj* object = iterator->object; - *int_key = text_iter_cp_get_current_key(object TSRMLS_CC); + *int_key = iter_ops[object->type]->key(object TSRMLS_CC); return HASH_KEY_IS_LONG; } @@ -139,7 +171,7 @@ static void text_iter_move_forward(zend_object_iterator* iter TSRMLS_DC) text_iter_it* iterator = (text_iter_it *) iter; text_iter_obj* object = iterator->object; - text_iter_cp_move_forward(object TSRMLS_CC); + iter_ops[object->type]->next(object TSRMLS_CC); } static void text_iter_rewind(zend_object_iterator* iter TSRMLS_DC) @@ -147,7 +179,7 @@ static void text_iter_rewind(zend_object_iterator* iter TSRMLS_DC) text_iter_it* iterator = (text_iter_it *) iter; text_iter_obj* object = iterator->object; - text_iter_cp_rewind(object TSRMLS_CC); + iter_ops[object->type]->rewind(object TSRMLS_CC); } zend_object_iterator_funcs text_iter_cp_funcs = { @@ -234,7 +266,7 @@ PHP_METHOD(TextIterator, current) zval *object = getThis(); text_iter_obj *intern = (text_iter_obj*) zend_object_store_get_object(object TSRMLS_CC); - text_iter_cp_get_current_data(intern TSRMLS_CC); + iter_ops[intern->type]->current(intern TSRMLS_CC); RETURN_UNICODEL(Z_USTRVAL_P(intern->current), Z_USTRLEN_P(intern->current), 1); } @@ -243,7 +275,7 @@ PHP_METHOD(TextIterator, next) zval *object = getThis(); text_iter_obj *intern = (text_iter_obj*) zend_object_store_get_object(object TSRMLS_CC); - text_iter_cp_move_forward(intern TSRMLS_CC); + iter_ops[intern->type]->next(intern TSRMLS_CC); } PHP_METHOD(TextIterator, key) @@ -251,7 +283,7 @@ PHP_METHOD(TextIterator, key) zval *object = getThis(); text_iter_obj *intern = (text_iter_obj*) zend_object_store_get_object(object TSRMLS_CC); - RETURN_LONG(text_iter_cp_get_current_key(intern TSRMLS_CC)); + RETURN_LONG(iter_ops[intern->type]->key(intern TSRMLS_CC)); } PHP_METHOD(TextIterator, valid) @@ -259,7 +291,7 @@ PHP_METHOD(TextIterator, valid) zval *object = getThis(); text_iter_obj *intern = (text_iter_obj*) zend_object_store_get_object(object TSRMLS_CC); - RETURN_BOOL(text_iter_cp_valid(intern TSRMLS_CC)); + RETURN_BOOL(iter_ops[intern->type]->valid(intern TSRMLS_CC)); } PHP_METHOD(TextIterator, rewind) @@ -267,7 +299,7 @@ PHP_METHOD(TextIterator, rewind) zval *object = getThis(); text_iter_obj *intern = (text_iter_obj*) zend_object_store_get_object(object TSRMLS_CC); - text_iter_cp_rewind(intern TSRMLS_CC); + iter_ops[object->type]->rewind(intern TSRMLS_CC); } static zend_function_entry text_iterator_funcs[] = {