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>