Abstract the iterator interface so that we can add new types.

This commit is contained in:
Andrei Zmievski 2006-02-04 00:23:52 +00:00
parent 94e3087be7
commit 4a3bf22b81

View file

@ -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[] = {