root/ext/intl/resourcebundle/resourcebundle_iterator.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. resourcebundle_iterator_read
  2. resourcebundle_iterator_invalidate
  3. resourcebundle_iterator_dtor
  4. resourcebundle_iterator_has_more
  5. resourcebundle_iterator_current
  6. resourcebundle_iterator_key
  7. resourcebundle_iterator_step
  8. resourcebundle_iterator_reset
  9. resourcebundle_get_iterator

   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 void resourcebundle_iterator_key( zend_object_iterator *iter, zval *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 
 112         if (iterator->is_table) {
 113                 ZVAL_STRING(key, iterator->currentkey, 1);
 114         } else {
 115                 ZVAL_LONG(key, iterator->i);
 116         }
 117 }
 118 /* }}} */
 119 
 120 /* {{{ resourcebundle_iterator_has_more */
 121 static void resourcebundle_iterator_step( zend_object_iterator *iter TSRMLS_DC )
 122 {
 123         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
 124 
 125         iterator->i++;
 126         resourcebundle_iterator_invalidate( iter TSRMLS_CC );
 127 }
 128 /* }}} */
 129 
 130 /* {{{ resourcebundle_iterator_has_reset */
 131 static void resourcebundle_iterator_reset( zend_object_iterator *iter TSRMLS_DC )
 132 {
 133         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
 134 
 135         iterator->i = 0;
 136         resourcebundle_iterator_invalidate( iter TSRMLS_CC );
 137 }
 138 /* }}} */
 139 
 140 /* {{{ resourcebundle_iterator_funcs */
 141 static zend_object_iterator_funcs resourcebundle_iterator_funcs = {
 142         resourcebundle_iterator_dtor,
 143         resourcebundle_iterator_has_more,
 144         resourcebundle_iterator_current,
 145         resourcebundle_iterator_key,
 146         resourcebundle_iterator_step,
 147         resourcebundle_iterator_reset,
 148         resourcebundle_iterator_invalidate
 149 };
 150 /* }}} */
 151 
 152 /* {{{ resourcebundle_get_iterator */
 153 zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref TSRMLS_DC )
 154 {
 155         ResourceBundle_object   *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC );
 156         ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) );
 157 
 158         if (byref) {
 159              php_error( E_ERROR, "ResourceBundle does not support writable iterators" );
 160         }
 161 
 162         Z_ADDREF_P(object);
 163         iterator->intern.data = (void *) object;
 164         iterator->intern.funcs = &resourcebundle_iterator_funcs;
 165 
 166         iterator->subject = rb;
 167 
 168         /* The iterated rb can only be either URES_TABLE or URES_ARRAY
 169          * All other types are returned as php primitives!
 170          */
 171         iterator->is_table = (ures_getType( rb->me ) == URES_TABLE);
 172         iterator->length = ures_getSize( rb->me );
 173 
 174         iterator->current = NULL;
 175         iterator->currentkey = NULL;
 176         iterator->i = 0;
 177 
 178         return (zend_object_iterator *) iterator;
 179 }
 180 /* }}} */
 181 
 182 /*
 183  * Local variables:
 184  * tab-width: 4
 185  * c-basic-offset: 4
 186  * End:
 187  * vim600: noet sw=4 ts=4 fdm=marker
 188  * vim<600: noet sw=4 ts=4
 189  */

/* [<][>][^][v][top][bottom][index][help] */