2003-10-23 04:04:48 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Zend Engine |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2008-12-31 19:15:49 +08:00
| Copyright ( c ) 1998 - 2009 Zend Technologies Ltd . ( http : //www.zend.com) |
2003-10-23 04:04:48 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| This source file is subject to version 2.00 of the Zend license , |
| that is bundled with this package in the file LICENSE , and is |
| available through the world - wide - web at the following url : |
| http : //www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ zend . com so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Marcus Boerger < helly @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
# include "zend.h"
# include "zend_API.h"
# include "zend_interfaces.h"
2005-01-25 18:40:51 +08:00
# include "zend_exceptions.h"
2003-10-23 04:04:48 +08:00
2004-03-28 22:32:32 +08:00
ZEND_API zend_class_entry * zend_ce_traversable ;
ZEND_API zend_class_entry * zend_ce_aggregate ;
ZEND_API zend_class_entry * zend_ce_iterator ;
ZEND_API zend_class_entry * zend_ce_arrayaccess ;
2005-03-19 09:11:48 +08:00
ZEND_API zend_class_entry * zend_ce_serializable ;
2003-10-23 04:04:48 +08:00
2006-05-10 07:53:23 +08:00
/* {{{ zend_call_method
2003-10-23 04:04:48 +08:00
Only returns the returned zval if retval_ptr ! = NULL */
ZEND_API zval * zend_call_method ( zval * * object_pp , zend_class_entry * obj_ce , zend_function * * fn_proxy , char * function_name , int function_name_len , zval * * retval_ptr_ptr , int param_count , zval * arg1 , zval * arg2 TSRMLS_DC )
{
int result ;
zend_fcall_info fci ;
zval z_fname ;
zval * retval ;
2005-03-02 07:41:49 +08:00
HashTable * function_table ;
2003-10-23 04:04:48 +08:00
zval * * params [ 2 ] ;
params [ 0 ] = & arg1 ;
params [ 1 ] = & arg2 ;
fci . size = sizeof ( fci ) ;
/*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
2008-11-28 03:01:23 +08:00
fci . object_ptr = object_pp ? * object_pp : NULL ;
2003-10-23 04:04:48 +08:00
fci . function_name = & z_fname ;
fci . retval_ptr_ptr = retval_ptr_ptr ? retval_ptr_ptr : & retval ;
fci . param_count = param_count ;
fci . params = params ;
fci . no_separation = 1 ;
fci . symbol_table = NULL ;
if ( ! fn_proxy & & ! obj_ce ) {
/* no interest in caching and no information already present that is
* needed later inside zend_call_function . */
ZVAL_STRINGL ( & z_fname , function_name , function_name_len , 0 ) ;
2005-10-03 20:36:36 +08:00
fci . function_table = ! object_pp ? EG ( function_table ) : NULL ;
2003-10-23 04:04:48 +08:00
result = zend_call_function ( & fci , NULL TSRMLS_CC ) ;
} else {
zend_fcall_info_cache fcic ;
fcic . initialized = 1 ;
if ( ! obj_ce ) {
2005-03-02 07:41:49 +08:00
obj_ce = object_pp ? Z_OBJCE_PP ( object_pp ) : NULL ;
}
if ( obj_ce ) {
function_table = & obj_ce - > function_table ;
} else {
function_table = EG ( function_table ) ;
2003-10-23 04:04:48 +08:00
}
if ( ! fn_proxy | | ! * fn_proxy ) {
2005-03-02 07:41:49 +08:00
if ( zend_hash_find ( function_table , function_name , function_name_len + 1 , ( void * * ) & fcic . function_handler ) = = FAILURE ) {
2003-10-23 04:04:48 +08:00
/* error at c-level */
2005-03-02 07:41:49 +08:00
zend_error ( E_CORE_ERROR , " Couldn't find implementation for method %s%s%s " , obj_ce ? obj_ce - > name : " " , obj_ce ? " :: " : " " , function_name ) ;
2003-10-23 04:04:48 +08:00
}
if ( fn_proxy ) {
* fn_proxy = fcic . function_handler ;
}
} else {
fcic . function_handler = * fn_proxy ;
}
fcic . calling_scope = obj_ce ;
2008-07-24 17:42:18 +08:00
fcic . called_scope = object_pp ? obj_ce : EG ( called_scope ) ;
2008-11-28 03:01:23 +08:00
fcic . object_ptr = object_pp ? * object_pp : NULL ;
2003-10-23 04:04:48 +08:00
result = zend_call_function ( & fci , & fcic TSRMLS_CC ) ;
}
if ( result = = FAILURE ) {
/* error at c-level */
if ( ! obj_ce ) {
2005-03-02 07:41:49 +08:00
obj_ce = object_pp ? Z_OBJCE_PP ( object_pp ) : NULL ;
2003-10-23 04:04:48 +08:00
}
2006-08-28 18:27:58 +08:00
if ( ! EG ( exception ) ) {
zend_error ( E_CORE_ERROR , " Couldn't execute method %s%s%s " , obj_ce ? obj_ce - > name : " " , obj_ce ? " :: " : " " , function_name ) ;
}
2003-10-23 04:04:48 +08:00
}
if ( ! retval_ptr_ptr ) {
if ( retval ) {
2003-11-17 08:36:41 +08:00
zval_ptr_dtor ( & retval ) ;
2003-10-23 04:04:48 +08:00
}
return NULL ;
}
return * retval_ptr_ptr ;
}
/* }}} */
/* iterator interface, c-level functions used by engine */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_new_iterator */
2006-05-10 07:53:23 +08:00
ZEND_API zval * zend_user_it_new_iterator ( zend_class_entry * ce , zval * object TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
zval * retval ;
return zend_call_method_with_0_params ( & object , ce , & ce - > iterator_funcs . zf_new_iterator , " getiterator " , & retval ) ;
2003-11-13 16:23:49 +08:00
2003-10-23 04:04:48 +08:00
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_dtor */
2006-05-10 07:53:23 +08:00
ZEND_API void zend_user_it_invalidate_current ( zend_object_iterator * _iter TSRMLS_DC )
2004-01-27 06:33:52 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
if ( iter - > value ) {
zval_ptr_dtor ( & iter - > value ) ;
iter - > value = NULL ;
}
}
/* }}} */
/* {{{ zend_user_it_dtor */
static void zend_user_it_dtor ( zend_object_iterator * _iter TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
2004-04-27 23:47:55 +08:00
zend_user_it_invalidate_current ( _iter TSRMLS_CC ) ;
2003-10-23 04:04:48 +08:00
zval_ptr_dtor ( & object ) ;
efree ( iter ) ;
}
/* }}} */
2004-03-09 02:05:41 +08:00
/* {{{ zend_user_it_valid */
2006-05-10 07:53:23 +08:00
ZEND_API int zend_user_it_valid ( zend_object_iterator * _iter TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
2003-11-05 06:07:59 +08:00
if ( _iter ) {
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
zval * more ;
int result ;
2006-05-10 07:53:23 +08:00
2004-03-09 02:05:41 +08:00
zend_call_method_with_0_params ( & object , iter - > ce , & iter - > ce - > iterator_funcs . zf_valid , " valid " , & more ) ;
2003-11-05 06:07:59 +08:00
if ( more ) {
result = i_zend_is_true ( more ) ;
2003-11-18 08:01:34 +08:00
zval_ptr_dtor ( & more ) ;
2003-11-05 06:07:59 +08:00
return result ? SUCCESS : FAILURE ;
}
}
return FAILURE ;
2003-10-23 04:04:48 +08:00
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_get_current_data */
2006-05-10 07:53:23 +08:00
ZEND_API void zend_user_it_get_current_data ( zend_object_iterator * _iter , zval * * * data TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
if ( ! iter - > value ) {
zend_call_method_with_0_params ( & object , iter - > ce , & iter - > ce - > iterator_funcs . zf_current , " current " , & iter - > value ) ;
}
* data = & iter - > value ;
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_get_current_key_default */
2003-10-23 04:04:48 +08:00
#if 0
2004-01-27 06:33:52 +08:00
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 )
2003-10-23 04:04:48 +08:00
{
2003-11-11 00:13:38 +08:00
* int_key = _iter - > index ;
2003-10-23 04:04:48 +08:00
return HASH_KEY_IS_LONG ;
}
# endif
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_get_current_key */
2006-05-10 07:53:23 +08:00
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 )
2003-10-23 04:04:48 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
zval * retval ;
zend_call_method_with_0_params ( & object , iter - > ce , & iter - > ce - > iterator_funcs . zf_key , " key " , & retval ) ;
2004-04-25 19:25:25 +08:00
if ( ! retval ) {
* int_key = 0 ;
2005-07-20 03:46:21 +08:00
if ( ! EG ( exception ) )
{
zend_error ( E_WARNING , " Nothing returned from %s::key() " , iter - > ce - > name ) ;
}
2004-04-25 19:25:25 +08:00
return HASH_KEY_IS_LONG ;
}
2006-05-12 05:07:39 +08:00
switch ( Z_TYPE_P ( retval ) ) {
default :
2003-10-23 04:04:48 +08:00
zend_error ( E_WARNING , " Illegal type returned from %s::key() " , iter - > ce - > name ) ;
case IS_NULL :
* int_key = 0 ;
zval_ptr_dtor ( & retval ) ;
return HASH_KEY_IS_LONG ;
case IS_STRING :
2006-05-12 05:07:39 +08:00
* str_key = estrndup ( Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) ) ;
* str_key_len = Z_STRLEN_P ( retval ) + 1 ;
2003-10-23 04:04:48 +08:00
zval_ptr_dtor ( & retval ) ;
return HASH_KEY_IS_STRING ;
case IS_DOUBLE :
2006-05-12 05:07:39 +08:00
* int_key = ( long ) Z_DVAL_P ( retval ) ;
zval_ptr_dtor ( & retval ) ;
return HASH_KEY_IS_LONG ;
2003-10-23 04:04:48 +08:00
case IS_RESOURCE :
2006-05-10 07:53:23 +08:00
case IS_BOOL :
2006-05-12 05:07:39 +08:00
case IS_LONG :
* int_key = ( long ) Z_LVAL_P ( retval ) ;
2003-10-23 04:04:48 +08:00
zval_ptr_dtor ( & retval ) ;
return HASH_KEY_IS_LONG ;
}
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_move_forward */
2006-05-10 07:53:23 +08:00
ZEND_API void zend_user_it_move_forward ( zend_object_iterator * _iter TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
2004-04-27 23:47:55 +08:00
zend_user_it_invalidate_current ( _iter TSRMLS_CC ) ;
2003-10-23 04:04:48 +08:00
zend_call_method_with_0_params ( & object , iter - > ce , & iter - > ce - > iterator_funcs . zf_next , " next " , NULL ) ;
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_rewind */
2006-05-10 07:53:23 +08:00
ZEND_API void zend_user_it_rewind ( zend_object_iterator * _iter TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
zend_user_iterator * iter = ( zend_user_iterator * ) _iter ;
zval * object = ( zval * ) iter - > it . data ;
2004-04-27 23:47:55 +08:00
zend_user_it_invalidate_current ( _iter TSRMLS_CC ) ;
2003-10-23 04:04:48 +08:00
zend_call_method_with_0_params ( & object , iter - > ce , & iter - > ce - > iterator_funcs . zf_rewind , " rewind " , NULL ) ;
}
/* }}} */
zend_object_iterator_funcs zend_interface_iterator_funcs_iterator = {
2004-01-27 06:33:52 +08:00
zend_user_it_dtor ,
2004-03-09 02:05:41 +08:00
zend_user_it_valid ,
2004-01-27 06:33:52 +08:00
zend_user_it_get_current_data ,
zend_user_it_get_current_key ,
zend_user_it_move_forward ,
2004-04-27 23:38:07 +08:00
zend_user_it_rewind ,
zend_user_it_invalidate_current
2003-10-23 04:04:48 +08:00
} ;
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_get_iterator */
2006-05-10 07:53:23 +08:00
static zend_object_iterator * zend_user_it_get_iterator ( zend_class_entry * ce , zval * object , int by_ref TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
2006-05-10 07:53:23 +08:00
zend_user_iterator * iterator ;
if ( by_ref ) {
zend_error ( E_ERROR , " An iterator cannot be used with foreach by reference " ) ;
}
iterator = emalloc ( sizeof ( zend_user_iterator ) ) ;
2003-10-23 04:04:48 +08:00
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( object ) ;
2003-10-23 04:04:48 +08:00
iterator - > it . data = ( void * ) object ;
iterator - > it . funcs = ce - > iterator_funcs . funcs ;
iterator - > ce = Z_OBJCE_P ( object ) ;
iterator - > value = NULL ;
return ( zend_object_iterator * ) iterator ;
}
/* }}} */
2004-01-27 06:33:52 +08:00
/* {{{ zend_user_it_get_new_iterator */
2006-05-10 07:53:23 +08:00
ZEND_API zend_object_iterator * zend_user_it_get_new_iterator ( zend_class_entry * ce , zval * object , int by_ref TSRMLS_DC )
2003-10-23 04:04:48 +08:00
{
2004-01-27 06:33:52 +08:00
zval * iterator = zend_user_it_new_iterator ( ce , object TSRMLS_CC ) ;
2003-11-18 08:18:48 +08:00
zend_object_iterator * new_iterator ;
2003-10-23 04:04:48 +08:00
2005-01-25 03:18:37 +08:00
zend_class_entry * ce_it = iterator & & Z_TYPE_P ( iterator ) = = IS_OBJECT ? Z_OBJCE_P ( iterator ) : NULL ;
2003-11-13 16:23:49 +08:00
2006-05-10 07:53:23 +08:00
if ( ! ce_it | | ! ce_it - > get_iterator | | ( ce_it - > get_iterator = = zend_user_it_get_new_iterator & & iterator = = object ) ) {
if ( ! EG ( exception ) ) {
2006-04-11 06:49:29 +08:00
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 ) ;
2005-01-25 03:18:37 +08:00
}
2006-05-10 07:53:23 +08:00
if ( iterator ) {
2005-01-25 03:18:37 +08:00
zval_ptr_dtor ( & iterator ) ;
}
2003-10-23 04:04:48 +08:00
return NULL ;
}
2006-05-10 07:53:23 +08:00
new_iterator = ce_it - > get_iterator ( ce_it , iterator , by_ref TSRMLS_CC ) ;
2003-11-18 08:18:48 +08:00
zval_ptr_dtor ( & iterator ) ;
return new_iterator ;
2003-10-23 04:04:48 +08:00
}
/* }}} */
/* {{{ zend_implement_traversable */
static int zend_implement_traversable ( zend_class_entry * interface , zend_class_entry * class_type TSRMLS_DC )
{
/* check that class_type is traversable at c-level or implements at least one of 'aggregate' and 'Iterator' */
2004-09-27 16:33:11 +08:00
zend_uint i ;
2003-10-23 04:04:48 +08:00
2004-01-18 00:50:54 +08:00
if ( class_type - > get_iterator | | ( class_type - > parent & & class_type - > parent - > get_iterator ) ) {
2003-10-23 04:04:48 +08:00
return SUCCESS ;
2004-03-10 00:38:37 +08:00
}
2003-10-23 04:04:48 +08:00
for ( i = 0 ; i < class_type - > num_interfaces ; i + + ) {
if ( class_type - > interfaces [ i ] = = zend_ce_aggregate | | class_type - > interfaces [ i ] = = zend_ce_iterator ) {
return SUCCESS ;
}
}
zend_error ( E_CORE_ERROR , " Class %s must implement interface %s as part of either %s or %s " ,
class_type - > name ,
zend_ce_traversable - > name ,
zend_ce_iterator - > name ,
zend_ce_aggregate - > name ) ;
return FAILURE ;
}
/* }}} */
/* {{{ zend_implement_aggregate */
static int zend_implement_aggregate ( zend_class_entry * interface , zend_class_entry * class_type TSRMLS_DC )
{
2005-02-23 09:09:10 +08:00
int i , t = - 1 ;
2003-10-29 02:46:37 +08:00
if ( class_type - > get_iterator ) {
if ( class_type - > type = = ZEND_INTERNAL_CLASS ) {
/* inheritance ensures the class has necessary userland methods */
return SUCCESS ;
2004-01-27 06:33:52 +08:00
} else if ( class_type - > get_iterator ! = zend_user_it_get_new_iterator ) {
2005-02-23 09:09:10 +08:00
/* c-level get_iterator cannot be changed (exception being only Traversable is implmented) */
if ( class_type - > num_interfaces ) {
2006-05-10 07:53:23 +08:00
for ( i = 0 ; i < class_type - > num_interfaces ; i + + ) {
2005-02-23 09:09:10 +08:00
if ( class_type - > interfaces [ i ] = = zend_ce_iterator ) {
return FAILURE ;
}
if ( class_type - > interfaces [ i ] = = zend_ce_traversable ) {
t = i ;
}
}
}
if ( t = = - 1 ) {
return FAILURE ;
}
2003-10-29 02:46:37 +08:00
}
2003-10-23 04:04:48 +08:00
}
class_type - > iterator_funcs . zf_new_iterator = NULL ;
2004-01-27 06:33:52 +08:00
class_type - > get_iterator = zend_user_it_get_new_iterator ;
2003-10-23 04:04:48 +08:00
return SUCCESS ;
}
/* }}} */
/* {{{ zend_implement_iterator */
static int zend_implement_iterator ( zend_class_entry * interface , zend_class_entry * class_type TSRMLS_DC )
{
2004-01-27 06:33:52 +08:00
if ( class_type - > get_iterator & & class_type - > get_iterator ! = zend_user_it_get_iterator ) {
2003-10-29 02:46:37 +08:00
if ( class_type - > type = = ZEND_INTERNAL_CLASS ) {
/* inheritance ensures the class has the necessary userland methods */
return SUCCESS ;
2004-01-27 06:33:52 +08:00
} else if ( class_type - > get_iterator ! = zend_user_it_get_new_iterator ) {
2003-10-29 02:46:37 +08:00
/* c-level get_iterator cannot be changed */
return FAILURE ;
}
2003-10-23 04:04:48 +08:00
}
2004-01-27 06:33:52 +08:00
class_type - > get_iterator = zend_user_it_get_iterator ;
2004-03-09 02:05:41 +08:00
class_type - > iterator_funcs . zf_valid = NULL ;
2003-10-23 04:04:48 +08:00
class_type - > iterator_funcs . zf_current = NULL ;
class_type - > iterator_funcs . zf_key = NULL ;
class_type - > iterator_funcs . zf_next = NULL ;
class_type - > iterator_funcs . zf_rewind = NULL ;
if ( ! class_type - > iterator_funcs . funcs ) {
class_type - > iterator_funcs . funcs = & zend_interface_iterator_funcs_iterator ;
}
return SUCCESS ;
}
/* }}} */
2003-11-25 04:57:54 +08:00
/* {{{ zend_implement_arrayaccess */
static int zend_implement_arrayaccess ( zend_class_entry * interface , zend_class_entry * class_type TSRMLS_DC )
{
2004-01-27 06:33:52 +08:00
#if 0
/* get ht from ce */
if ( ht - > read_dimension ! = zend_std_read_dimension
| | ht - > write_dimension ! = zend_std_write_dimension
| | ht - > has_dimension ! = zend_std_has_dimension
| | ht - > unset_dimension ! = zend_std_unset_dimension ) {
return FAILURE ;
}
# endif
2003-11-25 04:57:54 +08:00
return SUCCESS ;
}
/* }}}*/
2005-03-08 06:23:14 +08:00
/* {{{ zend_user_serialize */
2008-08-25 02:22:33 +08:00
ZEND_API int zend_user_serialize ( zval * object , unsigned char * * buffer , zend_uint * buf_len , zend_serialize_data * data TSRMLS_DC )
2005-03-08 06:23:14 +08:00
{
zend_class_entry * ce = Z_OBJCE_P ( object ) ;
zval * retval ;
int result ;
zend_call_method_with_0_params ( & object , ce , & ce - > serialize_func , " serialize " , & retval ) ;
if ( ! retval | | EG ( exception ) ) {
result = FAILURE ;
} else {
switch ( Z_TYPE_P ( retval ) ) {
case IS_NULL :
/* we could also make this '*buf_len = 0' but this allows to skip variables */
2005-04-05 17:16:27 +08:00
zval_ptr_dtor ( & retval ) ;
return FAILURE ;
2005-03-08 06:23:14 +08:00
case IS_STRING :
2008-01-25 02:07:45 +08:00
* buffer = ( unsigned char * ) estrndup ( Z_STRVAL_P ( retval ) , Z_STRLEN_P ( retval ) ) ;
2005-03-08 06:23:14 +08:00
* buf_len = Z_STRLEN_P ( retval ) ;
result = SUCCESS ;
break ;
default : /* failure */
result = FAILURE ;
break ;
}
zval_ptr_dtor ( & retval ) ;
}
if ( result = = FAILURE ) {
2006-05-19 05:24:04 +08:00
zend_throw_exception_ex ( NULL , 0 TSRMLS_CC , " %s::serialize() must return a string or NULL " , ce - > name ) ;
2005-03-08 06:23:14 +08:00
}
return result ;
}
/* }}} */
/* {{{ zend_user_unserialize */
2008-08-25 02:22:33 +08:00
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 )
2005-03-08 06:23:14 +08:00
{
zval * zdata ;
object_init_ex ( * object , ce ) ;
2006-05-10 07:53:23 +08:00
2005-03-08 06:23:14 +08:00
MAKE_STD_ZVAL ( zdata ) ;
ZVAL_STRINGL ( zdata , ( char * ) buf , buf_len , 1 ) ;
zend_call_method_with_1_params ( object , ce , & ce - > unserialize_func , " unserialize " , NULL , zdata ) ;
2006-05-10 07:53:23 +08:00
2005-03-08 06:23:14 +08:00
zval_ptr_dtor ( & zdata ) ;
2006-05-10 07:53:23 +08:00
2005-03-08 06:23:14 +08:00
if ( EG ( exception ) ) {
return FAILURE ;
} else {
return SUCCESS ;
}
}
/* }}} */
2008-12-22 22:11:49 +08:00
ZEND_API int zend_class_serialize_deny ( zval * object , unsigned char * * buffer , zend_uint * buf_len , zend_serialize_data * data TSRMLS_DC ) /* { { { */
{
zend_class_entry * ce = Z_OBJCE_P ( object ) ;
zend_throw_exception_ex ( NULL , 0 TSRMLS_CC , " Serialization of '%s' is not allowed " , ce - > name ) ;
return FAILURE ;
}
/* }}} */
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 ) /* { { { */
{
zend_throw_exception_ex ( NULL , 0 TSRMLS_CC , " Unserialization of '%s' is not allowed " , ce - > name ) ;
return FAILURE ;
}
/* }}} */
2005-03-19 09:11:48 +08:00
/* {{{ zend_implement_serializable */
static int zend_implement_serializable ( zend_class_entry * interface , zend_class_entry * class_type TSRMLS_DC )
2005-03-08 06:23:14 +08:00
{
2008-08-25 02:22:33 +08:00
if ( class_type - > parent
& & ( class_type - > parent - > serialize | | class_type - > parent - > unserialize )
& & ! instanceof_function_ex ( class_type - > parent , zend_ce_serializable , 1 TSRMLS_CC ) ) {
2005-03-08 06:23:14 +08:00
return FAILURE ;
}
2008-08-25 02:22:33 +08:00
if ( ! class_type - > serialize ) {
class_type - > serialize = zend_user_serialize ;
}
if ( ! class_type - > unserialize ) {
class_type - > unserialize = zend_user_unserialize ;
}
2005-03-08 06:23:14 +08:00
return SUCCESS ;
}
/* }}}*/
2003-10-23 04:04:48 +08:00
/* {{{ function tables */
2007-09-28 02:00:48 +08:00
const zend_function_entry zend_funcs_aggregate [ ] = {
2003-10-23 04:04:48 +08:00
ZEND_ABSTRACT_ME ( iterator , getIterator , NULL )
{ NULL , NULL , NULL }
} ;
2007-09-28 02:00:48 +08:00
const zend_function_entry zend_funcs_iterator [ ] = {
2003-10-23 04:04:48 +08:00
ZEND_ABSTRACT_ME ( iterator , current , NULL )
ZEND_ABSTRACT_ME ( iterator , next , NULL )
ZEND_ABSTRACT_ME ( iterator , key , NULL )
2004-03-09 01:33:31 +08:00
ZEND_ABSTRACT_ME ( iterator , valid , NULL )
2003-11-11 00:13:38 +08:00
ZEND_ABSTRACT_ME ( iterator , rewind , NULL )
2003-10-23 04:04:48 +08:00
{ NULL , NULL , NULL }
} ;
2007-09-28 02:00:48 +08:00
const zend_function_entry * zend_funcs_traversable = NULL ;
2003-11-25 04:57:54 +08:00
2005-03-14 00:34:37 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_arrayaccess_offset , 0 , 0 , 1 )
2003-11-25 04:57:54 +08:00
ZEND_ARG_INFO ( 0 , offset )
2007-05-31 00:32:02 +08:00
ZEND_END_ARG_INFO ( )
2003-11-25 04:57:54 +08:00
2005-03-14 00:34:37 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_arrayaccess_offset_get , 0 , 0 , 1 ) /* actually this should be return by ref but atm cannot be */
ZEND_ARG_INFO ( 0 , offset )
2007-05-31 00:32:02 +08:00
ZEND_END_ARG_INFO ( )
2005-03-14 00:34:37 +08:00
2006-05-10 07:53:23 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_arrayaccess_offset_value , 0 , 0 , 2 )
2003-11-25 04:57:54 +08:00
ZEND_ARG_INFO ( 0 , offset )
ZEND_ARG_INFO ( 0 , value )
2007-05-31 00:32:02 +08:00
ZEND_END_ARG_INFO ( )
2003-11-25 04:57:54 +08:00
2007-09-28 02:00:48 +08:00
const zend_function_entry zend_funcs_arrayaccess [ ] = {
2003-11-25 04:57:54 +08:00
ZEND_ABSTRACT_ME ( arrayaccess , offsetExists , arginfo_arrayaccess_offset )
2005-03-14 00:34:37 +08:00
ZEND_ABSTRACT_ME ( arrayaccess , offsetGet , arginfo_arrayaccess_offset_get )
2003-11-25 04:57:54 +08:00
ZEND_ABSTRACT_ME ( arrayaccess , offsetSet , arginfo_arrayaccess_offset_value )
ZEND_ABSTRACT_ME ( arrayaccess , offsetUnset , arginfo_arrayaccess_offset )
{ NULL , NULL , NULL }
} ;
2005-03-19 09:11:48 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_serializable_serialize , 0 )
2005-03-08 06:23:14 +08:00
ZEND_ARG_INFO ( 0 , serialized )
2007-05-31 00:32:02 +08:00
ZEND_END_ARG_INFO ( )
2005-03-08 06:23:14 +08:00
2007-09-28 02:00:48 +08:00
const zend_function_entry zend_funcs_serializable [ ] = {
2005-03-19 09:11:48 +08:00
ZEND_ABSTRACT_ME ( serializable , serialize , NULL )
2006-05-10 07:53:23 +08:00
ZEND_FENTRY ( unserialize , NULL , arginfo_serializable_serialize , ZEND_ACC_PUBLIC | ZEND_ACC_ABSTRACT | ZEND_ACC_CTOR )
2005-03-08 06:23:14 +08:00
{ NULL , NULL , NULL }
} ;
2003-10-23 04:04:48 +08:00
/* }}} */
# define REGISTER_ITERATOR_INTERFACE(class_name, class_name_str) \
{ \
zend_class_entry ce ; \
INIT_CLASS_ENTRY ( ce , # class_name_str , zend_funcs_ # # class_name ) \
zend_ce_ # # class_name = zend_register_internal_interface ( & ce TSRMLS_CC ) ; \
zend_ce_ # # class_name - > interface_gets_implemented = zend_implement_ # # class_name ; \
}
# define REGISTER_ITERATOR_IMPLEMENT(class_name, interface_name) \
zend_class_implements ( zend_ce_ # # class_name TSRMLS_CC , 1 , zend_ce_ # # interface_name )
/* {{{ zend_register_interfaces */
ZEND_API void zend_register_interfaces ( TSRMLS_D )
{
REGISTER_ITERATOR_INTERFACE ( traversable , Traversable ) ;
REGISTER_ITERATOR_INTERFACE ( aggregate , IteratorAggregate ) ;
REGISTER_ITERATOR_IMPLEMENT ( aggregate , traversable ) ;
REGISTER_ITERATOR_INTERFACE ( iterator , Iterator ) ;
REGISTER_ITERATOR_IMPLEMENT ( iterator , traversable ) ;
2006-05-10 07:53:23 +08:00
2003-11-25 04:57:54 +08:00
REGISTER_ITERATOR_INTERFACE ( arrayaccess , ArrayAccess ) ;
2006-05-10 07:53:23 +08:00
2005-03-19 09:11:48 +08:00
REGISTER_ITERATOR_INTERFACE ( serializable , Serializable )
2003-10-23 04:04:48 +08:00
}
/* }}} */
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* indent - tabs - mode : t
* End :
*/