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

LCOV - code coverage report
Current view: top level - Zend - zend_interfaces.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 213 223 95.5 %
Date: 2014-08-04 Functions: 21 21 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Mon, 04 Aug 2014 15:48:58 +0000 (16 days ago)

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