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>