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

Generated by: LCOV version 1.10

Generated at Tue, 15 Jul 2014 20:53:19 +0000 (7 days ago)

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