Annotation of embedaddon/php/ext/intl/resourcebundle/resourcebundle_iterator.c, revision 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>