Annotation of embedaddon/php/ext/intl/resourcebundle/resourcebundle_iterator.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:    +----------------------------------------------------------------------+
                      3:    | PHP Version 5                                                        |
                      4:    +----------------------------------------------------------------------+
                      5:    | This source file is subject to version 3.01 of the PHP license,      |
                      6:    | that is bundled with this package in the file LICENSE, and is        |
                      7:    | available through the world-wide-web at the following url:           |
                      8:    | http://www.php.net/license/3_01.txt                                  |
                      9:    | If you did not receive a copy of the PHP license and are unable to   |
                     10:    | obtain it through the world-wide-web, please send a note to          |
                     11:    | license@php.net so we can mail you a copy immediately.               |
                     12:    +----------------------------------------------------------------------+
                     13:    | Authors: Hans-Peter Oeri (University of St.Gallen) <hp@oeri.ch>      |
                     14:    +----------------------------------------------------------------------+
                     15:  */
                     16: 
                     17: #include <php.h>
                     18: #include <zend.h>
                     19: #include <zend_API.h>
                     20: 
                     21: #include "resourcebundle/resourcebundle.h"
                     22: #include "resourcebundle/resourcebundle_class.h"
                     23: #include "resourcebundle/resourcebundle_iterator.h"
                     24: 
                     25: /*
                     26:  * Although libicu offers iterator functions, they are not used here: libicu does iterate
                     27:  * irrespective of array indices. Those cannot be recreated afterwards. Arrays as well as tables
                     28:  * can however be accessed by numerical index, with table keys readable ex post.
                     29:  */
                     30: 
                     31: /* {{{ resourcebundle_iterator_read */
                     32: static void resourcebundle_iterator_read( ResourceBundle_iterator *iterator TSRMLS_DC ) 
                     33: {
                     34:        UErrorCode icuerror = U_ZERO_ERROR;
                     35:        ResourceBundle_object *rb = iterator->subject;
                     36: 
                     37:        rb->child = ures_getByIndex( rb->me, iterator->i, rb->child, &icuerror );
                     38: 
                     39:        if (U_SUCCESS(icuerror)) {
                     40:                /* ATTN: key extraction must be the first thing to do... rb->child might be reset in read! */
                     41:                if (iterator->is_table) {
                     42:                        iterator->currentkey = estrdup( ures_getKey( rb->child ) );
                     43:                }
                     44:                MAKE_STD_ZVAL( iterator->current );
                     45:                resourcebundle_extract_value( iterator->current, rb TSRMLS_CC );
                     46:        }
                     47:        else {
                     48:                // zend_throw_exception( spl_ce_OutOfRangeException, "Running past end of ResourceBundle", 0 TSRMLS_CC);
                     49:                iterator->current = NULL;
                     50:        }
                     51: }
                     52: /* }}} */
                     53: 
                     54: /* {{{ resourcebundle_iterator_invalidate */
                     55: static void resourcebundle_iterator_invalidate( zend_object_iterator *iter TSRMLS_DC ) 
                     56: {
                     57:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                     58: 
                     59:        if (iterator->current) {
                     60:                zval_ptr_dtor( &iterator->current );
                     61:                iterator->current = NULL;
                     62:        }
                     63:        if (iterator->currentkey) {
                     64:                efree( iterator->currentkey );
                     65:                iterator->currentkey = NULL;
                     66:        }
                     67: }
                     68: /* }}} */
                     69: 
                     70: /* {{{ resourcebundle_iterator_dtor */
                     71: static void resourcebundle_iterator_dtor( zend_object_iterator *iter TSRMLS_DC )
                     72: {
                     73:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                     74:        zval                    *object = (zval *)iterator->intern.data;
                     75: 
                     76:        resourcebundle_iterator_invalidate( iter TSRMLS_CC );
                     77: 
                     78:        Z_DELREF_P(object);
                     79: 
                     80:        efree(iterator);
                     81: }
                     82: /* }}} */
                     83: 
                     84: /* {{{ resourcebundle_iterator_has_more */
                     85: static int resourcebundle_iterator_has_more( zend_object_iterator *iter TSRMLS_DC )
                     86: {
                     87:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                     88:        return (iterator->i < iterator->length) ? SUCCESS : FAILURE;
                     89: }
                     90: /* }}} */
                     91: 
                     92: /* {{{ resourcebundle_iterator_current */
                     93: static void resourcebundle_iterator_current( zend_object_iterator *iter, zval ***data TSRMLS_DC )
                     94: {
                     95:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                     96:        if (!iterator->current) {
                     97:                resourcebundle_iterator_read( iterator TSRMLS_CC);
                     98:        }
                     99:        *data = &iterator->current;
                    100: }
                    101: /* }}} */
                    102: 
                    103: /* {{{ resourcebundle_iterator_key */
                    104: static int resourcebundle_iterator_key( zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC )
                    105: {
                    106:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                    107: 
                    108:        if (!iterator->current) {
                    109:                resourcebundle_iterator_read( iterator TSRMLS_CC);
                    110:        }
                    111:        if (iterator->is_table) {
                    112:                *str_key = estrdup( iterator->currentkey );
                    113:                *str_key_len = strlen( iterator->currentkey ) + 1;
                    114:                return HASH_KEY_IS_STRING;
                    115:        }
                    116:        else {
                    117:                *int_key = iterator->i;
                    118:                return HASH_KEY_IS_LONG;
                    119:        }
                    120: }
                    121: /* }}} */
                    122: 
                    123: /* {{{ resourcebundle_iterator_has_more */
                    124: static void resourcebundle_iterator_step( zend_object_iterator *iter TSRMLS_DC )
                    125: {
                    126:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                    127: 
                    128:        iterator->i++;
                    129:        resourcebundle_iterator_invalidate( iter TSRMLS_CC );
                    130: }
                    131: /* }}} */
                    132: 
                    133: /* {{{ resourcebundle_iterator_has_reset */
                    134: static void resourcebundle_iterator_reset( zend_object_iterator *iter TSRMLS_DC )
                    135: {
                    136:        ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
                    137: 
                    138:        iterator->i = 0;
                    139:        resourcebundle_iterator_invalidate( iter TSRMLS_CC );
                    140: }
                    141: /* }}} */
                    142: 
                    143: /* {{{ resourcebundle_iterator_funcs */
                    144: static zend_object_iterator_funcs resourcebundle_iterator_funcs = {
                    145:        resourcebundle_iterator_dtor,
                    146:        resourcebundle_iterator_has_more,
                    147:        resourcebundle_iterator_current,
                    148:        resourcebundle_iterator_key,
                    149:        resourcebundle_iterator_step,
                    150:        resourcebundle_iterator_reset,
                    151:        resourcebundle_iterator_invalidate
                    152: };
                    153: /* }}} */
                    154: 
                    155: /* {{{ resourcebundle_get_iterator */
                    156: zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref TSRMLS_DC )
                    157: {
                    158:        ResourceBundle_object   *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
                    159:        ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) );
                    160: 
                    161:        if (byref) {
                    162:             php_error( E_ERROR, "ResourceBundle does not support writable iterators" );
                    163:        }
                    164: 
                    165:        Z_ADDREF_P(object);
                    166:        iterator->intern.data = (void *) object;
                    167:        iterator->intern.funcs = &resourcebundle_iterator_funcs;
                    168: 
                    169:        iterator->subject = rb;
                    170: 
                    171:        /* The iterated rb can only be either URES_TABLE or URES_ARRAY
                    172:         * All other types are returned as php primitives!
                    173:         */
                    174:        iterator->is_table = (ures_getType( rb->me ) == URES_TABLE);
                    175:        iterator->length = ures_getSize( rb->me );
                    176: 
                    177:        iterator->current = NULL;
                    178:        iterator->currentkey = NULL;
                    179:        iterator->i = 0;
                    180: 
                    181:        return (zend_object_iterator *) iterator;
                    182: }
                    183: /* }}} */
                    184: 
                    185: /*
                    186:  * Local variables:
                    187:  * tab-width: 4
                    188:  * c-basic-offset: 4
                    189:  * End:
                    190:  * vim600: noet sw=4 ts=4 fdm=marker
                    191:  * vim<600: noet sw=4 ts=4
                    192:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>