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 7                                                        |
   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 )
  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                 resourcebundle_extract_value( &iterator->current, rb );
  45         }
  46         else {
  47                 // zend_throw_exception( spl_ce_OutOfRangeException, "Running past end of ResourceBundle", 0);
  48                 ZVAL_UNDEF(&iterator->current);
  49         }
  50 }
  51 /* }}} */
  52 
  53 /* {{{ resourcebundle_iterator_invalidate */
  54 static void resourcebundle_iterator_invalidate( zend_object_iterator *iter )
  55 {
  56         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
  57 
  58         if (!Z_ISUNDEF(iterator->current)) {
  59                 zval_ptr_dtor( &iterator->current );
  60                 ZVAL_UNDEF(&iterator->current);
  61         }
  62         if (iterator->currentkey) {
  63                 efree( iterator->currentkey );
  64                 iterator->currentkey = NULL;
  65         }
  66 }
  67 /* }}} */
  68 
  69 /* {{{ resourcebundle_iterator_dtor */
  70 static void resourcebundle_iterator_dtor( zend_object_iterator *iter )
  71 {
  72         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
  73         zval                    *object = &iterator->intern.data;
  74 
  75         resourcebundle_iterator_invalidate( iter );
  76 
  77         zval_ptr_dtor(object);
  78 }
  79 /* }}} */
  80 
  81 /* {{{ resourcebundle_iterator_has_more */
  82 static int resourcebundle_iterator_has_more( zend_object_iterator *iter )
  83 {
  84         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
  85         return (iterator->i < iterator->length) ? SUCCESS : FAILURE;
  86 }
  87 /* }}} */
  88 
  89 /* {{{ resourcebundle_iterator_current */
  90 static zval *resourcebundle_iterator_current( zend_object_iterator *iter )
  91 {
  92         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
  93         if (Z_ISUNDEF(iterator->current)) {
  94                 resourcebundle_iterator_read( iterator);
  95         }
  96         return &iterator->current;
  97 }
  98 /* }}} */
  99 
 100 /* {{{ resourcebundle_iterator_key */
 101 static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key )
 102 {
 103         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
 104 
 105         if (Z_ISUNDEF(iterator->current)) {
 106                 resourcebundle_iterator_read( iterator);
 107         }
 108 
 109         if (iterator->is_table) {
 110                 ZVAL_STRING(key, iterator->currentkey);
 111         } else {
 112                 ZVAL_LONG(key, iterator->i);
 113         }
 114 }
 115 /* }}} */
 116 
 117 /* {{{ resourcebundle_iterator_step */
 118 static void resourcebundle_iterator_step( zend_object_iterator *iter )
 119 {
 120         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
 121 
 122         iterator->i++;
 123         resourcebundle_iterator_invalidate( iter );
 124 }
 125 /* }}} */
 126 
 127 /* {{{ resourcebundle_iterator_has_reset */
 128 static void resourcebundle_iterator_reset( zend_object_iterator *iter )
 129 {
 130         ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
 131 
 132         iterator->i = 0;
 133         resourcebundle_iterator_invalidate( iter );
 134 }
 135 /* }}} */
 136 
 137 /* {{{ resourcebundle_iterator_funcs */
 138 static zend_object_iterator_funcs resourcebundle_iterator_funcs = {
 139         resourcebundle_iterator_dtor,
 140         resourcebundle_iterator_has_more,
 141         resourcebundle_iterator_current,
 142         resourcebundle_iterator_key,
 143         resourcebundle_iterator_step,
 144         resourcebundle_iterator_reset,
 145         resourcebundle_iterator_invalidate
 146 };
 147 /* }}} */
 148 
 149 /* {{{ resourcebundle_get_iterator */
 150 zend_object_iterator *resourcebundle_get_iterator( zend_class_entry *ce, zval *object, int byref )
 151 {
 152         ResourceBundle_object   *rb = Z_INTL_RESOURCEBUNDLE_P(object );
 153         ResourceBundle_iterator *iterator = emalloc( sizeof( ResourceBundle_iterator ) );
 154 
 155         if (byref) {
 156              php_error( E_ERROR, "ResourceBundle does not support writable iterators" );
 157         }
 158 
 159         zend_iterator_init(&iterator->intern);
 160         ZVAL_COPY(&iterator->intern.data, object);
 161         iterator->intern.funcs = &resourcebundle_iterator_funcs;
 162 
 163         iterator->subject = rb;
 164 
 165         /* The iterated rb can only be either URES_TABLE or URES_ARRAY
 166          * All other types are returned as php primitives!
 167          */
 168         iterator->is_table = (ures_getType( rb->me ) == URES_TABLE);
 169         iterator->length = ures_getSize( rb->me );
 170 
 171         ZVAL_UNDEF(&iterator->current);
 172         iterator->currentkey = NULL;
 173         iterator->i = 0;
 174 
 175         return (zend_object_iterator *) iterator;
 176 }
 177 /* }}} */
 178 
 179 /*
 180  * Local variables:
 181  * tab-width: 4
 182  * c-basic-offset: 4
 183  * End:
 184  * vim600: noet sw=4 ts=4 fdm=marker
 185  * vim<600: noet sw=4 ts=4
 186  */

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