resourcebundle_iterator.c [plain text]
#include <php.h>
#include <zend.h>
#include <zend_API.h>
#include "resourcebundle/resourcebundle.h"
#include "resourcebundle/resourcebundle_class.h"
#include "resourcebundle/resourcebundle_iterator.h"
static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator TSRMLS_DC )
{
UErrorCode icuerror = U_ZERO_ERROR;
ResourceBundle_object *rb = iterator->subject;
rb->child = ures_getByIndex( rb->me, iterator->i, rb->child, &icuerror );
if (U_SUCCESS(icuerror)) {
if (iterator->is_table) {
iterator->currentkey = estrdup( ures_getKey( rb->child ) );
}
MAKE_STD_ZVAL( iterator->current );
resourcebundle_extract_value( iterator->current, rb TSRMLS_CC );
}
else {
iterator->current = NULL;
}
}
static void resourcebundle_iterator_invalidate( zend_object_iterator *iter TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
if (iterator->current) {
zval_ptr_dtor( &iterator->current );
iterator->current = NULL;
}
if (iterator->currentkey) {
efree( iterator->currentkey );
iterator->currentkey = NULL;
}
}
static void resourcebundle_iterator_dtor( zend_object_iterator *iter TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
zval *object = (zval *)iterator->intern.data;
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
Z_DELREF_P(object);
efree(iterator);
}
static int resourcebundle_iterator_has_more( zend_object_iterator *iter TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
return (iterator->i < iterator->length) ? SUCCESS : FAILURE;
}
static void resourcebundle_iterator_current( zend_object_iterator *iter, zval ***data TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
if (!iterator->current) {
resourcebundle_iterator_read( iterator TSRMLS_CC);
}
*data = &iterator->current;
}
static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
if (!iterator->current) {
resourcebundle_iterator_read( iterator TSRMLS_CC);
}
if (iterator->is_table) {
ZVAL_STRING(key, iterator->currentkey, 1);
} else {
ZVAL_LONG(key, iterator->i);
}
}
static void resourcebundle_iterator_step( zend_object_iterator *iter TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
iterator->i++;
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
}
static void resourcebundle_iterator_reset( zend_object_iterator *iter TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
iterator->i = 0;
resourcebundle_iterator_invalidate( iter TSRMLS_CC );
}
static zend_object_iterator_funcs resourcebundle_iterator_funcs = {
resourcebundle_iterator_dtor,
resourcebundle_iterator_has_more,
resourcebundle_iterator_current,
resourcebundle_iterator_key,
resourcebundle_iterator_step,
resourcebundle_iterator_reset,
resourcebundle_iterator_invalidate
};
zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref TSRMLS_DC )
{
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) );
if (byref) {
php_error( E_ERROR, "ResourceBundle does not support writable iterators" );
}
Z_ADDREF_P(object);
iterator->intern.data = (void *) object;
iterator->intern.funcs = &resourcebundle_iterator_funcs;
iterator->subject = rb;
iterator->is_table = (ures_getType( rb->me ) == URES_TABLE);
iterator->length = ures_getSize( rb->me );
iterator->current = NULL;
iterator->currentkey = NULL;
iterator->i = 0;
return (zend_object_iterator *) iterator;
}