root/Zend/zend_interfaces.c

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

DEFINITIONS

This source file includes following definitions.
  1. zend_call_method
  2. zend_user_it_new_iterator
  3. zend_user_it_invalidate_current
  4. zend_user_it_dtor
  5. zend_user_it_valid
  6. zend_user_it_get_current_data
  7. zend_user_it_get_current_key_default
  8. zend_user_it_get_current_key
  9. zend_user_it_move_forward
  10. zend_user_it_rewind
  11. zend_user_it_get_iterator
  12. zend_user_it_get_new_iterator
  13. zend_implement_traversable
  14. zend_implement_aggregate
  15. zend_implement_iterator
  16. zend_implement_arrayaccess
  17. zend_user_serialize
  18. zend_user_unserialize
  19. zend_class_serialize_deny
  20. zend_class_unserialize_deny
  21. zend_implement_serializable
  22. zend_register_interfaces

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 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 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         params[0] = &arg1;
  45         params[1] = &arg2;
  46 
  47         fci.size = sizeof(fci);
  48         /*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
  49         fci.object_ptr = object_pp ? *object_pp : NULL;
  50         fci.function_name = &z_fname;
  51         fci.retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : &retval;
  52         fci.param_count = param_count;
  53         fci.params = params;
  54         fci.no_separation = 1;
  55         fci.symbol_table = NULL;
  56 
  57         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                 ZVAL_STRINGL(&z_fname, function_name, function_name_len, 0);
  61                 fci.function_table = !object_pp ? EG(function_table) : NULL;
  62                 result = zend_call_function(&fci, NULL TSRMLS_CC);
  63         } else {
  64                 zend_fcall_info_cache fcic;
  65 
  66                 fcic.initialized = 1;
  67                 if (!obj_ce) {
  68                         obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
  69                 }
  70                 if (obj_ce) {
  71                         function_table = &obj_ce->function_table;
  72                 } else {
  73                         function_table = EG(function_table);
  74                 }
  75                 if (!fn_proxy || !*fn_proxy) {
  76                         if (zend_hash_find(function_table, function_name, function_name_len+1, (void **) &fcic.function_handler) == FAILURE) {
  77                                 /* error at c-level */
  78                                 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                         if (fn_proxy) {
  81                                 *fn_proxy = fcic.function_handler;
  82                         }
  83                 } else {
  84                         fcic.function_handler = *fn_proxy;
  85                 }
  86                 fcic.calling_scope = obj_ce;
  87                 if (object_pp) {
  88                         fcic.called_scope = Z_OBJCE_PP(object_pp);
  89                 } else if (obj_ce &&
  90                            !(EG(called_scope) &&
  91                              instanceof_function(EG(called_scope), obj_ce TSRMLS_CC))) {
  92                         fcic.called_scope = obj_ce;
  93                 } else {
  94                         fcic.called_scope = EG(called_scope);
  95                 }
  96                 fcic.object_ptr = object_pp ? *object_pp : NULL;
  97                 result = zend_call_function(&fci, &fcic TSRMLS_CC);
  98         }
  99         if (result == FAILURE) {
 100                 /* error at c-level */
 101                 if (!obj_ce) {
 102                         obj_ce = object_pp ? Z_OBJCE_PP(object_pp) : NULL;
 103                 }
 104                 if (!EG(exception)) {
 105                         zend_error(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name : "", obj_ce ? "::" : "", function_name);
 106                 }
 107         }
 108         if (!retval_ptr_ptr) {
 109                 if (retval) {
 110                         zval_ptr_dtor(&retval);
 111                 }
 112                 return NULL;
 113         }
 114         return *retval_ptr_ptr;
 115 }
 116 /* }}} */
 117 
 118 /* iterator interface, c-level functions used by engine */
 119 
 120 /* {{{ zend_user_it_new_iterator */
 121 ZEND_API zval *zend_user_it_new_iterator(zend_class_entry *ce, zval *object TSRMLS_DC)
 122 {
 123         zval *retval;
 124 
 125         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 ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC)
 132 {
 133         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 134 
 135         if (iter->value) {
 136                 zval_ptr_dtor(&iter->value);
 137                 iter->value = NULL;
 138         }
 139 }
 140 /* }}} */
 141 
 142 /* {{{ zend_user_it_dtor */
 143 static void zend_user_it_dtor(zend_object_iterator *_iter TSRMLS_DC)
 144 {
 145         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 146         zval *object = (zval*)iter->it.data;
 147 
 148         zend_user_it_invalidate_current(_iter TSRMLS_CC);
 149         zval_ptr_dtor(&object);
 150         efree(iter);
 151 }
 152 /* }}} */
 153 
 154 /* {{{ zend_user_it_valid */
 155 ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC)
 156 {
 157         if (_iter) {
 158                 zend_user_iterator *iter = (zend_user_iterator*)_iter;
 159                 zval *object = (zval*)iter->it.data;
 160                 zval *more;
 161                 int result;
 162 
 163                 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_valid, "valid", &more);
 164                 if (more) {
 165                         result = i_zend_is_true(more);
 166                         zval_ptr_dtor(&more);
 167                         return result ? SUCCESS : FAILURE;
 168                 }
 169         }
 170         return FAILURE;
 171 }
 172 /* }}} */
 173 
 174 /* {{{ zend_user_it_get_current_data */
 175 ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC)
 176 {
 177         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 178         zval *object = (zval*)iter->it.data;
 179 
 180         if (!iter->value) {
 181                 zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_current, "current", &iter->value);
 182         }
 183         *data = &iter->value;
 184 }
 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 ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC)
 199 {
 200         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 201         zval *object = (zval*)iter->it.data;
 202         zval *retval;
 203 
 204         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
 205 
 206         if (retval) {
 207                 ZVAL_ZVAL(key, retval, 1, 1);
 208         } else {
 209                 if (!EG(exception)) {
 210                         zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
 211                 }
 212 
 213                 ZVAL_LONG(key, 0);
 214         }
 215 }
 216 
 217 /* {{{ zend_user_it_move_forward */
 218 ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
 219 {
 220         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 221         zval *object = (zval*)iter->it.data;
 222 
 223         zend_user_it_invalidate_current(_iter TSRMLS_CC);
 224         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_next, "next", NULL);
 225 }
 226 /* }}} */
 227 
 228 /* {{{ zend_user_it_rewind */
 229 ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC)
 230 {
 231         zend_user_iterator *iter = (zend_user_iterator*)_iter;
 232         zval *object = (zval*)iter->it.data;
 233 
 234         zend_user_it_invalidate_current(_iter TSRMLS_CC);
 235         zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_rewind, "rewind", NULL);
 236 }
 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 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         if (by_ref) {
 255                 zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
 256         }
 257 
 258         iterator = emalloc(sizeof(zend_user_iterator));
 259 
 260         Z_ADDREF_P(object);
 261         iterator->it.data = (void*)object;
 262         iterator->it.funcs = ce->iterator_funcs.funcs;
 263         iterator->ce = Z_OBJCE_P(object);
 264         iterator->value = NULL;
 265         return (zend_object_iterator*)iterator;
 266 }
 267 /* }}} */
 268 
 269 /* {{{ zend_user_it_get_new_iterator */
 270 ZEND_API zend_object_iterator *zend_user_it_get_new_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
 271 {
 272         zval *iterator = zend_user_it_new_iterator(ce, object TSRMLS_CC);
 273         zend_object_iterator *new_iterator;
 274 
 275         zend_class_entry *ce_it = iterator && Z_TYPE_P(iterator) == IS_OBJECT ? Z_OBJCE_P(iterator) : NULL;
 276 
 277         if (!ce_it || !ce_it->get_iterator || (ce_it->get_iterator == zend_user_it_get_new_iterator && iterator == object)) {
 278                 if (!EG(exception)) {
 279                         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                 if (iterator) {
 282                         zval_ptr_dtor(&iterator);
 283                 }
 284                 return NULL;
 285         }
 286 
 287         new_iterator = ce_it->get_iterator(ce_it, iterator, by_ref TSRMLS_CC);
 288         zval_ptr_dtor(&iterator);
 289         return new_iterator;
 290 }
 291 /* }}} */
 292 
 293 /* {{{ zend_implement_traversable */
 294 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         if (class_type->get_iterator || (class_type->parent && class_type->parent->get_iterator)) {
 300                 return SUCCESS;
 301         }
 302         for (i = 0; i < class_type->num_interfaces; i++) {
 303                 if (class_type->interfaces[i] == zend_ce_aggregate || class_type->interfaces[i] == zend_ce_iterator) {
 304                         return SUCCESS;
 305                 }
 306         }
 307         zend_error(E_CORE_ERROR, "Class %s must implement interface %s as part of either %s or %s",
 308                 class_type->name,
 309                 zend_ce_traversable->name,
 310                 zend_ce_iterator->name,
 311                 zend_ce_aggregate->name);
 312         return FAILURE;
 313 }
 314 /* }}} */
 315 
 316 /* {{{ zend_implement_aggregate */
 317 static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
 318 {
 319         int i, t = -1;
 320 
 321         if (class_type->get_iterator) {
 322                 if (class_type->type == ZEND_INTERNAL_CLASS) {
 323                         /* inheritance ensures the class has necessary userland methods */
 324                         return SUCCESS;
 325                 } 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                         if (class_type->num_interfaces) {
 328                                 for (i = 0; i < class_type->num_interfaces; i++) {
 329                                         if (class_type->interfaces[i] == zend_ce_iterator) {
 330                                                 zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
 331                                                                         class_type->name,
 332                                                                         interface->name,
 333                                                                         zend_ce_iterator->name);
 334                                                 return FAILURE;
 335                                         }
 336                                         if (class_type->interfaces[i] == zend_ce_traversable) {
 337                                                 t = i;
 338                                         }
 339                                 }
 340                         }
 341                         if (t == -1) {
 342                                 return FAILURE;
 343                         }
 344                 }
 345         }
 346         class_type->iterator_funcs.zf_new_iterator = NULL;
 347         class_type->get_iterator = zend_user_it_get_new_iterator;
 348         return SUCCESS;
 349 }
 350 /* }}} */
 351 
 352 /* {{{ zend_implement_iterator */
 353 static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
 354 {
 355         if (class_type->get_iterator && class_type->get_iterator != zend_user_it_get_iterator) {
 356                 if (class_type->type == ZEND_INTERNAL_CLASS) {
 357                         /* inheritance ensures the class has the necessary userland methods */
 358                         return SUCCESS;
 359                 } else {
 360                         /* c-level get_iterator cannot be changed */
 361                         if (class_type->get_iterator == zend_user_it_get_new_iterator) {
 362                                 zend_error(E_ERROR, "Class %s cannot implement both %s and %s at the same time",
 363                                                         class_type->name,
 364                                                         interface->name,
 365                                                         zend_ce_aggregate->name);
 366                         }
 367                         return FAILURE;
 368                 }
 369         }
 370         class_type->get_iterator = zend_user_it_get_iterator;
 371         class_type->iterator_funcs.zf_valid = NULL;
 372         class_type->iterator_funcs.zf_current = NULL;
 373         class_type->iterator_funcs.zf_key = NULL;
 374         class_type->iterator_funcs.zf_next = NULL;
 375         class_type->iterator_funcs.zf_rewind = NULL;
 376         if (!class_type->iterator_funcs.funcs) {
 377                 class_type->iterator_funcs.funcs = &zend_interface_iterator_funcs_iterator;
 378         }
 379         return SUCCESS;
 380 }
 381 /* }}} */
 382 
 383 /* {{{ zend_implement_arrayaccess */
 384 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         return SUCCESS;
 396 }
 397 /* }}}*/
 398 
 399 /* {{{ zend_user_serialize */
 400 ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC)
 401 {
 402         zend_class_entry * ce = Z_OBJCE_P(object);
 403         zval *retval;
 404         int result;
 405 
 406         zend_call_method_with_0_params(&object, ce, &ce->serialize_func, "serialize", &retval);
 407 
 408 
 409         if (!retval || EG(exception)) {
 410                 result = FAILURE;
 411         } else {
 412                 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                         zval_ptr_dtor(&retval);
 416                         return FAILURE;
 417                 case IS_STRING:
 418                         *buffer = (unsigned char*)estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
 419                         *buf_len = Z_STRLEN_P(retval);
 420                         result = SUCCESS;
 421                         break;
 422                 default: /* failure */
 423                         result = FAILURE;
 424                         break;
 425                 }
 426                 zval_ptr_dtor(&retval);
 427         }
 428 
 429         if (result == FAILURE && !EG(exception)) {
 430                 zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "%s::serialize() must return a string or NULL", ce->name);
 431         }
 432         return result;
 433 }
 434 /* }}} */
 435 
 436 /* {{{ zend_user_unserialize */
 437 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         object_init_ex(*object, ce);
 442 
 443         MAKE_STD_ZVAL(zdata);
 444         ZVAL_STRINGL(zdata, (char*)buf, buf_len, 1);
 445 
 446         zend_call_method_with_1_params(object, ce, &ce->unserialize_func, "unserialize", NULL, zdata);
 447 
 448         zval_ptr_dtor(&zdata);
 449 
 450         if (EG(exception)) {
 451                 return FAILURE;
 452         } else {
 453                 return SUCCESS;
 454         }
 455 }
 456 /* }}} */
 457 
 458 ZEND_API int zend_class_serialize_deny(zval *object, unsigned char **buffer, zend_uint *buf_len, zend_serialize_data *data TSRMLS_DC) /* {{{ */
 459 {
 460         zend_class_entry *ce = Z_OBJCE_P(object);
 461         zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Serialization of '%s' is not allowed", ce->name);
 462         return FAILURE;
 463 }
 464 /* }}} */
 465 
 466 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         zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Unserialization of '%s' is not allowed", ce->name);
 469         return FAILURE;
 470 }
 471 /* }}} */
 472 
 473 /* {{{ zend_implement_serializable */
 474 static int zend_implement_serializable(zend_class_entry *interface, zend_class_entry *class_type TSRMLS_DC)
 475 {
 476         if (class_type->parent
 477                 && (class_type->parent->serialize || class_type->parent->unserialize)
 478                 && !instanceof_function_ex(class_type->parent, zend_ce_serializable, 1 TSRMLS_CC)) {
 479                 return FAILURE;
 480         }
 481         if (!class_type->serialize) {
 482                 class_type->serialize = zend_user_serialize;
 483         }
 484         if (!class_type->unserialize) {
 485                 class_type->unserialize = zend_user_unserialize;
 486         }
 487         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 ZEND_API void zend_register_interfaces(TSRMLS_D)
 553 {
 554         REGISTER_ITERATOR_INTERFACE(traversable, Traversable);
 555 
 556         REGISTER_ITERATOR_INTERFACE(aggregate, IteratorAggregate);
 557         REGISTER_ITERATOR_IMPLEMENT(aggregate, traversable);
 558 
 559         REGISTER_ITERATOR_INTERFACE(iterator, Iterator);
 560         REGISTER_ITERATOR_IMPLEMENT(iterator, traversable);
 561 
 562         REGISTER_ITERATOR_INTERFACE(arrayaccess, ArrayAccess);
 563 
 564         REGISTER_ITERATOR_INTERFACE(serializable, Serializable)
 565 }
 566 /* }}} */
 567 
 568 /*
 569  * Local variables:
 570  * tab-width: 4
 571  * c-basic-offset: 4
 572  * indent-tabs-mode: t
 573  * End:
 574  */

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