PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - spl - spl_fixedarray.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 470
Code covered: 98.5 % Executed lines: 463
Legend: not executed executed

       1                 : /*
       2                 :   +----------------------------------------------------------------------+
       3                 :   | PHP Version 5                                                        |
       4                 :   +----------------------------------------------------------------------+
       5                 :   | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :   +----------------------------------------------------------------------+
       7                 :   | This source file is subject to version 3.01 of the PHP license,      |
       8                 :   | that is bundled with this package in the file LICENSE, and is        |
       9                 :   | available through the world-wide-web at the following url:           |
      10                 :   | http://www.php.net/license/3_01.txt                                  |
      11                 :   | If you did not receive a copy of the PHP license and are unable to   |
      12                 :   | obtain it through the world-wide-web, please send a note to          |
      13                 :   | license@php.net so we can mail you a copy immediately.               |
      14                 :   +----------------------------------------------------------------------+
      15                 :   | Author: Antony Dovgal <tony@daylessday.org>                          |
      16                 :   |         Etienne Kneuss <colder@php.net>                              |
      17                 :   +----------------------------------------------------------------------+
      18                 : */
      19                 : 
      20                 : /* $Id: spl_fixedarray.c 283486 2009-07-04 20:31:27Z felipe $ */
      21                 : 
      22                 : #ifdef HAVE_CONFIG_H
      23                 : #include "config.h"
      24                 : #endif
      25                 : 
      26                 : #include "php.h"
      27                 : #include "php_ini.h"
      28                 : #include "ext/standard/info.h"
      29                 : #include "zend_exceptions.h"
      30                 : 
      31                 : #include "php_spl.h"
      32                 : #include "spl_functions.h"
      33                 : #include "spl_engine.h"
      34                 : #include "spl_fixedarray.h"
      35                 : #include "spl_exceptions.h"
      36                 : #include "spl_iterators.h"
      37                 : 
      38                 : zend_object_handlers spl_handler_SplFixedArray;
      39                 : PHPAPI zend_class_entry *spl_ce_SplFixedArray;
      40                 : 
      41                 : #ifdef COMPILE_DL_SPL_FIXEDARRAY
      42                 : ZEND_GET_MODULE(spl_fixedarray)
      43                 : #endif
      44                 : 
      45                 : typedef struct _spl_fixedarray { /* {{{ */
      46                 :         long size;
      47                 :         zval **elements;
      48                 : } spl_fixedarray;
      49                 : /* }}} */
      50                 : 
      51                 : typedef struct _spl_fixedarray_object { /* {{{ */
      52                 :         zend_object            std;
      53                 :         spl_fixedarray         *array;
      54                 :         zval                  *retval;
      55                 :         zend_function         *fptr_offset_get;
      56                 :         zend_function         *fptr_offset_set;
      57                 :         zend_function         *fptr_offset_has;
      58                 :         zend_function         *fptr_offset_del;
      59                 :         zend_function         *fptr_count;
      60                 :         int                    current;
      61                 :         int                    flags;
      62                 :         zend_class_entry      *ce_get_iterator;
      63                 : } spl_fixedarray_object;
      64                 : /* }}} */
      65                 : 
      66                 : typedef struct _spl_fixedarray_it { /* {{{ */
      67                 :         zend_user_iterator     intern;
      68                 :         spl_fixedarray_object  *object;
      69                 : } spl_fixedarray_it;
      70                 : /* }}} */
      71                 : 
      72                 : #define SPL_FIXEDARRAY_OVERLOADED_REWIND  0x0001
      73                 : #define SPL_FIXEDARRAY_OVERLOADED_VALID   0x0002
      74                 : #define SPL_FIXEDARRAY_OVERLOADED_KEY     0x0004
      75                 : #define SPL_FIXEDARRAY_OVERLOADED_CURRENT 0x0008
      76                 : #define SPL_FIXEDARRAY_OVERLOADED_NEXT    0x0010
      77                 : 
      78                 : static void spl_fixedarray_init(spl_fixedarray *array, long size TSRMLS_DC) /* {{{ */
      79              70 : {
      80              70 :         if (size > 0) {
      81              58 :                 array->size = 0; /* reset size in case ecalloc() fails */
      82              58 :                 array->elements = ecalloc(size, sizeof(zval *));
      83              58 :                 array->size = size;
      84                 :         } else {
      85              12 :                 array->elements = NULL;
      86              12 :                 array->size = 0;
      87                 :         }
      88              70 : }
      89                 : /* }}} */
      90                 : 
      91                 : static void spl_fixedarray_resize(spl_fixedarray *array, long size TSRMLS_DC) /* {{{ */
      92              19 : {
      93              19 :         if (size == array->size) {
      94                 :                 /* nothing to do */
      95               2 :                 return;
      96                 :         }
      97                 : 
      98                 :         /* first initialization */
      99              17 :         if (array->size == 0) {
     100               3 :                 spl_fixedarray_init(array, size TSRMLS_CC);
     101               3 :                 return;
     102                 :         }
     103                 : 
     104                 :         /* clearing the array */
     105              14 :         if (size == 0) {
     106                 :                 long i;
     107                 : 
     108             112 :                 for (i = 0; i < array->size; i++) {
     109             108 :                         if (array->elements[i]) {
     110               4 :                                 zval_ptr_dtor(&(array->elements[i]));
     111                 :                         }
     112                 :                 }
     113                 : 
     114               4 :                 if (array->elements) {
     115               4 :                         efree(array->elements);
     116               4 :                         array->elements = NULL;
     117                 :                 }
     118              10 :         } else if (size > array->size) {
     119               4 :                 array->elements = erealloc(array->elements, sizeof(zval *) * size);
     120               4 :                 memset(array->elements + array->size, '\0', sizeof(zval *) * (size - array->size));
     121                 :         } else { /* size < array->size */
     122                 :                 long i;
     123                 : 
     124              33 :                 for (i = size; i < array->size; i++) {
     125              27 :                         if (array->elements[i]) {
     126               9 :                                 zval_ptr_dtor(&(array->elements[i]));
     127                 :                         }
     128                 :                 }
     129               6 :                 array->elements = erealloc(array->elements, sizeof(zval *) * size);
     130                 :         }
     131                 : 
     132              14 :         array->size = size;
     133                 : }
     134                 : /* }}} */
     135                 : 
     136                 : static void spl_fixedarray_copy(spl_fixedarray *to, spl_fixedarray *from TSRMLS_DC) /* {{{ */
     137               1 : {
     138                 :         int i;
     139              11 :         for (i = 0; i < from->size; i++) {
     140              10 :                 if (from->elements[i]) {
     141               4 :                         Z_ADDREF_P(from->elements[i]);
     142               4 :                         to->elements[i] = from->elements[i];
     143                 :                 } else {
     144               6 :                         to->elements[i] = NULL;
     145                 :                 }
     146                 :         }
     147               1 : }
     148                 : /* }}} */
     149                 : 
     150                 : static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {{{{ */
     151              21 : {
     152              21 :         spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC);
     153              21 :         int  i = 0;
     154                 : 
     155              21 :         if (intern->array) {
     156              69 :                 for (i = 0; i < intern->array->size; i++) {
     157              49 :                         if (intern->array->elements[i]) {
     158              40 :                                 zend_hash_index_update(intern->std.properties, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL);
     159              40 :                                 Z_ADDREF_P(intern->array->elements[i]);
     160                 :                         } else {
     161               9 :                                 zend_hash_index_update(intern->std.properties, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL);
     162               9 :                                 Z_ADDREF_P(EG(uninitialized_zval_ptr));
     163                 :                         }
     164                 :                 }
     165                 :         }
     166                 : 
     167              21 :         return intern->std.properties;
     168                 : }
     169                 : /* }}}} */
     170                 : 
     171                 : static void spl_fixedarray_object_free_storage(void *object TSRMLS_DC) /* {{{ */
     172              74 : {
     173              74 :         spl_fixedarray_object *intern = (spl_fixedarray_object *)object;
     174                 :         long i;
     175                 : 
     176              74 :         if (intern->array) {
     177           10496 :                 for (i = 0; i < intern->array->size; i++) {
     178           10428 :                         if (intern->array->elements[i]) {
     179              94 :                                 zval_ptr_dtor(&(intern->array->elements[i]));
     180                 :                         }
     181                 :                 }
     182                 : 
     183              68 :                 if (intern->array->size > 0 && intern->array->elements) {
     184              54 :                         efree(intern->array->elements);
     185                 :                 }
     186              68 :                 efree(intern->array);
     187                 :         }
     188                 : 
     189              74 :         zend_object_std_dtor(&intern->std TSRMLS_CC);
     190              74 :         zval_ptr_dtor(&intern->retval);
     191                 : 
     192              74 :         efree(object);
     193              74 : }
     194                 : /* }}} */
     195                 : 
     196                 : zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
     197                 : 
     198                 : static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_type, spl_fixedarray_object **obj, zval *orig, int clone_orig TSRMLS_DC) /* {{{ */
     199              74 : {
     200                 :         zend_object_value     retval;
     201                 :         spl_fixedarray_object *intern;
     202                 :         zval                 *tmp;
     203              74 :         zend_class_entry     *parent = class_type;
     204              74 :         int                   inherited = 0;
     205                 : 
     206              74 :         intern = ecalloc(1, sizeof(spl_fixedarray_object));
     207              74 :         *obj = intern;
     208              74 :         ALLOC_INIT_ZVAL(intern->retval);
     209                 : 
     210              74 :         zend_object_std_init(&intern->std, class_type TSRMLS_CC);
     211              74 :         zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     212                 : 
     213              74 :         intern->current = 0;
     214              74 :         intern->flags = 0;
     215                 : 
     216              74 :         if (orig && clone_orig) {
     217               1 :                 spl_fixedarray_object *other = (spl_fixedarray_object*)zend_object_store_get_object(orig TSRMLS_CC);
     218               1 :                 intern->ce_get_iterator = other->ce_get_iterator;
     219                 : 
     220               1 :                 intern->array = emalloc(sizeof(spl_fixedarray));
     221               1 :                 spl_fixedarray_init(intern->array, other->array->size TSRMLS_CC);
     222               1 :                 spl_fixedarray_copy(intern->array, other->array TSRMLS_CC);
     223                 :         }
     224                 : 
     225             152 :         while (parent) {
     226              78 :                 if (parent == spl_ce_SplFixedArray) {
     227              74 :                         retval.handlers = &spl_handler_SplFixedArray;
     228              74 :                         class_type->get_iterator = spl_fixedarray_get_iterator;
     229              74 :                         break;
     230                 :                 }
     231                 : 
     232               4 :                 parent = parent->parent;
     233               4 :                 inherited = 1;
     234                 :         }
     235                 : 
     236              74 :         retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, spl_fixedarray_object_free_storage, NULL TSRMLS_CC);
     237                 : 
     238              74 :         if (!parent) { /* this must never happen */
     239               0 :                 php_error_docref(NULL TSRMLS_CC, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray");
     240                 :         }
     241              74 :         if (!class_type->iterator_funcs.zf_current) {
     242              57 :                 zend_hash_find(&class_type->function_table, "rewind",  sizeof("rewind"),  (void **) &class_type->iterator_funcs.zf_rewind);
     243              57 :                 zend_hash_find(&class_type->function_table, "valid",   sizeof("valid"),   (void **) &class_type->iterator_funcs.zf_valid);
     244              57 :                 zend_hash_find(&class_type->function_table, "key",     sizeof("key"),     (void **) &class_type->iterator_funcs.zf_key);
     245              57 :                 zend_hash_find(&class_type->function_table, "current", sizeof("current"), (void **) &class_type->iterator_funcs.zf_current);
     246              57 :                 zend_hash_find(&class_type->function_table, "next",    sizeof("next"),    (void **) &class_type->iterator_funcs.zf_next);
     247                 :         }
     248              74 :         if (inherited) {
     249               4 :                 if (class_type->iterator_funcs.zf_rewind->common.scope  != parent) { 
     250               2 :                         intern->flags |= SPL_FIXEDARRAY_OVERLOADED_REWIND;
     251                 :                 }
     252               4 :                 if (class_type->iterator_funcs.zf_valid->common.scope   != parent) { 
     253               2 :                         intern->flags |= SPL_FIXEDARRAY_OVERLOADED_VALID;
     254                 :                 }
     255               4 :                 if (class_type->iterator_funcs.zf_key->common.scope     != parent) { 
     256               2 :                         intern->flags |= SPL_FIXEDARRAY_OVERLOADED_KEY;
     257                 :                 }
     258               4 :                 if (class_type->iterator_funcs.zf_current->common.scope != parent) { 
     259               2 :                         intern->flags |= SPL_FIXEDARRAY_OVERLOADED_CURRENT;
     260                 :                 }
     261               4 :                 if (class_type->iterator_funcs.zf_next->common.scope    != parent) { 
     262               2 :                         intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT;
     263                 :                 }
     264                 : 
     265               4 :                 zend_hash_find(&class_type->function_table, "offsetget",    sizeof("offsetget"),    (void **) &intern->fptr_offset_get);
     266               4 :                 if (intern->fptr_offset_get->common.scope == parent) {
     267               3 :                         intern->fptr_offset_get = NULL;
     268                 :                 }
     269               4 :                 zend_hash_find(&class_type->function_table, "offsetset",    sizeof("offsetset"),    (void **) &intern->fptr_offset_set);
     270               4 :                 if (intern->fptr_offset_set->common.scope == parent) {
     271               3 :                         intern->fptr_offset_set = NULL;
     272                 :                 }
     273               4 :                 zend_hash_find(&class_type->function_table, "offsetexists", sizeof("offsetexists"), (void **) &intern->fptr_offset_has);
     274               4 :                 if (intern->fptr_offset_has->common.scope == parent) {
     275               3 :                         intern->fptr_offset_has = NULL;
     276                 :                 }
     277               4 :                 zend_hash_find(&class_type->function_table, "offsetunset",  sizeof("offsetunset"),  (void **) &intern->fptr_offset_del);
     278               4 :                 if (intern->fptr_offset_del->common.scope == parent) {
     279               3 :                         intern->fptr_offset_del = NULL;
     280                 :                 }
     281               4 :                 zend_hash_find(&class_type->function_table, "count",        sizeof("count"),        (void **) &intern->fptr_count);
     282               4 :                 if (intern->fptr_count->common.scope == parent) {
     283               2 :                         intern->fptr_count = NULL;
     284                 :                 }
     285                 :         }
     286                 : 
     287              74 :         return retval;
     288                 : }
     289                 : /* }}} */
     290                 : 
     291                 : static zend_object_value spl_fixedarray_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
     292              73 : {
     293                 :         spl_fixedarray_object *tmp;
     294              73 :         return spl_fixedarray_object_new_ex(class_type, &tmp, NULL, 0 TSRMLS_CC);
     295                 : }
     296                 : /* }}} */
     297                 : 
     298                 : static zend_object_value spl_fixedarray_object_clone(zval *zobject TSRMLS_DC) /* {{{ */
     299               1 : {
     300                 :         zend_object_value      new_obj_val;
     301                 :         zend_object           *old_object;
     302                 :         zend_object           *new_object;
     303               1 :         zend_object_handle     handle = Z_OBJ_HANDLE_P(zobject);
     304                 :         spl_fixedarray_object  *intern;
     305                 : 
     306               1 :         old_object  = zend_objects_get_address(zobject TSRMLS_CC);
     307               1 :         new_obj_val = spl_fixedarray_object_new_ex(old_object->ce, &intern, zobject, 1 TSRMLS_CC);
     308               1 :         new_object  = &intern->std;
     309                 : 
     310               1 :         zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
     311                 : 
     312               1 :         return new_obj_val;
     313                 : }
     314                 : /* }}} */
     315                 : 
     316                 : static inline zval **spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */
     317              55 : {
     318                 :         long index;
     319                 : 
     320                 :         /* we have to return NULL on error here to avoid memleak because of 
     321                 :          * ZE duplicating uninitialized_zval_ptr */
     322              55 :         if (!offset) {
     323               2 :                 zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
     324               2 :                 return NULL;
     325                 :         }
     326                 : 
     327              53 :         if (Z_TYPE_P(offset) != IS_LONG) {
     328               3 :                 index = spl_offset_convert_to_long(offset TSRMLS_CC);
     329                 :         } else {
     330              50 :                 index = Z_LVAL_P(offset);
     331                 :         }
     332                 :         
     333              53 :         if (index < 0 || intern->array == NULL || index >= intern->array->size) {
     334               5 :                 zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
     335               5 :                 return NULL;
     336              48 :         } else if(!intern->array->elements[index]) {
     337              13 :                 return NULL;
     338                 :         } else {
     339              35 :                 return &intern->array->elements[index];
     340                 :         }
     341                 : }
     342                 : /* }}} */
     343                 : 
     344                 : static zval *spl_fixedarray_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) /* {{{ */
     345              19 : {
     346                 :         spl_fixedarray_object *intern;
     347                 :         zval **retval;
     348                 : 
     349              19 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     350                 : 
     351              19 :         if (intern->fptr_offset_get) {
     352                 :                 zval *rv;
     353               5 :                 SEPARATE_ARG_IF_REF(offset);
     354               5 :                 zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_get, "offsetGet", &rv, offset);
     355               5 :                 zval_ptr_dtor(&offset);
     356               5 :                 if (rv) {
     357               4 :                         zval_ptr_dtor(&intern->retval);
     358               4 :                         MAKE_STD_ZVAL(intern->retval);
     359               4 :                         ZVAL_ZVAL(intern->retval, rv, 1, 1);
     360               4 :                         return intern->retval;
     361                 :                 }
     362               1 :                 return EG(uninitialized_zval_ptr);
     363                 :         }
     364                 : 
     365              14 :         retval = spl_fixedarray_object_read_dimension_helper(intern, offset TSRMLS_CC);
     366              14 :         if (retval) {
     367               8 :                 return *retval;
     368                 :         }
     369               6 :         return NULL;
     370                 : }
     371                 : /* }}} */
     372                 : 
     373                 : static inline void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *intern, zval *offset, zval *value TSRMLS_DC) /* {{{ */
     374             100 : {
     375                 :         long index;
     376                 : 
     377             100 :         if (!offset) {
     378                 :                 /* '$array[] = value' syntax is not supported */
     379               2 :                 zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
     380               2 :                 return;
     381                 :         }
     382                 : 
     383              98 :         if (Z_TYPE_P(offset) != IS_LONG) {
     384               3 :                 index = spl_offset_convert_to_long(offset TSRMLS_CC);
     385                 :         } else {
     386              95 :                 index = Z_LVAL_P(offset);
     387                 :         }
     388                 : 
     389              98 :         if (index < 0 || intern->array == NULL || index >= intern->array->size) {
     390               3 :                 zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
     391               3 :                 return;
     392                 :         } else {
     393              95 :                 if (intern->array->elements[index]) {
     394               3 :                         zval_ptr_dtor(&(intern->array->elements[index]));
     395                 :                 }
     396              95 :                 SEPARATE_ARG_IF_REF(value);
     397              95 :                 intern->array->elements[index] = value;
     398                 :         }
     399                 : }
     400                 : /* }}} */
     401                 : 
     402                 : static void spl_fixedarray_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) /* {{{ */
     403             100 : {
     404                 :         spl_fixedarray_object *intern;
     405                 : 
     406             100 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     407                 : 
     408             100 :         if (intern->fptr_offset_set) {
     409               6 :                 SEPARATE_ARG_IF_REF(offset);
     410               6 :                 SEPARATE_ARG_IF_REF(value);
     411               6 :                 zend_call_method_with_2_params(&object, intern->std.ce, &intern->fptr_offset_set, "offsetSet", NULL, offset, value);
     412               6 :                 zval_ptr_dtor(&value);
     413               6 :                 zval_ptr_dtor(&offset);
     414               6 :                 return;
     415                 :         }
     416                 : 
     417              94 :         spl_fixedarray_object_write_dimension_helper(intern, offset, value TSRMLS_CC);
     418                 : }
     419                 : /* }}} */
     420                 : 
     421                 : static inline void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *intern, zval *offset TSRMLS_DC) /* {{{ */
     422               5 : {
     423                 :         long index;
     424                 :         
     425               5 :         if (Z_TYPE_P(offset) != IS_LONG) {
     426               1 :                 index = spl_offset_convert_to_long(offset TSRMLS_CC);
     427                 :         } else {
     428               4 :                 index = Z_LVAL_P(offset);
     429                 :         }
     430                 :         
     431               5 :         if (index < 0 || intern->array == NULL || index >= intern->array->size) {
     432               2 :                 zend_throw_exception(spl_ce_RuntimeException, "Index invalid or out of range", 0 TSRMLS_CC);
     433               2 :                 return;
     434                 :         } else {
     435               3 :                 if (intern->array->elements[index]) {
     436               3 :                         zval_ptr_dtor(&(intern->array->elements[index]));
     437                 :                 }
     438               3 :                 intern->array->elements[index] = NULL;
     439                 :         }
     440                 : }
     441                 : /* }}} */
     442                 : 
     443                 : static void spl_fixedarray_object_unset_dimension(zval *object, zval *offset TSRMLS_DC) /* {{{ */
     444               4 : {
     445                 :         spl_fixedarray_object *intern;
     446                 : 
     447               4 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     448                 : 
     449               4 :         if (intern->fptr_offset_del) {
     450               2 :                 SEPARATE_ARG_IF_REF(offset);
     451               2 :                 zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset);
     452               2 :                 zval_ptr_dtor(&offset);
     453               2 :                 return;
     454                 :         }
     455                 : 
     456               2 :         spl_fixedarray_object_unset_dimension_helper(intern, offset TSRMLS_CC);
     457                 : 
     458                 : }
     459                 : /* }}} */
     460                 : 
     461                 : static inline int spl_fixedarray_object_has_dimension_helper(spl_fixedarray_object *intern, zval *offset, int check_empty TSRMLS_DC) /* {{{ */
     462              12 : {
     463                 :         long index;
     464                 :         int retval;
     465                 :         
     466              12 :         if (Z_TYPE_P(offset) != IS_LONG) {
     467               2 :                 index = spl_offset_convert_to_long(offset TSRMLS_CC);
     468                 :         } else {
     469              10 :                 index = Z_LVAL_P(offset);
     470                 :         }
     471                 :         
     472              14 :         if (index < 0 || intern->array == NULL || index >= intern->array->size) {
     473               2 :                 retval = 0;
     474                 :         } else {
     475              10 :                 if (!intern->array->elements[index]) {
     476               5 :                         retval = 0;
     477               5 :                 } else if (check_empty) {
     478               3 :                         if (zend_is_true(intern->array->elements[index])) {
     479               2 :                                 retval = 1;
     480                 :                         } else {
     481               1 :                                 retval = 0;
     482                 :                         }
     483                 :                 } else { /* != NULL and !check_empty */
     484               2 :                         retval = 1;
     485                 :                 }
     486                 :         }
     487                 : 
     488              12 :         return retval;
     489                 : }
     490                 : /* }}} */
     491                 : 
     492                 : static int spl_fixedarray_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) /* {{{ */
     493              10 : {
     494                 :         spl_fixedarray_object *intern;
     495                 : 
     496              10 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     497                 : 
     498              10 :         if (intern->fptr_offset_get) {
     499                 :                 zval *rv;
     500               4 :                 SEPARATE_ARG_IF_REF(offset);
     501               4 :                 zend_call_method_with_1_params(&object, intern->std.ce, &intern->fptr_offset_has, "offsetExists", &rv, offset);
     502               4 :                 zval_ptr_dtor(&offset);
     503               4 :                 if (rv) {
     504               4 :                         zval_ptr_dtor(&intern->retval);
     505               4 :                         MAKE_STD_ZVAL(intern->retval);
     506               4 :                         ZVAL_ZVAL(intern->retval, rv, 1, 1);
     507               4 :                         return zend_is_true(intern->retval);
     508                 :                 }
     509               0 :                 return 0;
     510                 :         }
     511                 : 
     512               6 :         return spl_fixedarray_object_has_dimension_helper(intern, offset, check_empty TSRMLS_CC);
     513                 : }
     514                 : /* }}} */
     515                 : 
     516                 : static int spl_fixedarray_object_count_elements(zval *object, long *count TSRMLS_DC) /* {{{ */
     517              10 : {
     518                 :         spl_fixedarray_object *intern;
     519                 :         
     520              10 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     521              10 :         if (intern->fptr_count) {
     522                 :                 zval *rv;
     523               3 :                 zend_call_method_with_0_params(&object, intern->std.ce, &intern->fptr_count, "count", &rv);
     524               3 :                 if (rv) {
     525               3 :                         zval_ptr_dtor(&intern->retval);
     526               3 :                         MAKE_STD_ZVAL(intern->retval);
     527               3 :                         ZVAL_ZVAL(intern->retval, rv, 1, 1);
     528               3 :                         convert_to_long(intern->retval);
     529               3 :                         *count = (long) Z_LVAL_P(intern->retval);
     530               3 :                         return SUCCESS;
     531                 :                 }
     532               7 :         } else if (intern->array) {
     533               7 :                 *count = intern->array->size;
     534               7 :                 return SUCCESS;
     535                 :         }
     536                 : 
     537               0 :         *count = 0;
     538               0 :         return SUCCESS;
     539                 : }
     540                 : /* }}} */
     541                 : 
     542                 : /* {{{ proto void SplFixedArray::__construct([int size])
     543                 : */
     544                 : SPL_METHOD(SplFixedArray, __construct)
     545              67 : {
     546              67 :         zval *object = getThis();
     547                 :         spl_fixedarray_object *intern;
     548              67 :         long size = 0;
     549                 : 
     550              67 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &size)) {
     551               6 :                 return;
     552                 :         }
     553                 : 
     554              61 :         if (size < 0) {
     555               1 :                 zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array size cannot be less than zero");
     556               1 :                 return;
     557                 :         }
     558                 : 
     559              60 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     560                 : 
     561              60 :         if (intern->array) {
     562                 :                 /* called __construct() twice, bail out */
     563               1 :                 return;
     564                 :         }
     565                 : 
     566              59 :         intern->array = emalloc(sizeof(spl_fixedarray));
     567              59 :         spl_fixedarray_init(intern->array, size TSRMLS_CC);
     568                 : }
     569                 : /* }}} */
     570                 : 
     571                 : /* {{{ proto int SplFixedArray::count(void)
     572                 : */
     573                 : SPL_METHOD(SplFixedArray, count)
     574               6 : {
     575               6 :         zval *object = getThis();
     576                 :         spl_fixedarray_object *intern;
     577                 : 
     578               6 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
     579               3 :                 return;
     580                 :         }
     581                 : 
     582               3 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     583               3 :         if (intern->array) {
     584               3 :                 RETURN_LONG(intern->array->size);
     585                 :         }
     586               0 :         RETURN_LONG(0);
     587                 : }
     588                 : /* }}} */
     589                 : 
     590                 : /* {{{ proto object SplFixedArray::toArray()
     591                 : */
     592                 : SPL_METHOD(SplFixedArray, toArray)
     593               3 : {
     594                 :         spl_fixedarray_object *intern;
     595                 :         zval *ret, *tmp;
     596                 :         HashTable *ret_ht, *obj_ht;
     597                 : 
     598               3 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
     599               0 :                 return;
     600                 :         }
     601                 : 
     602               3 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
     603                 : 
     604               3 :         ALLOC_HASHTABLE(ret_ht);
     605               3 :         zend_hash_init(ret_ht, 0, NULL, ZVAL_PTR_DTOR, 0);
     606               3 :         ALLOC_INIT_ZVAL(ret);
     607               3 :         Z_TYPE_P(ret) = IS_ARRAY;
     608               3 :         obj_ht = spl_fixedarray_object_get_properties(getThis() TSRMLS_CC);
     609               3 :         zend_hash_copy(ret_ht, obj_ht, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
     610               3 :         Z_ARRVAL_P(ret) = ret_ht;
     611                 : 
     612               3 :         RETURN_ZVAL(ret, 1, 1);
     613                 : }
     614                 : /* }}} */
     615                 : 
     616                 : /* {{{ proto object SplFixedArray::fromArray(array data[, bool save_indexes])
     617                 : */
     618                 : SPL_METHOD(SplFixedArray, fromArray)
     619              12 : {
     620                 :         zval *data;
     621                 :         spl_fixedarray *array;
     622                 :         spl_fixedarray_object *intern;
     623                 :         int num;
     624              12 :         zend_bool save_indexes = 1;
     625                 : 
     626              12 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &data, &save_indexes)) {
     627               3 :                 return;
     628                 :         }
     629                 : 
     630               9 :         array = ecalloc(1, sizeof(*array));
     631               9 :         num = zend_hash_num_elements(Z_ARRVAL_P(data));
     632                 :         
     633              12 :         if (num > 0 && save_indexes) {
     634                 :                 zval **element, *value;
     635                 :                 char *str_index;
     636               5 :                 ulong num_index, max_index = 0;
     637                 :                 long tmp;
     638                 : 
     639               5 :                 for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
     640              18 :                         zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
     641                 :                         zend_hash_move_forward(Z_ARRVAL_P(data))
     642               8 :                         ) {
     643               9 :                         if (zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0) != HASH_KEY_IS_LONG || (long)num_index < 0) {
     644               1 :                                 efree(array);
     645               1 :                                 zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array must contain only positive integer keys");
     646               1 :                                 return;
     647                 :                         }
     648                 : 
     649               8 :                         if (num_index > max_index) {
     650               6 :                                 max_index = num_index;
     651                 :                         }
     652                 :                 }
     653                 : 
     654               4 :                 tmp = max_index + 1;
     655               4 :                 if (tmp <= 0) {
     656               1 :                         efree(array);
     657               1 :                         zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "integer overflow detected");
     658               1 :                         return;
     659                 :                 }
     660               3 :                 spl_fixedarray_init(array, tmp TSRMLS_CC);
     661                 : 
     662               3 :                 for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
     663              13 :                         zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
     664                 :                         zend_hash_move_forward(Z_ARRVAL_P(data))
     665               7 :                         ) {
     666                 :                         
     667               7 :                         zend_hash_get_current_key(Z_ARRVAL_P(data), &str_index, &num_index, 0);
     668               7 :                         value = *element;
     669                 : 
     670               7 :                         SEPARATE_ARG_IF_REF(value);
     671               7 :                         array->elements[num_index] = value;
     672                 :                 }
     673                 : 
     674               7 :         } else if (num > 0 && !save_indexes) {
     675                 :                 zval **element, *value;
     676               3 :                 long i = 0;
     677                 :                 
     678               3 :                 spl_fixedarray_init(array, num TSRMLS_CC);
     679                 :                 
     680               3 :                 for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(data));
     681              13 :                         zend_hash_get_current_data(Z_ARRVAL_P(data), (void **) &element) == SUCCESS;
     682                 :                         zend_hash_move_forward(Z_ARRVAL_P(data))
     683               7 :                         ) {
     684                 :                         
     685               7 :                         value = *element;
     686                 : 
     687               7 :                         SEPARATE_ARG_IF_REF(value);
     688               7 :                         array->elements[i] = value;
     689               7 :                         i++;
     690                 :                 }
     691                 :         } else {
     692               1 :                 spl_fixedarray_init(array, 0 TSRMLS_CC);
     693                 :         }
     694                 : 
     695               7 :         object_init_ex(return_value, spl_ce_SplFixedArray);
     696               7 :         Z_TYPE_P(return_value) = IS_OBJECT;
     697                 : 
     698               7 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(return_value TSRMLS_CC);
     699               7 :         intern->array = array;
     700                 : }
     701                 : /* }}} */
     702                 : 
     703                 : /* {{{ proto int SplFixedArray::getSize(void)
     704                 : */
     705                 : SPL_METHOD(SplFixedArray, getSize)
     706              14 : {
     707              14 :         zval *object = getThis();
     708                 :         spl_fixedarray_object *intern;
     709                 : 
     710              14 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "")) {
     711               1 :                 return;
     712                 :         }
     713                 : 
     714              13 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     715              13 :         if (intern->array) {
     716              12 :                 RETURN_LONG(intern->array->size);
     717                 :         }
     718               1 :         RETURN_LONG(0);
     719                 : }
     720                 : /* }}} */
     721                 : 
     722                 : /* {{{ proto bool SplFixedArray::setSize(int size)
     723                 : */
     724                 : SPL_METHOD(SplFixedArray, setSize)
     725              21 : {
     726              21 :         zval *object = getThis();
     727                 :         spl_fixedarray_object *intern;
     728                 :         long size;
     729                 : 
     730              21 :         if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size)) {
     731               1 :                 return;
     732                 :         }
     733                 : 
     734              20 :         if (size < 0) {
     735               1 :                 zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, "array size cannot be less than zero");
     736               1 :                 return;
     737                 :         }
     738                 : 
     739              19 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(object TSRMLS_CC);
     740              19 :         if (!intern->array) {
     741               1 :                 intern->array = ecalloc(1, sizeof(spl_fixedarray));
     742                 :         }
     743                 : 
     744              19 :         spl_fixedarray_resize(intern->array, size TSRMLS_CC);
     745              19 :         RETURN_TRUE;
     746                 : }
     747                 : /* }}} */
     748                 : 
     749                 : /* {{{ proto bool SplFixedArray::offsetExists(mixed $index) U
     750                 :  Returns whether the requested $index exists. */
     751                 : SPL_METHOD(SplFixedArray, offsetExists)
     752               7 : {
     753                 :         zval                  *zindex;
     754                 :         spl_fixedarray_object  *intern;
     755                 : 
     756               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
     757               1 :                 return;
     758                 :         }
     759                 : 
     760               6 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
     761                 : 
     762               6 :         RETURN_BOOL(spl_fixedarray_object_has_dimension_helper(intern, zindex, 0 TSRMLS_CC));
     763                 : } /* }}} */
     764                 : 
     765                 : /* {{{ proto mixed SplFixedArray::offsetGet(mixed $index) U
     766                 :  Returns the value at the specified $index. */
     767                 : SPL_METHOD(SplFixedArray, offsetGet)
     768               6 : {
     769                 :         zval                  *zindex, **value_pp;
     770                 :         spl_fixedarray_object  *intern;
     771                 : 
     772               6 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
     773               1 :                 return;
     774                 :         }
     775                 : 
     776               5 :         intern    = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
     777               5 :         value_pp  = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
     778                 : 
     779               5 :         if (value_pp) {
     780               4 :                 RETURN_ZVAL(*value_pp, 1, 0);
     781                 :         }
     782               1 :         RETURN_NULL();
     783                 : } /* }}} */
     784                 : 
     785                 : /* {{{ proto void SplFixedArray::offsetSet(mixed $index, mixed $newval) U
     786                 :  Sets the value at the specified $index to $newval. */
     787                 : SPL_METHOD(SplFixedArray, offsetSet)
     788               8 : {
     789                 :         zval                  *zindex, *value;
     790                 :         spl_fixedarray_object  *intern;
     791                 : 
     792               8 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) {
     793               2 :                 return;
     794                 :         }
     795                 : 
     796               6 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
     797               6 :         spl_fixedarray_object_write_dimension_helper(intern, zindex, value TSRMLS_CC);
     798                 : 
     799                 : } /* }}} */
     800                 : 
     801                 : /* {{{ proto void SplFixedArray::offsetUnset(mixed $index) U
     802                 :  Unsets the value at the specified $index. */
     803                 : SPL_METHOD(SplFixedArray, offsetUnset)
     804               4 : {
     805                 :         zval                  *zindex;
     806                 :         spl_fixedarray_object  *intern;
     807                 : 
     808               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zindex) == FAILURE) {
     809               1 :                 return;
     810                 :         }
     811                 : 
     812               3 :         intern = (spl_fixedarray_object *)zend_object_store_get_object(getThis() TSRMLS_CC);
     813               3 :         spl_fixedarray_object_unset_dimension_helper(intern, zindex TSRMLS_CC);
     814                 : 
     815                 : } /* }}} */
     816                 : 
     817                 : static void spl_fixedarray_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
     818               9 : {
     819               9 :         spl_fixedarray_it  *iterator = (spl_fixedarray_it *)iter;
     820                 : 
     821               9 :         zend_user_it_invalidate_current(iter TSRMLS_CC);
     822               9 :         zval_ptr_dtor((zval**)&iterator->intern.it.data);
     823                 : 
     824               9 :         efree(iterator);
     825               9 : }
     826                 : /* }}} */
     827                 : 
     828                 : static void spl_fixedarray_it_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
     829               9 : {
     830               9 :         spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
     831               9 :         spl_fixedarray_object *intern   = iterator->object;
     832                 : 
     833               9 :         if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_REWIND) {
     834               2 :                 zend_user_it_rewind(iter TSRMLS_CC);
     835                 :         } else {
     836               7 :                 iterator->object->current = 0;
     837                 :         }
     838               9 : }
     839                 : /* }}} */
     840                 : 
     841                 : static int spl_fixedarray_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
     842              45 : {
     843              45 :         spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
     844              45 :         spl_fixedarray_object *intern   = iterator->object;
     845                 : 
     846              45 :         if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_VALID) {
     847              10 :                 return zend_user_it_valid(iter TSRMLS_CC);
     848                 :         }
     849                 : 
     850              35 :         if (iterator->object->current >= 0 && iterator->object->array && iterator->object->current < iterator->object->array->size) {
     851              28 :                 return SUCCESS;
     852                 :         }
     853                 : 
     854               7 :         return FAILURE;
     855                 : }
     856                 : /* }}} */
     857                 : 
     858                 : static void spl_fixedarray_it_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */
     859              36 : {
     860                 :         zval                  *zindex;
     861              36 :         spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
     862              36 :         spl_fixedarray_object *intern   = iterator->object;
     863                 : 
     864              36 :         if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_CURRENT) {
     865               8 :                 zend_user_it_get_current_data(iter, data TSRMLS_CC);
     866                 :         } else {
     867              28 :                 ALLOC_INIT_ZVAL(zindex);
     868              28 :                 ZVAL_LONG(zindex, iterator->object->current);
     869                 : 
     870              28 :                 *data = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
     871                 : 
     872              28 :                 if (*data == NULL) {
     873              10 :                         *data = &EG(uninitialized_zval_ptr);
     874                 :                 }
     875                 : 
     876              28 :                 zval_ptr_dtor(&zindex);
     877                 :         }
     878              36 : }
     879                 : /* }}} */
     880                 : 
     881                 : static int spl_fixedarray_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
     882              13 : {
     883              13 :         spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
     884              13 :         spl_fixedarray_object *intern   = iterator->object;
     885                 : 
     886              13 :         if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_KEY) {
     887               8 :                 return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
     888                 :         } else {
     889               5 :                 *int_key = (ulong) iterator->object->current;
     890               5 :                 return HASH_KEY_IS_LONG;
     891                 :         }
     892                 : 
     893                 : }
     894                 : /* }}} */
     895                 : 
     896                 : static void spl_fixedarray_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
     897              36 : {
     898              36 :         spl_fixedarray_it     *iterator = (spl_fixedarray_it *)iter;
     899              36 :         spl_fixedarray_object *intern   = iterator->object;
     900                 : 
     901              36 :         if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_NEXT) {
     902               8 :                 zend_user_it_move_forward(iter TSRMLS_CC);
     903                 :         } else {
     904              28 :                 zend_user_it_invalidate_current(iter TSRMLS_CC);
     905              28 :                 iterator->object->current++;
     906                 :         }
     907              36 : }
     908                 : /* }}} */
     909                 : 
     910                 : /* {{{  proto int SplFixedArray::key() U
     911                 :    Return current array key */
     912                 : SPL_METHOD(SplFixedArray, key)
     913              15 : {
     914              15 :         spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     915                 :         
     916              15 :         if (zend_parse_parameters_none() == FAILURE) {
     917               3 :                 return;
     918                 :         }
     919                 : 
     920              12 :         RETURN_LONG(intern->current);
     921                 : }
     922                 : /* }}} */
     923                 : 
     924                 : /* {{{ proto void SplFixedArray::next() U
     925                 :    Move to next entry */
     926                 : SPL_METHOD(SplFixedArray, next)
     927               9 : {
     928               9 :         spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     929                 :         
     930               9 :         if (zend_parse_parameters_none() == FAILURE) {
     931               1 :                 return;
     932                 :         }
     933                 : 
     934               8 :         intern->current++;
     935                 : }
     936                 : /* }}} */
     937                 : 
     938                 : /* {{{ proto bool SplFixedArray::valid() U
     939                 :    Check whether the datastructure contains more entries */
     940                 : SPL_METHOD(SplFixedArray, valid)
     941              10 : {
     942              10 :         spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     943                 :         
     944              10 :         if (zend_parse_parameters_none() == FAILURE) {
     945               0 :                 return;
     946                 :         }
     947                 : 
     948              10 :         RETURN_BOOL(intern->current >= 0 && intern->array && intern->current < intern->array->size);
     949                 : }
     950                 : /* }}} */
     951                 : 
     952                 : /* {{{ proto void SplFixedArray::rewind() U
     953                 :    Rewind the datastructure back to the start */
     954                 : SPL_METHOD(SplFixedArray, rewind)
     955               3 : {
     956               3 :         spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     957                 :         
     958               3 :         if (zend_parse_parameters_none() == FAILURE) {
     959               1 :                 return;
     960                 :         }
     961                 : 
     962               2 :         intern->current = 0;
     963                 : }
     964                 : /* }}} */
     965                 : 
     966                 : /* {{{ proto mixed|NULL SplFixedArray::current() U
     967                 :    Return current datastructure entry */
     968                 : SPL_METHOD(SplFixedArray, current)
     969              11 : {
     970                 :         zval                 *zindex, **value_pp;
     971              11 :         spl_fixedarray_object *intern  = (spl_fixedarray_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
     972                 :         
     973              11 :         if (zend_parse_parameters_none() == FAILURE) {
     974               3 :                 return;
     975                 :         }
     976                 : 
     977               8 :         ALLOC_INIT_ZVAL(zindex);
     978               8 :         ZVAL_LONG(zindex, intern->current);
     979                 : 
     980               8 :         value_pp  = spl_fixedarray_object_read_dimension_helper(intern, zindex TSRMLS_CC);
     981                 : 
     982               8 :         zval_ptr_dtor(&zindex);
     983                 : 
     984               8 :         if (value_pp) {
     985               5 :                 RETURN_ZVAL(*value_pp, 1, 0);
     986                 :         }
     987               3 :         RETURN_NULL();
     988                 : }
     989                 : /* }}} */
     990                 : 
     991                 : /* iterator handler table */
     992                 : zend_object_iterator_funcs spl_fixedarray_it_funcs = {
     993                 :         spl_fixedarray_it_dtor,
     994                 :         spl_fixedarray_it_valid,
     995                 :         spl_fixedarray_it_get_current_data,
     996                 :         spl_fixedarray_it_get_current_key,
     997                 :         spl_fixedarray_it_move_forward,
     998                 :         spl_fixedarray_it_rewind
     999                 : };
    1000                 : 
    1001                 : zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
    1002              10 : {
    1003                 :         spl_fixedarray_it      *iterator;
    1004              10 :         spl_fixedarray_object  *fixedarray_object = (spl_fixedarray_object*)zend_object_store_get_object(object TSRMLS_CC);
    1005                 : 
    1006              10 :         if (by_ref) {
    1007               1 :                 zend_throw_exception(spl_ce_RuntimeException, "An iterator cannot be used with foreach by reference", 0 TSRMLS_CC);
    1008               1 :                 return NULL;
    1009                 :         }
    1010                 : 
    1011               9 :         Z_ADDREF_P(object);
    1012                 : 
    1013               9 :         iterator                     = emalloc(sizeof(spl_fixedarray_it));
    1014               9 :         iterator->intern.it.data     = (void*)object;
    1015               9 :         iterator->intern.it.funcs    = &spl_fixedarray_it_funcs;
    1016               9 :         iterator->intern.ce          = ce;
    1017               9 :         iterator->intern.value       = NULL;
    1018               9 :         iterator->object             = fixedarray_object;
    1019                 : 
    1020               9 :         return (zend_object_iterator*)iterator;
    1021                 : }
    1022                 : /* }}} */
    1023                 : 
    1024                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_splfixedarray_construct, 0, 0, 0)
    1025                 :         ZEND_ARG_INFO(0, size)
    1026                 : ZEND_END_ARG_INFO()
    1027                 : 
    1028                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetGet, 0, 0, 1)
    1029                 :         ZEND_ARG_INFO(0, index)
    1030                 : ZEND_END_ARG_INFO()
    1031                 : 
    1032                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetSet, 0, 0, 2)
    1033                 :         ZEND_ARG_INFO(0, index)
    1034                 :         ZEND_ARG_INFO(0, newval)
    1035                 : ZEND_END_ARG_INFO()
    1036                 : 
    1037                 : ZEND_BEGIN_ARG_INFO(arginfo_fixedarray_setSize, 0)
    1038                 :         ZEND_ARG_INFO(0, value)
    1039                 : ZEND_END_ARG_INFO()
    1040                 : 
    1041                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_fromArray, 0, 0, 1)
    1042                 :         ZEND_ARG_INFO(0, data)
    1043                 :         ZEND_ARG_INFO(0, save_indexes)
    1044                 : ZEND_END_ARG_INFO()
    1045                 : 
    1046                 : ZEND_BEGIN_ARG_INFO(arginfo_splfixedarray_void, 0)
    1047                 : ZEND_END_ARG_INFO()
    1048                 : 
    1049                 : static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */
    1050                 :         SPL_ME(SplFixedArray, __construct,     arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC)
    1051                 :         SPL_ME(SplFixedArray, count,           arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1052                 :         SPL_ME(SplFixedArray, toArray,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1053                 :         SPL_ME(SplFixedArray, fromArray,       arginfo_fixedarray_fromArray,   ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
    1054                 :         SPL_ME(SplFixedArray, getSize,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1055                 :         SPL_ME(SplFixedArray, setSize,         arginfo_fixedarray_setSize,     ZEND_ACC_PUBLIC)
    1056                 :         SPL_ME(SplFixedArray, offsetExists,    arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
    1057                 :         SPL_ME(SplFixedArray, offsetGet,       arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
    1058                 :         SPL_ME(SplFixedArray, offsetSet,       arginfo_fixedarray_offsetSet,   ZEND_ACC_PUBLIC)
    1059                 :         SPL_ME(SplFixedArray, offsetUnset,     arginfo_fixedarray_offsetGet,   ZEND_ACC_PUBLIC)
    1060                 :         SPL_ME(SplFixedArray, rewind,          arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1061                 :         SPL_ME(SplFixedArray, current,         arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1062                 :         SPL_ME(SplFixedArray, key,             arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1063                 :         SPL_ME(SplFixedArray, next,            arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1064                 :         SPL_ME(SplFixedArray, valid,           arginfo_splfixedarray_void,     ZEND_ACC_PUBLIC)
    1065                 :         {NULL, NULL, NULL}
    1066                 : };
    1067                 : /* }}} */
    1068                 : 
    1069                 : /* {{{ PHP_MINIT_FUNCTION */
    1070                 : PHP_MINIT_FUNCTION(spl_fixedarray)
    1071           17633 : {
    1072           17633 :         REGISTER_SPL_STD_CLASS_EX(SplFixedArray, spl_fixedarray_new, spl_funcs_SplFixedArray);
    1073           17633 :         memcpy(&spl_handler_SplFixedArray, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
    1074                 : 
    1075           17633 :         spl_handler_SplFixedArray.clone_obj       = spl_fixedarray_object_clone;
    1076           17633 :         spl_handler_SplFixedArray.read_dimension  = spl_fixedarray_object_read_dimension;
    1077           17633 :         spl_handler_SplFixedArray.write_dimension = spl_fixedarray_object_write_dimension;
    1078           17633 :         spl_handler_SplFixedArray.unset_dimension = spl_fixedarray_object_unset_dimension;
    1079           17633 :         spl_handler_SplFixedArray.has_dimension   = spl_fixedarray_object_has_dimension;
    1080           17633 :         spl_handler_SplFixedArray.count_elements  = spl_fixedarray_object_count_elements;
    1081           17633 :         spl_handler_SplFixedArray.get_properties  = spl_fixedarray_object_get_properties;
    1082                 : 
    1083           17633 :         REGISTER_SPL_IMPLEMENTS(SplFixedArray, Iterator);
    1084           17633 :         REGISTER_SPL_IMPLEMENTS(SplFixedArray, ArrayAccess);
    1085           17633 :         REGISTER_SPL_IMPLEMENTS(SplFixedArray, Countable);
    1086                 : 
    1087           17633 :         spl_ce_SplFixedArray->get_iterator = spl_fixedarray_get_iterator;
    1088                 : 
    1089           17633 :         return SUCCESS;
    1090                 : }
    1091                 : /* }}} */
    1092                 : 
    1093                 : 
    1094                 : /*
    1095                 :  * Local variables:
    1096                 :  * tab-width: 4
    1097                 :  * c-basic-offset: 4
    1098                 :  * End:
    1099                 :  * vim600: noet sw=4 ts=4 fdm=marker
    1100                 :  * vim<600: noet sw=4 ts=4
    1101                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:09 +0000 (3 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.