LTP GCOV extension - code coverage report
Current view: directory - Zend - zend_interfaces.c
Test: PHP Code Coverage
Date: 2007-04-10 Instrumented lines: 213
Code covered: 55.9 % Executed lines: 119
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | Zend Engine                                                          |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1998-2007 Zend Technologies Ltd. (http://www.zend.com) |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt.                                |
      11                 :    | If you did not receive a copy of the Zend license and are unable to  |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@zend.com so we can mail you a copy immediately.              |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Marcus Boerger <helly@php.net>                              |
      16                 :    +----------------------------------------------------------------------+
      17                 : */
      18                 : 
      19                 : /* $Id: zend_interfaces.c,v 1.33.2.4.2.5 2007/01/01 09:35:46 sebastian Exp $ */
      20                 : 
      21                 : #include "zend.h"
      22                 : #include "zend_API.h"
      23                 : #include "zend_interfaces.h"
      24                 : #include "zend_exceptions.h"
      25                 : 
      26                 : ZEND_API zend_class_entry *zend_ce_traversable;
      27                 : ZEND_API zend_class_entry *zend_ce_aggregate;
      28                 : ZEND_API zend_class_entry *zend_ce_iterator;
      29                 : ZEND_API zend_class_entry *zend_ce_arrayaccess;
      30                 : ZEND_API zend_class_entry *zend_ce_serializable;
      31                 : 
      32                 : /* {{{ zend_call_method
      33                 :  Only returns the returned zval if retval_ptr != NULL */
      34                 : ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend_function **fn_proxy, char *function_name, int function_name_len, zval **retval_ptr_ptr, int param_count, zval* arg1, zval* arg2 TSRMLS_DC)
      35             141 : {
      36                 :         int result;
      37                 :         zend_fcall_info fci;
      38                 :         zval z_fname;
      39                 :         zval *retval;
      40                 :         HashTable *function_table;
      41                 : 
      42                 :         zval **params[2];
      43                 : 
      44             141 :         params[0] = &arg1;
      45             141 :         params[1] = &arg2;
      46                 : 
      47             141 :         fci.size = sizeof(fci);
      48                 :         /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
      49             141 :         fci.object_pp = object_pp;
      50             141 :         fci.function_name = &z_fname;
      51             141 :         fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
      52             141 :         fci.param_count = param_count;
      53             141 :         fci.params = params;
      54             141 :         fci.no_separation = 1;
      55             141 :         fci.symbol_table = NULL;
      56                 : 
      57             141 :         if (!fn_proxy && !obj_ce) {
      58                 :                 /* no interest in caching and no information already present that is
      59                 :                  * needed later inside zend_call_function. */
      60               0 :                 ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
      61               0 :                 fci.function_table = !object_pp ? EG(function_table) : NULL;
      62               0 :                 result = zend_call_function(&fci, NULL TSRMLS_CC);
      63                 :         } else {
      64                 :                 zend_fcall_info_cache fcic;
      65                 : 
      66             141 :                 fcic.initialized = 1;
      67             141 :                 if (!obj_ce) {
      68               0 :                         obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
      69                 :                 }
      70             141 :                 if (obj_ce) {
      71             141 :                         function_table = &obj_ce->function_table;
      72                 :                 } else {
      73               0 :                         function_table = EG(function_table);
      74                 :                 }
      75             213 :                 if (!fn_proxy || !*fn_proxy) {
      76              72 :                         if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
      77                 :                                 /* error at c-level */
      78               0 :                                 zend_error(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
      79                 :                         }
      80              72 :                         if (fn_proxy) {
      81               8 :                                 *fn_proxy = fcic.function_handler;
      82                 :                         }
      83                 :                 } else {
      84              69 :                         fcic.function_handler = *fn_proxy;
      85                 :                 }
      86             141 :                 fcic.calling_scope = obj_ce;
      87             141 :                 fcic.object_pp = object_pp;
      88             141 :                 result = zend_call_function(&fci, &fcic TSRMLS_CC);
      89                 :         }
      90             141 :         if (result == FAILURE) {
      91                 :                 /* error at c-level */
      92               0 :                 if (!obj_ce) {
      93               0 :                         obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
      94                 :                 }
      95               0 :                 if (!EG(exception)) {
      96               0 :                         zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
      97                 :                 }
      98                 :         }
      99             141 :         if (!retval_ptr_ptr) {
     100              93 :                 if (retval) {
     101              93 :                         zval_ptr_dtor(&retval);
     102                 :                 }
     103              93 :                 return NULL;
     104                 :         }
     105              48 :         return *retval_ptr_ptr;
     106                 : }
     107                 : /* }}} */
     108                 : 
     109                 : /* iterator interface, c-level functions used by engine */
     110                 : 
     111                 : /* {{{ zend_user_it_new_iterator */
     112                 : ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
     113               0 : {
     114                 :         zval *retval;
     115                 : 
     116               0 :         return zend_call_method_with_0_params(&object, ce, &ce->iterator_funcs.zf_new_iterator, "getiterator", &retval);
     117                 : 
     118                 : }
     119                 : /* }}} */
     120                 : 
     121                 : /* {{{ zend_user_it_dtor */
     122                 : ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC)
     123              26 : {
     124              26 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     125                 : 
     126              26 :         if (iter->value) {
     127              18 :                 zval_ptr_dtor(&iter->value);
     128              18 :                 iter->value = NULL;
     129                 :         }
     130              26 : }
     131                 : /* }}} */
     132                 : 
     133                 : /* {{{ zend_user_it_dtor */
     134                 : static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
     135               4 : {
     136               4 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     137               4 :         zval *object = (zval*)iter->it.data;
     138                 : 
     139               4 :         zend_user_it_invalidate_current(_iter TSRMLS_CC);
     140               4 :         zval_ptr_dtor(&object);
     141               4 :         efree(iter);
     142               4 : }
     143                 : /* }}} */
     144                 : 
     145                 : /* {{{ zend_user_it_valid */
     146                 : ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
     147              22 : {
     148              22 :         if (_iter) {
     149              22 :                 zend_user_iterator *iter = (zend_user_iterator*)_iter;
     150              22 :                 zval *object = (zval*)iter->it.data;
     151                 :                 zval *more;
     152                 :                 int result;
     153                 : 
     154              22 :                 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
     155              22 :                 if (more) {
     156              22 :                         result = i_zend_is_true(more);
     157              22 :                         zval_ptr_dtor(&more);
     158              22 :                         return result ? SUCCESS : FAILURE;
     159                 :                 }
     160                 :         }
     161               0 :         return FAILURE;
     162                 : }
     163                 : /* }}} */
     164                 : 
     165                 : /* {{{ zend_user_it_get_current_data */
     166                 : ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC)
     167              18 : {
     168              18 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     169              18 :         zval *object = (zval*)iter->it.data;
     170                 : 
     171              18 :         if (!iter->value) {
     172              18 :                 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
     173                 :         }
     174              18 :         *data = &iter->value;
     175              18 : }
     176                 : /* }}} */
     177                 : 
     178                 : /* {{{ zend_user_it_get_current_key_default */
     179                 : #if 0
     180                 : static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
     181                 : {
     182                 :         *int_key = _iter->index;
     183                 :         return HASH_KEY_IS_LONG;
     184                 : }
     185                 : #endif
     186                 : /* }}} */
     187                 : 
     188                 : /* {{{ zend_user_it_get_current_key */
     189                 : ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
     190               0 : {
     191               0 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     192               0 :         zval *object = (zval*)iter->it.data;
     193                 :         zval *retval;
     194                 : 
     195               0 :         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
     196                 : 
     197               0 :         if (!retval) {
     198               0 :                 *int_key = 0;
     199               0 :                 if (!EG(exception))
     200                 :                 {
     201               0 :                         zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
     202                 :                 }
     203               0 :                 return HASH_KEY_IS_LONG;
     204                 :         }
     205               0 :         switch (Z_TYPE_P(retval)) {
     206                 :                 default:
     207               0 :                         zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
     208                 :                 case IS_NULL:
     209               0 :                         *int_key = 0;
     210               0 :                         zval_ptr_dtor(&retval);
     211               0 :                         return HASH_KEY_IS_LONG;
     212                 : 
     213                 :                 case IS_STRING:
     214               0 :                         *str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
     215               0 :                         *str_key_len = Z_STRLEN_P(retval)+1;
     216               0 :                         zval_ptr_dtor(&retval);
     217               0 :                         return HASH_KEY_IS_STRING;
     218                 : 
     219                 :                 case IS_DOUBLE:
     220               0 :                         *int_key = (long)Z_DVAL_P(retval);
     221               0 :                         zval_ptr_dtor(&retval);
     222               0 :                         return HASH_KEY_IS_LONG;
     223                 : 
     224                 :                 case IS_RESOURCE:
     225                 :                 case IS_BOOL:
     226                 :                 case IS_LONG:
     227               0 :                         *int_key = (long)Z_LVAL_P(retval);
     228               0 :                         zval_ptr_dtor(&retval);
     229               0 :                         return HASH_KEY_IS_LONG;
     230                 :         }
     231                 : }
     232                 : /* }}} */
     233                 : 
     234                 : /* {{{ zend_user_it_move_forward */
     235                 : ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
     236              18 : {
     237              18 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     238              18 :         zval *object = (zval*)iter->it.data;
     239                 : 
     240              18 :         zend_user_it_invalidate_current(_iter TSRMLS_CC);
     241              18 :         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
     242              18 : }
     243                 : /* }}} */
     244                 : 
     245                 : /* {{{ zend_user_it_rewind */
     246                 : ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC)
     247               4 : {
     248               4 :         zend_user_iterator *iter = (zend_user_iterator*)_iter;
     249               4 :         zval *object = (zval*)iter->it.data;
     250                 : 
     251               4 :         zend_user_it_invalidate_current(_iter TSRMLS_CC);
     252               4 :         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
     253               4 : }
     254                 : /* }}} */
     255                 : 
     256                 : zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = {
     257                 :         zend_user_it_dtor,
     258                 :         zend_user_it_valid,
     259                 :         zend_user_it_get_current_data,
     260                 :         zend_user_it_get_current_key,
     261                 :         zend_user_it_move_forward,
     262                 :         zend_user_it_rewind,
     263                 :         zend_user_it_invalidate_current
     264                 : };
     265                 : 
     266                 : /* {{{ zend_user_it_get_iterator */
     267                 : static zend_object_iterator *zend_user_it_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
     268               4 : {
     269                 :         zend_user_iterator *iterator;
     270                 : 
     271               4 :         if (by_ref) {
     272               0 :                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
     273                 :         }
     274                 : 
     275               4 :         iterator = emalloc(sizeof(zend_user_iterator));
     276                 : 
     277               4 :         object->refcount++;
     278               4 :         iterator->it.data = (void*)object;
     279               4 :         iterator->it.funcs = ce->iterator_funcs.funcs;
     280               4 :         iterator->ce = Z_OBJCE_P(object);
     281               4 :         iterator->value = NULL;
     282               4 :         return (zend_object_iterator*)iterator;
     283                 : }
     284                 : /* }}} */
     285                 : 
     286                 : /* {{{ zend_user_it_get_new_iterator */
     287                 : ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
     288               0 : {
     289               0 :         zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC);
     290                 :         zend_object_iterator *new_iterator;
     291                 : 
     292               0 :         zend_class_entry *ce_it = iterator && Z_TYPE_P(iterator) == IS_OBJECT ? Z_OBJCE_P(iterator) : NULL;
     293                 : 
     294               0 :         if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
     295               0 :                 if (!EG(exception)) {
     296               0 :                         zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Objects returned by %s::getIterator() must be traversable or implement interface Iterator", ce ? ce->name : Z_OBJCE_P(object)->name);
     297                 :                 }
     298               0 :                 if (iterator) {
     299               0 :                         zval_ptr_dtor(&iterator);
     300                 :                 }
     301               0 :                 return NULL;
     302                 :         }
     303                 : 
     304               0 :         new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
     305               0 :         zval_ptr_dtor(&iterator);
     306               0 :         return new_iterator;
     307                 : }
     308                 : /* }}} */
     309                 : 
     310                 : /* {{{ zend_implement_traversable */
     311                 : static int zend_implement_traversable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
     312            4843 : {
     313                 :         /* check that class_type is traversable at c-level or implements at least one of 'aggregate' and 'Iterator' */
     314                 :         zend_uint i;
     315                 : 
     316            4843 :         if (class_type->get_iterator || (class_type->parent && class_type->parent->get_iterator)) {
     317            4623 :                 return SUCCESS;
     318                 :         }
     319             660 :         for (i = 0; i < class_type->num_interfaces; i++) {
     320             660 :                 if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
     321             220 :                         return SUCCESS;
     322                 :                 }
     323                 :         }
     324               0 :         zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
     325                 :                 class_type->name,
     326                 :                 zend_ce_traversable->name,
     327                 :                 zend_ce_iterator->name,
     328                 :                 zend_ce_aggregate->name);
     329               0 :         return FAILURE;
     330                 : }
     331                 : /* }}} */
     332                 : 
     333                 : /* {{{ zend_implement_aggregate */
     334                 : static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
     335             220 : {
     336             220 :         int i, t = -1;
     337                 : 
     338             220 :         if (class_type->get_iterator) {
     339               0 :                 if (class_type->type == ZEND_INTERNAL_CLASS) {
     340                 :                         /* inheritance ensures the class has necessary userland methods */
     341               0 :                         return SUCCESS;
     342               0 :                 } else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
     343                 :                         /* c-level get_iterator cannot be changed (exception being only Traversable is implmented) */
     344               0 :                         if (class_type->num_interfaces) {
     345               0 :                                 for (i = 0; i < class_type->num_interfaces; i++) {
     346               0 :                                         if (class_type->interfaces[i] == zend_ce_iterator) {
     347               0 :                                                 return FAILURE;
     348                 :                                         }
     349               0 :                                         if (class_type->interfaces[i] == zend_ce_traversable) {
     350               0 :                                                 t = i;
     351                 :                                         }
     352                 :                                 }
     353                 :                         }
     354               0 :                         if (t == -1) {
     355               0 :                                 return FAILURE;
     356                 :                         }
     357                 :                 }
     358                 :         }
     359             220 :         class_type->iterator_funcs.zf_new_iterator = NULL;
     360             220 :         class_type->get_iterator = zend_user_it_get_new_iterator;
     361             220 :         return SUCCESS;
     362                 : }
     363                 : /* }}} */
     364                 : 
     365                 : /* {{{ zend_implement_iterator */
     366                 : static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
     367            4623 : {
     368            4623 :         if (class_type->get_iterator && class_type->get_iterator != zend_user_it_get_iterator) {
     369               0 :                 if (class_type->type == ZEND_INTERNAL_CLASS) {
     370                 :                         /* inheritance ensures the class has the necessary userland methods */
     371               0 :                         return SUCCESS;
     372               0 :                 } else if (class_type->get_iterator != zend_user_it_get_new_iterator) {
     373                 :                         /* c-level get_iterator cannot be changed */
     374               0 :                         return FAILURE;
     375                 :                 }
     376                 :         }
     377            4623 :         class_type->get_iterator = zend_user_it_get_iterator;
     378            4623 :         class_type->iterator_funcs.zf_valid = NULL;
     379            4623 :         class_type->iterator_funcs.zf_current = NULL;
     380            4623 :         class_type->iterator_funcs.zf_key = NULL;
     381            4623 :         class_type->iterator_funcs.zf_next = NULL;
     382            4623 :         class_type->iterator_funcs.zf_rewind = NULL;
     383            4623 :         if (!class_type->iterator_funcs.funcs) {
     384            4623 :                 class_type->iterator_funcs.funcs = &zend_interface_iterator_funcs_iterator;
     385                 :         }
     386            4623 :         return SUCCESS;
     387                 : }
     388                 : /* }}} */
     389                 : 
     390                 : /* {{{ zend_implement_arrayaccess */
     391                 : static int zend_implement_arrayaccess(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
     392            1320 : {
     393                 : #if 0
     394                 :         /* get ht from ce */
     395                 :         if (ht->read_dimension != zend_std_read_dimension
     396                 :         ||  ht->write_dimension != zend_std_write_dimension
     397                 :         ||  ht->has_dimension != zend_std_has_dimension
     398                 :         ||  ht->unset_dimension != zend_std_unset_dimension) {
     399                 :                 return FAILURE;
     400                 :         }
     401                 : #endif
     402            1320 :         return SUCCESS;
     403                 : }
     404                 : /* }}}*/
     405                 : 
     406                 : /* {{{ zend_user_serialize */
     407                 : int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
     408               0 : {
     409               0 :         zend_class_entry * ce = Z_OBJCE_P(object);
     410                 :         zval *retval;
     411                 :         int result;
     412                 : 
     413               0 :         zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
     414                 : 
     415                 : 
     416               0 :         if (!retval || EG(exception)) {
     417               0 :                 result = FAILURE;
     418                 :         } else {
     419               0 :                 switch(Z_TYPE_P(retval)) {
     420                 :                 case IS_NULL:
     421                 :                         /* we could also make this '*buf_len = 0' but this allows to skip variables */
     422               0 :                         zval_ptr_dtor(&retval);
     423               0 :                         return FAILURE;
     424                 :                 case IS_STRING:
     425               0 :                         *buffer = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
     426               0 :                         *buf_len = Z_STRLEN_P(retval);
     427               0 :                         result = SUCCESS;
     428               0 :                         break;
     429                 :                 default: /* failure */
     430               0 :                         result = FAILURE;
     431                 :                         break;
     432                 :                 }
     433               0 :                 zval_ptr_dtor(&retval);
     434                 :         }
     435                 : 
     436               0 :         if (result == FAILURE) {
     437               0 :                 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
     438                 :         }
     439               0 :         return result;
     440                 : }
     441                 : /* }}} */
     442                 : 
     443                 : /* {{{ zend_user_unserialize */
     444                 : int zend_user_unserialize(zval **object, zend_class_entry *ce, const unsigned char *buf, zend_uint buf_len, zend_unserialize_data *data TSRMLS_DC)
     445               0 : {
     446                 :         zval * zdata;
     447                 : 
     448               0 :         object_init_ex(*object, ce);
     449                 : 
     450               0 :         MAKE_STD_ZVAL(zdata);
     451               0 :         ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
     452                 : 
     453               0 :         zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
     454                 : 
     455               0 :         zval_ptr_dtor(&zdata);
     456                 : 
     457               0 :         if (EG(exception)) {
     458               0 :                 return FAILURE;
     459                 :         } else {
     460               0 :                 return SUCCESS;
     461                 :         }
     462                 : }
     463                 : /* }}} */
     464                 : 
     465                 : /* {{{ zend_implement_serializable */
     466                 : static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
     467             661 : {
     468             661 :         if ((class_type->serialize   && class_type->serialize   != zend_user_serialize)
     469                 :         ||  (class_type->unserialize && class_type->unserialize != zend_user_unserialize)
     470                 :         ) {
     471               0 :                 return FAILURE;
     472                 :         }
     473             661 :         class_type->serialize = zend_user_serialize;
     474             661 :         class_type->unserialize = zend_user_unserialize;
     475             661 :         return SUCCESS;
     476                 : }
     477                 : /* }}}*/
     478                 : 
     479                 : /* {{{ function tables */
     480                 : zend_function_entry zend_funcs_aggregate[] = {
     481                 :         ZEND_ABSTRACT_ME(iterator, getIterator, NULL)
     482                 :         {NULL, NULL, NULL}
     483                 : };
     484                 : 
     485                 : zend_function_entry zend_funcs_iterator[] = {
     486                 :         ZEND_ABSTRACT_ME(iterator, current,  NULL)
     487                 :         ZEND_ABSTRACT_ME(iterator, next,     NULL)
     488                 :         ZEND_ABSTRACT_ME(iterator, key,      NULL)
     489                 :         ZEND_ABSTRACT_ME(iterator, valid,    NULL)
     490                 :         ZEND_ABSTRACT_ME(iterator, rewind,   NULL)
     491                 :         {NULL, NULL, NULL}
     492                 : };
     493                 : 
     494                 : zend_function_entry *zend_funcs_traversable    = NULL;
     495                 : 
     496                 : static
     497                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset, 0, 0, 1)
     498                 :         ZEND_ARG_INFO(0, offset)
     499                 : ZEND_END_ARG_INFO();
     500                 : 
     501                 : static
     502                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_get, 0, 0, 1) /* actually this should be return by ref but atm cannot be */
     503                 :         ZEND_ARG_INFO(0, offset)
     504                 : ZEND_END_ARG_INFO();
     505                 : 
     506                 : static
     507                 : ZEND_BEGIN_ARG_INFO_EX(arginfo_arrayaccess_offset_value, 0, 0, 2)
     508                 :         ZEND_ARG_INFO(0, offset)
     509                 :         ZEND_ARG_INFO(0, value)
     510                 : ZEND_END_ARG_INFO();
     511                 : 
     512                 : zend_function_entry zend_funcs_arrayaccess[] = {
     513                 :         ZEND_ABSTRACT_ME(arrayaccess, offsetExists, arginfo_arrayaccess_offset)
     514                 :         ZEND_ABSTRACT_ME(arrayaccess, offsetGet,    arginfo_arrayaccess_offset_get)
     515                 :         ZEND_ABSTRACT_ME(arrayaccess, offsetSet,    arginfo_arrayaccess_offset_value)
     516                 :         ZEND_ABSTRACT_ME(arrayaccess, offsetUnset,  arginfo_arrayaccess_offset)
     517                 :         {NULL, NULL, NULL}
     518                 : };
     519                 : 
     520                 : static
     521                 : ZEND_BEGIN_ARG_INFO(arginfo_serializable_serialize, 0)
     522                 :         ZEND_ARG_INFO(0, serialized)
     523                 : ZEND_END_ARG_INFO();
     524                 : 
     525                 : zend_function_entry zend_funcs_serializable[] = {
     526                 :         ZEND_ABSTRACT_ME(serializable, serialize,   NULL)
     527                 :         ZEND_FENTRY(unserialize, NULL, arginfo_serializable_serialize, ZEND_ACC_PUBLIC|ZEND_ACC_ABSTRACT|ZEND_ACC_CTOR)
     528                 :         {NULL, NULL, NULL}
     529                 : };
     530                 : /* }}} */
     531                 : 
     532                 : #define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
     533                 :         {\
     534                 :                 zend_class_entry ce;\
     535                 :                 INIT_CLASS_ENTRY(ce, # class_name_str, zend_funcs_ ## class_name) \
     536                 :                 zend_ce_ ## class_name = zend_register_internal_interface(&ce TSRMLS_CC);\
     537                 :                 zend_ce_ ## class_name->interface_gets_implemented = zend_implement_ ## class_name;\
     538                 :         }
     539                 : 
     540                 : #define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
     541                 :         zend_class_implements(zend_ce_ ## class_name TSRMLS_CC, 1, zend_ce_ ## interface_name)
     542                 : 
     543                 : /* {{{ zend_register_interfaces */
     544                 : ZEND_API void zend_register_interfaces(TSRMLS_D)
     545             220 : {
     546             220 :         REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
     547                 : 
     548             220 :         REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
     549             220 :         REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
     550                 : 
     551             220 :         REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
     552             220 :         REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
     553                 : 
     554             220 :         REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
     555                 : 
     556             220 :         REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
     557             220 : }
     558                 : /* }}} */
     559                 : 
     560                 : /*
     561                 :  * Local variables:
     562                 :  * tab-width: 4
     563                 :  * c-basic-offset: 4
     564                 :  * indent-tabs-mode: t
     565                 :  * End:
     566                 :  */

Generated by: LTP GCOV extension version 1.5