2003-05-02 07:28:28 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2003-06-13 03:30:54 +08:00
| PHP Version 5 |
2003-05-02 07:28:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2012-01-01 21:15:04 +08:00
| Copyright ( c ) 1997 - 2012 The PHP Group |
2003-05-02 07:28:28 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 20:51:34 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2003-05-02 07:28:28 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-13 03:30:54 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 20:51:34 +08:00
| http : //www.php.net/license/3_01.txt |
2003-05-02 07:28:28 +08:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world - wide - web , please send a note to |
| license @ php . net so we can mail you a copy immediately . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Authors : Marcus Boerger < helly @ php . net > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2004-01-21 04:59:45 +08:00
/* $Id$ */
2003-05-02 07:28:28 +08:00
# ifdef HAVE_CONFIG_H
# include "config.h"
# endif
# include "php.h"
# include "php_ini.h"
# include "ext/standard/info.h"
2007-12-07 00:04:17 +08:00
# include "ext/standard/php_var.h"
# include "ext/standard/php_smart_str.h"
2003-11-09 22:05:36 +08:00
# include "zend_interfaces.h"
2004-11-12 04:06:23 +08:00
# include "zend_exceptions.h"
2003-05-02 07:28:28 +08:00
# include "php_spl.h"
# include "spl_functions.h"
# include "spl_engine.h"
2004-04-27 23:42:45 +08:00
# include "spl_iterators.h"
2003-05-02 07:28:28 +08:00
# include "spl_array.h"
2004-11-12 04:06:23 +08:00
# include "spl_exceptions.h"
2003-05-02 07:28:28 +08:00
2003-11-17 13:32:43 +08:00
zend_object_handlers spl_handler_ArrayObject ;
2004-11-02 04:57:23 +08:00
PHPAPI zend_class_entry * spl_ce_ArrayObject ;
2003-11-09 22:05:36 +08:00
zend_object_handlers spl_handler_ArrayIterator ;
2004-11-02 04:57:23 +08:00
PHPAPI zend_class_entry * spl_ce_ArrayIterator ;
2005-09-19 01:15:04 +08:00
PHPAPI zend_class_entry * spl_ce_RecursiveArrayIterator ;
2003-07-20 04:54:22 +08:00
2005-09-19 01:15:04 +08:00
# define SPL_ARRAY_STD_PROP_LIST 0x00000001
# define SPL_ARRAY_ARRAY_AS_PROPS 0x00000002
2007-12-05 23:56:41 +08:00
# define SPL_ARRAY_CHILD_ARRAYS_ONLY 0x00000004
2006-05-10 08:03:38 +08:00
# define SPL_ARRAY_OVERLOADED_REWIND 0x00010000
# define SPL_ARRAY_OVERLOADED_VALID 0x00020000
# define SPL_ARRAY_OVERLOADED_KEY 0x00040000
# define SPL_ARRAY_OVERLOADED_CURRENT 0x00080000
# define SPL_ARRAY_OVERLOADED_NEXT 0x00100000
2005-09-19 01:15:04 +08:00
# define SPL_ARRAY_IS_REF 0x01000000
# define SPL_ARRAY_IS_SELF 0x02000000
# define SPL_ARRAY_USE_OTHER 0x04000000
2006-05-10 08:03:38 +08:00
# define SPL_ARRAY_INT_MASK 0xFFFF0000
2007-12-07 00:04:17 +08:00
# define SPL_ARRAY_CLONE_MASK 0x0300FFFF
2005-05-19 23:52:02 +08:00
2003-07-20 04:54:22 +08:00
typedef struct _spl_array_object {
2008-08-26 02:40:44 +08:00
zend_object std ;
zval * array ;
zval * retval ;
HashPosition pos ;
2008-11-19 22:41:40 +08:00
ulong pos_h ;
2008-08-26 02:40:44 +08:00
int ar_flags ;
int is_self ;
zend_function * fptr_offset_get ;
zend_function * fptr_offset_set ;
zend_function * fptr_offset_has ;
zend_function * fptr_offset_del ;
zend_function * fptr_count ;
zend_function * fptr_serialize ;
zend_function * fptr_unserialize ;
zend_class_entry * ce_get_iterator ;
php_serialize_data_t * serialize_data ;
php_unserialize_data_t * unserialize_data ;
2009-08-14 06:07:05 +08:00
HashTable * debug_info ;
2011-11-18 13:22:35 +08:00
unsigned char nApplyCount ;
2003-07-20 04:54:22 +08:00
} spl_array_object ;
2007-12-07 00:04:17 +08:00
static inline HashTable * spl_array_get_hash_table ( spl_array_object * intern , int check_std_props TSRMLS_DC ) { /* {{{ */
2006-04-05 03:53:21 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_SELF ) ! = 0 ) {
return intern - > std . properties ;
2007-07-20 18:53:56 +08:00
} else if ( ( intern - > ar_flags & SPL_ARRAY_USE_OTHER ) & & ( check_std_props = = 0 | | ( intern - > ar_flags & SPL_ARRAY_STD_PROP_LIST ) = = 0 ) & & Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
2005-06-20 08:19:18 +08:00
spl_array_object * other = ( spl_array_object * ) zend_object_store_get_object ( intern - > array TSRMLS_CC ) ;
return spl_array_get_hash_table ( other , check_std_props TSRMLS_CC ) ;
} else if ( ( intern - > ar_flags & ( ( check_std_props ? SPL_ARRAY_STD_PROP_LIST : 0 ) | SPL_ARRAY_IS_SELF ) ) ! = 0 ) {
2005-05-19 23:52:02 +08:00
return intern - > std . properties ;
} else {
return HASH_OF ( intern - > array ) ;
}
2007-12-07 00:04:17 +08:00
} /* }}} */
2005-05-19 23:52:02 +08:00
2008-07-24 23:54:41 +08:00
static void spl_array_rewind ( spl_array_object * intern TSRMLS_DC ) ;
2008-11-19 22:41:40 +08:00
static void spl_array_update_pos ( spl_array_object * intern ) /* { { { */
{
2008-11-20 01:53:47 +08:00
Bucket * pos = intern - > pos ;
if ( pos ! = NULL ) {
2008-11-19 22:41:40 +08:00
intern - > pos_h = pos - > h ;
}
} /* }}} */
static void spl_array_set_pos ( spl_array_object * intern , HashPosition pos ) /* { { { */
{
intern - > pos = pos ;
spl_array_update_pos ( intern ) ;
} /* }}} */
SPL_API int spl_hash_verify_pos_ex ( spl_array_object * intern , HashTable * ht TSRMLS_DC ) /* { { { */
2005-03-22 04:07:33 +08:00
{
Bucket * p ;
/* IS_CONSISTENT(ht);*/
/* HASH_PROTECT_RECURSION(ht);*/
2008-11-19 22:41:40 +08:00
p = ht - > arBuckets [ intern - > pos_h & ht - > nTableMask ] ;
2005-03-22 04:07:33 +08:00
while ( p ! = NULL ) {
if ( p = = intern - > pos ) {
return SUCCESS ;
}
2008-11-19 22:41:40 +08:00
p = p - > pNext ;
2005-03-22 04:07:33 +08:00
}
/* HASH_UNPROTECT_RECURSION(ht); */
2008-07-24 23:54:41 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
2005-03-22 04:07:33 +08:00
return FAILURE ;
2008-11-19 22:41:40 +08:00
} /* }}} */
SPL_API int spl_hash_verify_pos ( spl_array_object * intern TSRMLS_DC ) /* { { { */
{
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
return spl_hash_verify_pos_ex ( intern , ht TSRMLS_CC ) ;
2005-03-22 04:07:33 +08:00
}
/* }}} */
2004-02-04 20:45:47 +08:00
/* {{{ spl_array_object_free_storage */
static void spl_array_object_free_storage ( void * object TSRMLS_DC )
2003-07-20 04:54:22 +08:00
{
spl_array_object * intern = ( spl_array_object * ) object ;
2006-03-29 22:28:43 +08:00
zend_object_std_dtor ( & intern - > std TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
2003-11-17 13:25:47 +08:00
zval_ptr_dtor ( & intern - > array ) ;
2005-06-20 11:02:52 +08:00
zval_ptr_dtor ( & intern - > retval ) ;
2003-07-20 04:54:22 +08:00
2009-08-14 06:07:05 +08:00
if ( intern - > debug_info ! = NULL ) {
zend_hash_destroy ( intern - > debug_info ) ;
efree ( intern - > debug_info ) ;
}
2003-07-20 04:54:22 +08:00
efree ( object ) ;
}
/* }}} */
2006-05-10 08:03:38 +08:00
zend_object_iterator * spl_array_get_iterator ( zend_class_entry * ce , zval * object , int by_ref TSRMLS_DC ) ;
2008-08-26 02:40:44 +08:00
int spl_array_serialize ( zval * object , unsigned char * * buffer , zend_uint * buf_len , zend_serialize_data * data TSRMLS_DC ) ;
int spl_array_unserialize ( zval * * object , zend_class_entry * ce , const unsigned char * buf , zend_uint buf_len , zend_unserialize_data * data TSRMLS_DC ) ;
2006-04-05 03:53:21 +08:00
2007-12-05 23:56:41 +08:00
/* {{{ spl_array_object_new_ex */
2006-04-05 03:53:21 +08:00
static zend_object_value spl_array_object_new_ex ( zend_class_entry * class_type , spl_array_object * * obj , zval * orig , int clone_orig TSRMLS_DC )
2003-07-20 04:54:22 +08:00
{
zend_object_value retval ;
spl_array_object * intern ;
zval * tmp ;
2005-03-03 18:35:34 +08:00
zend_class_entry * parent = class_type ;
int inherited = 0 ;
2003-07-20 04:54:22 +08:00
intern = emalloc ( sizeof ( spl_array_object ) ) ;
memset ( intern , 0 , sizeof ( spl_array_object ) ) ;
* obj = intern ;
2005-06-20 11:02:52 +08:00
ALLOC_INIT_ZVAL ( intern - > retval ) ;
2003-07-20 04:54:22 +08:00
2006-03-29 22:28:43 +08:00
zend_object_std_init ( & intern - > std , class_type TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
zend_hash_copy ( intern - > std . properties , & class_type - > default_properties , ( copy_ctor_func_t ) zval_add_ref , ( void * ) & tmp , sizeof ( zval * ) ) ;
2005-05-19 23:52:02 +08:00
intern - > ar_flags = 0 ;
2008-08-26 02:40:44 +08:00
intern - > serialize_data = NULL ;
intern - > unserialize_data = NULL ;
2009-08-14 06:07:05 +08:00
intern - > debug_info = NULL ;
2006-04-05 03:53:21 +08:00
intern - > ce_get_iterator = spl_ce_ArrayIterator ;
2003-07-20 04:54:22 +08:00
if ( orig ) {
2005-06-20 08:19:18 +08:00
spl_array_object * other = ( spl_array_object * ) zend_object_store_get_object ( orig TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
intern - > ar_flags & = ~ SPL_ARRAY_CLONE_MASK ;
2006-04-05 03:53:21 +08:00
intern - > ar_flags | = ( other - > ar_flags & SPL_ARRAY_CLONE_MASK ) ;
intern - > ce_get_iterator = other - > ce_get_iterator ;
if ( clone_orig ) {
intern - > array = other - > array ;
if ( Z_OBJ_HT_P ( orig ) = = & spl_handler_ArrayObject ) {
2006-04-08 06:53:23 +08:00
MAKE_STD_ZVAL ( intern - > array ) ;
array_init ( intern - > array ) ;
zend_hash_copy ( HASH_OF ( intern - > array ) , HASH_OF ( other - > array ) , ( copy_ctor_func_t ) zval_add_ref , & tmp , sizeof ( zval * ) ) ;
}
if ( Z_OBJ_HT_P ( orig ) = = & spl_handler_ArrayIterator ) {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( other - > array ) ;
2006-04-05 03:53:21 +08:00
}
} else {
intern - > array = orig ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( intern - > array ) ;
2006-04-05 03:53:21 +08:00
intern - > ar_flags | = SPL_ARRAY_IS_REF | SPL_ARRAY_USE_OTHER ;
}
2003-07-20 04:54:22 +08:00
} else {
MAKE_STD_ZVAL ( intern - > array ) ;
array_init ( intern - > array ) ;
2005-05-19 23:52:02 +08:00
intern - > ar_flags & = ~ SPL_ARRAY_IS_REF ;
2003-07-20 04:54:22 +08:00
}
2005-11-15 06:03:02 +08:00
retval . handle = zend_objects_store_put ( intern , ( zend_objects_store_dtor_t ) zend_objects_destroy_object , ( zend_objects_free_object_storage_t ) spl_array_object_free_storage , NULL TSRMLS_CC ) ;
2005-03-03 18:35:34 +08:00
while ( parent ) {
2006-04-05 03:53:21 +08:00
if ( parent = = spl_ce_ArrayIterator | | parent = = spl_ce_RecursiveArrayIterator ) {
2005-03-03 18:35:34 +08:00
retval . handlers = & spl_handler_ArrayIterator ;
2006-05-10 08:03:38 +08:00
class_type - > get_iterator = spl_array_get_iterator ;
2005-03-03 18:35:34 +08:00
break ;
} else if ( parent = = spl_ce_ArrayObject ) {
retval . handlers = & spl_handler_ArrayObject ;
break ;
}
parent = parent - > parent ;
inherited = 1 ;
}
if ( ! parent ) { /* this must never happen */
2006-04-05 03:53:21 +08:00
php_error_docref ( NULL TSRMLS_CC , E_COMPILE_ERROR , " Internal compiler error, Class is not child of ArrayObject or ArrayIterator " ) ;
2005-03-03 18:35:34 +08:00
}
if ( inherited ) {
zend_hash_find ( & class_type - > function_table , " offsetget " , sizeof ( " offsetget " ) , ( void * * ) & intern - > fptr_offset_get ) ;
if ( intern - > fptr_offset_get - > common . scope = = parent ) {
intern - > fptr_offset_get = NULL ;
}
zend_hash_find ( & class_type - > function_table , " offsetset " , sizeof ( " offsetset " ) , ( void * * ) & intern - > fptr_offset_set ) ;
if ( intern - > fptr_offset_set - > common . scope = = parent ) {
intern - > fptr_offset_set = NULL ;
}
zend_hash_find ( & class_type - > function_table , " offsetexists " , sizeof ( " offsetexists " ) , ( void * * ) & intern - > fptr_offset_has ) ;
if ( intern - > fptr_offset_has - > common . scope = = parent ) {
intern - > fptr_offset_has = NULL ;
}
zend_hash_find ( & class_type - > function_table , " offsetunset " , sizeof ( " offsetunset " ) , ( void * * ) & intern - > fptr_offset_del ) ;
if ( intern - > fptr_offset_del - > common . scope = = parent ) {
intern - > fptr_offset_del = NULL ;
}
2008-07-07 07:45:56 +08:00
zend_hash_find ( & class_type - > function_table , " count " , sizeof ( " count " ) , ( void * * ) & intern - > fptr_count ) ;
if ( intern - > fptr_count - > common . scope = = parent ) {
intern - > fptr_count = NULL ;
}
2008-08-26 02:40:44 +08:00
zend_hash_find ( & class_type - > function_table , " serialize " , sizeof ( " serialize " ) , ( void * * ) & intern - > fptr_serialize ) ;
if ( intern - > fptr_serialize - > common . scope = = parent ) {
intern - > fptr_serialize = NULL ;
}
zend_hash_find ( & class_type - > function_table , " unserialize " , sizeof ( " unserialize " ) , ( void * * ) & intern - > fptr_unserialize ) ;
if ( intern - > fptr_unserialize - > common . scope = = parent ) {
intern - > fptr_unserialize = NULL ;
}
2003-07-20 09:22:03 +08:00
}
2006-05-10 08:03:38 +08:00
/* Cache iterator functions if ArrayIterator or derived. Check current's */
/* cache since only current is always required */
if ( retval . handlers = = & spl_handler_ArrayIterator ) {
if ( ! class_type - > iterator_funcs . zf_current ) {
zend_hash_find ( & class_type - > function_table , " rewind " , sizeof ( " rewind " ) , ( void * * ) & class_type - > iterator_funcs . zf_rewind ) ;
zend_hash_find ( & class_type - > function_table , " valid " , sizeof ( " valid " ) , ( void * * ) & class_type - > iterator_funcs . zf_valid ) ;
zend_hash_find ( & class_type - > function_table , " key " , sizeof ( " key " ) , ( void * * ) & class_type - > iterator_funcs . zf_key ) ;
zend_hash_find ( & class_type - > function_table , " current " , sizeof ( " current " ) , ( void * * ) & class_type - > iterator_funcs . zf_current ) ;
zend_hash_find ( & class_type - > function_table , " next " , sizeof ( " next " ) , ( void * * ) & class_type - > iterator_funcs . zf_next ) ;
}
if ( inherited ) {
if ( class_type - > iterator_funcs . zf_rewind - > common . scope ! = parent ) intern - > ar_flags | = SPL_ARRAY_OVERLOADED_REWIND ;
if ( class_type - > iterator_funcs . zf_valid - > common . scope ! = parent ) intern - > ar_flags | = SPL_ARRAY_OVERLOADED_VALID ;
if ( class_type - > iterator_funcs . zf_key - > common . scope ! = parent ) intern - > ar_flags | = SPL_ARRAY_OVERLOADED_KEY ;
if ( class_type - > iterator_funcs . zf_current - > common . scope ! = parent ) intern - > ar_flags | = SPL_ARRAY_OVERLOADED_CURRENT ;
if ( class_type - > iterator_funcs . zf_next - > common . scope ! = parent ) intern - > ar_flags | = SPL_ARRAY_OVERLOADED_NEXT ;
}
}
2008-07-24 23:54:41 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
return retval ;
}
/* }}} */
/* {{{ spl_array_object_new */
static zend_object_value spl_array_object_new ( zend_class_entry * class_type TSRMLS_DC )
{
spl_array_object * tmp ;
2006-04-05 03:53:21 +08:00
return spl_array_object_new_ex ( class_type , & tmp , NULL , 0 TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
}
/* }}} */
/* {{{ spl_array_object_clone */
static zend_object_value spl_array_object_clone ( zval * zobject TSRMLS_DC )
{
zend_object_value new_obj_val ;
zend_object * old_object ;
zend_object * new_object ;
zend_object_handle handle = Z_OBJ_HANDLE_P ( zobject ) ;
spl_array_object * intern ;
old_object = zend_objects_get_address ( zobject TSRMLS_CC ) ;
2006-04-05 03:53:21 +08:00
new_obj_val = spl_array_object_new_ex ( old_object - > ce , & intern , zobject , 1 TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
new_object = & intern - > std ;
zend_objects_clone_members ( new_object , new_obj_val , old_object , handle TSRMLS_CC ) ;
return new_obj_val ;
}
/* }}} */
2005-05-19 23:52:02 +08:00
static zval * * spl_array_get_dimension_ptr_ptr ( int check_inherited , zval * object , zval * offset , int type TSRMLS_DC ) /* { { { */
2003-07-20 04:54:22 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
zval * * retval ;
2003-07-20 04:54:22 +08:00
long index ;
2008-10-05 22:20:55 +08:00
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
2005-05-19 23:52:02 +08:00
/* We cannot get the pointer pointer so we don't allow it here for now
2005-03-03 18:35:34 +08:00
if ( check_inherited & & intern - > fptr_offset_get ) {
2005-05-19 23:52:02 +08:00
return zend_call_method_with_1_params ( & object , Z_OBJCE_P ( object ) , & intern - > fptr_offset_get , " offsetGet " , NULL , offset ) ;
} */
2006-04-02 03:13:04 +08:00
if ( ! offset ) {
return & EG ( uninitialized_zval_ptr ) ;
}
2005-03-03 18:35:34 +08:00
2010-05-13 16:09:54 +08:00
if ( ( type = = BP_VAR_W | | type = = BP_VAR_RW ) & & ( ht - > nApplyCount > 0 ) ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return & EG ( uninitialized_zval_ptr ) ; ;
}
2003-07-20 04:54:22 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_STRING :
2008-10-05 22:20:55 +08:00
if ( zend_symtable_find ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & retval ) = = FAILURE ) {
if ( type = = BP_VAR_W | | type = = BP_VAR_RW ) {
zval * value ;
ALLOC_INIT_ZVAL ( value ) ;
zend_symtable_update ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
zend_symtable_find ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & retval ) ;
return retval ;
} else {
zend_error ( E_NOTICE , " Undefined index: %s " , Z_STRVAL_P ( offset ) ) ;
return & EG ( uninitialized_zval_ptr ) ;
}
2003-07-25 04:28:15 +08:00
} else {
2005-05-19 23:52:02 +08:00
return retval ;
2003-07-20 04:54:22 +08:00
}
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) Z_DVAL_P ( offset ) ;
2003-07-25 04:28:15 +08:00
} else {
2003-07-20 04:54:22 +08:00
index = Z_LVAL_P ( offset ) ;
}
2008-10-05 22:20:55 +08:00
if ( zend_hash_index_find ( ht , index , ( void * * ) & retval ) = = FAILURE ) {
if ( type = = BP_VAR_W | | type = = BP_VAR_RW ) {
zval * value ;
ALLOC_INIT_ZVAL ( value ) ;
zend_hash_index_update ( ht , index , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
zend_hash_index_find ( ht , index , ( void * * ) & retval ) ;
return retval ;
} else {
2009-03-19 11:01:37 +08:00
zend_error ( E_NOTICE , " Undefined offset: %ld " , index ) ;
2008-10-05 22:20:55 +08:00
return & EG ( uninitialized_zval_ptr ) ;
}
2003-07-20 04:54:22 +08:00
} else {
2005-05-19 23:52:02 +08:00
return retval ;
2003-07-20 04:54:22 +08:00
}
break ;
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
2005-05-19 23:52:02 +08:00
return & EG ( uninitialized_zval_ptr ) ;
2003-07-20 04:54:22 +08:00
}
2005-03-03 18:35:34 +08:00
} /* }}} */
2005-05-19 23:52:02 +08:00
static zval * spl_array_read_dimension_ex ( int check_inherited , zval * object , zval * offset , int type TSRMLS_DC ) /* { { { */
{
2006-10-20 10:11:19 +08:00
zval * * ret ;
2005-05-19 23:52:02 +08:00
if ( check_inherited ) {
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( intern - > fptr_offset_get ) {
zval * rv ;
2006-03-23 19:42:32 +08:00
SEPARATE_ARG_IF_REF ( offset ) ;
2005-06-20 11:02:52 +08:00
zend_call_method_with_1_params ( & object , Z_OBJCE_P ( object ) , & intern - > fptr_offset_get , " offsetGet " , & rv , offset ) ;
2006-03-23 19:42:32 +08:00
zval_ptr_dtor ( & offset ) ;
2006-03-23 05:56:40 +08:00
if ( rv ) {
2006-03-23 07:12:03 +08:00
zval_ptr_dtor ( & intern - > retval ) ;
MAKE_STD_ZVAL ( intern - > retval ) ;
2006-03-23 05:56:40 +08:00
ZVAL_ZVAL ( intern - > retval , rv , 1 , 1 ) ;
2006-03-23 07:12:03 +08:00
return intern - > retval ;
2006-03-23 05:56:40 +08:00
}
2006-03-23 07:12:03 +08:00
return EG ( uninitialized_zval_ptr ) ;
2005-05-19 23:52:02 +08:00
}
}
2006-10-20 10:11:19 +08:00
ret = spl_array_get_dimension_ptr_ptr ( check_inherited , object , offset , type TSRMLS_CC ) ;
/* When in a write context,
* ZE has to be fooled into thinking this is in a reference set
* by separating ( if necessary ) and returning as an is_ref = 1 zval ( even if refcount = = 1 ) */
2007-10-07 13:22:07 +08:00
if ( ( type = = BP_VAR_W | | type = = BP_VAR_RW ) & & ! Z_ISREF_PP ( ret ) ) {
if ( Z_REFCOUNT_PP ( ret ) > 1 ) {
2006-10-20 10:11:19 +08:00
zval * newval ;
/* Separate */
MAKE_STD_ZVAL ( newval ) ;
* newval = * * ret ;
zval_copy_ctor ( newval ) ;
2007-10-07 13:22:07 +08:00
Z_SET_REFCOUNT_P ( newval , 1 ) ;
2006-10-20 10:11:19 +08:00
/* Replace */
2007-10-07 13:22:07 +08:00
Z_DELREF_PP ( ret ) ;
2006-10-20 10:11:19 +08:00
* ret = newval ;
}
2007-10-07 13:22:07 +08:00
Z_SET_ISREF_PP ( ret ) ;
2006-10-20 10:11:19 +08:00
}
return * ret ;
2005-05-19 23:52:02 +08:00
} /* }}} */
2005-03-03 18:35:34 +08:00
static zval * spl_array_read_dimension ( zval * object , zval * offset , int type TSRMLS_DC ) /* { { { */
{
return spl_array_read_dimension_ex ( 1 , object , offset , type TSRMLS_CC ) ;
} /* }}} */
2003-07-20 04:54:22 +08:00
2005-03-03 18:35:34 +08:00
static void spl_array_write_dimension_ex ( int check_inherited , zval * object , zval * offset , zval * value TSRMLS_DC ) /* { { { */
2003-07-20 04:54:22 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
long index ;
2010-05-13 16:09:54 +08:00
HashTable * ht ;
2003-07-20 04:54:22 +08:00
2005-03-03 18:35:34 +08:00
if ( check_inherited & & intern - > fptr_offset_set ) {
2005-06-20 11:02:52 +08:00
if ( ! offset ) {
ALLOC_INIT_ZVAL ( offset ) ;
} else {
2006-03-23 19:42:32 +08:00
SEPARATE_ARG_IF_REF ( offset ) ;
2005-06-20 11:02:52 +08:00
}
zend_call_method_with_2_params ( & object , Z_OBJCE_P ( object ) , & intern - > fptr_offset_set , " offsetSet " , NULL , offset , value ) ;
2006-03-23 19:42:32 +08:00
zval_ptr_dtor ( & offset ) ;
2005-03-03 18:35:34 +08:00
return ;
}
2004-03-14 04:01:00 +08:00
if ( ! offset ) {
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2010-05-13 16:09:54 +08:00
zend_hash_next_index_insert ( ht , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
2004-03-14 04:01:00 +08:00
return ;
}
2003-07-20 04:54:22 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_STRING :
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2010-05-13 16:09:54 +08:00
zend_symtable_update ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
2003-07-25 04:28:15 +08:00
return ;
2003-07-20 04:54:22 +08:00
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
2003-07-20 04:54:22 +08:00
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) Z_DVAL_P ( offset ) ;
2003-07-25 04:28:15 +08:00
} else {
2003-07-20 04:54:22 +08:00
index = Z_LVAL_P ( offset ) ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2010-05-13 16:09:54 +08:00
zend_hash_index_update ( ht , index , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
2003-07-20 04:54:22 +08:00
return ;
2005-06-20 11:02:52 +08:00
case IS_NULL :
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2010-05-13 16:09:54 +08:00
zend_hash_next_index_insert ( ht , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
2005-06-20 11:02:52 +08:00
return ;
2003-07-20 04:54:22 +08:00
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
return ;
}
2005-03-03 18:35:34 +08:00
} /* }}} */
2003-07-20 04:54:22 +08:00
2005-03-03 18:35:34 +08:00
static void spl_array_write_dimension ( zval * object , zval * offset , zval * value TSRMLS_DC ) /* { { { */
{
2005-03-09 05:33:15 +08:00
spl_array_write_dimension_ex ( 1 , object , offset , value TSRMLS_CC ) ;
2005-03-03 18:35:34 +08:00
} /* }}} */
static void spl_array_unset_dimension_ex ( int check_inherited , zval * object , zval * offset TSRMLS_DC ) /* { { { */
2003-08-05 04:17:53 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
long index ;
2010-05-13 16:09:54 +08:00
HashTable * ht ;
2005-03-03 18:35:34 +08:00
if ( check_inherited & & intern - > fptr_offset_del ) {
2006-03-23 19:42:32 +08:00
SEPARATE_ARG_IF_REF ( offset ) ;
2005-06-20 11:02:52 +08:00
zend_call_method_with_1_params ( & object , Z_OBJCE_P ( object ) , & intern - > fptr_offset_del , " offsetUnset " , NULL , offset ) ;
2006-03-23 19:42:32 +08:00
zval_ptr_dtor ( & offset ) ;
2005-03-03 18:35:34 +08:00
return ;
}
2003-08-05 04:17:53 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_STRING :
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
if ( ht = = & EG ( symbol_table ) ) {
2004-10-05 04:17:06 +08:00
if ( zend_delete_global_variable ( Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) TSRMLS_CC ) ) {
2004-10-05 03:54:35 +08:00
zend_error ( E_NOTICE , " Undefined index: %s " , Z_STRVAL_P ( offset ) ) ;
}
} else {
2010-05-13 16:09:54 +08:00
if ( zend_symtable_del ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 ) = = FAILURE ) {
2004-10-05 03:54:35 +08:00
zend_error ( E_NOTICE , " Undefined index: %s " , Z_STRVAL_P ( offset ) ) ;
}
2003-08-05 04:17:53 +08:00
}
2005-03-22 04:07:33 +08:00
break ;
2003-08-05 04:17:53 +08:00
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) Z_DVAL_P ( offset ) ;
} else {
index = Z_LVAL_P ( offset ) ;
}
2010-05-13 16:09:54 +08:00
ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( ht - > nApplyCount > 0 ) {
zend_error ( E_WARNING , " Modification of ArrayObject during sorting is prohibited " ) ;
return ;
}
if ( zend_hash_index_del ( ht , index ) = = FAILURE ) {
2003-09-04 22:44:55 +08:00
zend_error ( E_NOTICE , " Undefined offset: %ld " , Z_LVAL_P ( offset ) ) ;
2003-08-05 04:17:53 +08:00
}
2005-03-22 04:07:33 +08:00
break ;
2003-08-05 04:17:53 +08:00
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
return ;
}
2005-03-22 04:07:33 +08:00
spl_hash_verify_pos ( intern TSRMLS_CC ) ; /* call rewind on FAILURE */
2005-03-03 18:35:34 +08:00
} /* }}} */
2003-08-05 04:17:53 +08:00
2005-03-03 18:35:34 +08:00
static void spl_array_unset_dimension ( zval * object , zval * offset TSRMLS_DC ) /* { { { */
{
2005-03-09 05:33:15 +08:00
spl_array_unset_dimension_ex ( 1 , object , offset TSRMLS_CC ) ;
2005-03-03 18:35:34 +08:00
} /* }}} */
static int spl_array_has_dimension_ex ( int check_inherited , zval * object , zval * offset , int check_empty TSRMLS_DC ) /* { { { */
2003-11-17 13:25:47 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
long index ;
2007-03-21 04:28:08 +08:00
zval * rv , * * tmp ;
2003-11-17 13:25:47 +08:00
2005-03-03 18:35:34 +08:00
if ( check_inherited & & intern - > fptr_offset_has ) {
2006-03-23 19:42:32 +08:00
SEPARATE_ARG_IF_REF ( offset ) ;
2005-03-03 18:35:34 +08:00
zend_call_method_with_1_params ( & object , Z_OBJCE_P ( object ) , & intern - > fptr_offset_has , " offsetExists " , & rv , offset ) ;
2006-03-23 19:42:32 +08:00
zval_ptr_dtor ( & offset ) ;
2006-03-23 05:56:40 +08:00
if ( rv & & zend_is_true ( rv ) ) {
2005-03-03 18:35:34 +08:00
zval_ptr_dtor ( & rv ) ;
return 1 ;
}
2006-03-23 05:56:40 +08:00
if ( rv ) {
zval_ptr_dtor ( & rv ) ;
}
2005-03-03 18:35:34 +08:00
return 0 ;
}
2003-11-17 13:25:47 +08:00
switch ( Z_TYPE_P ( offset ) ) {
2012-03-11 16:27:55 +08:00
case IS_STRING :
{
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( zend_symtable_find ( ht , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & tmp ) ! = FAILURE ) {
switch ( check_empty ) {
case 0 :
return Z_TYPE_PP ( tmp ) ! = IS_NULL ;
case 2 :
return 1 ;
default :
return zend_is_true ( * tmp ) ;
}
2010-12-11 07:58:33 +08:00
}
2012-03-11 16:27:55 +08:00
return 0 ;
2007-01-07 11:52:44 +08:00
}
2012-03-11 16:27:55 +08:00
case IS_DOUBLE :
case IS_RESOURCE :
case IS_BOOL :
case IS_LONG :
{
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( offset - > type = = IS_DOUBLE ) {
index = ( long ) Z_DVAL_P ( offset ) ;
} else {
index = Z_LVAL_P ( offset ) ;
}
if ( zend_hash_index_find ( ht , index , ( void * * ) & tmp ) ! = FAILURE ) {
switch ( check_empty ) {
case 0 :
return Z_TYPE_PP ( tmp ) ! = IS_NULL ;
case 2 :
return 1 ;
default :
return zend_is_true ( * tmp ) ;
}
2010-12-11 07:58:33 +08:00
}
2012-03-11 16:27:55 +08:00
return 0 ;
2007-01-07 11:52:44 +08:00
}
2012-03-11 16:27:55 +08:00
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
2003-11-17 13:25:47 +08:00
}
return 0 ;
2005-03-03 18:35:34 +08:00
} /* }}} */
static int spl_array_has_dimension ( zval * object , zval * offset , int check_empty TSRMLS_DC ) /* { { { */
{
return spl_array_has_dimension_ex ( 1 , object , offset , check_empty TSRMLS_CC ) ;
} /* }}} */
2003-11-17 13:25:47 +08:00
2004-04-25 19:14:11 +08:00
/* {{{ proto bool ArrayObject::offsetExists(mixed $index)
2004-04-30 06:52:49 +08:00
proto bool ArrayIterator : : offsetExists ( mixed $ index )
2008-08-26 03:07:20 +08:00
Returns whether the requested $ index exists . */
2004-04-25 19:14:11 +08:00
SPL_METHOD ( Array , offsetExists )
{
zval * index ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & index ) = = FAILURE ) {
return ;
}
2012-03-28 20:04:41 +08:00
RETURN_BOOL ( spl_array_has_dimension_ex ( 0 , getThis ( ) , index , 2 TSRMLS_CC ) ) ;
2004-04-25 19:14:11 +08:00
} /* }}} */
2006-08-12 01:05:23 +08:00
/* {{{ proto mixed ArrayObject::offsetGet(mixed $index)
proto mixed ArrayIterator : : offsetGet ( mixed $ index )
2008-08-26 03:07:20 +08:00
Returns the value at the specified $ index . */
2004-04-25 19:14:11 +08:00
SPL_METHOD ( Array , offsetGet )
{
zval * index , * value ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & index ) = = FAILURE ) {
return ;
}
2005-03-03 18:35:34 +08:00
value = spl_array_read_dimension_ex ( 0 , getThis ( ) , index , BP_VAR_R TSRMLS_CC ) ;
2004-06-21 00:46:27 +08:00
RETURN_ZVAL ( value , 1 , 0 ) ;
2004-04-25 19:14:11 +08:00
} /* }}} */
2004-04-30 06:52:49 +08:00
/* {{{ proto void ArrayObject::offsetSet(mixed $index, mixed $newval)
proto void ArrayIterator : : offsetSet ( mixed $ index , mixed $ newval )
2008-08-26 03:07:20 +08:00
Sets the value at the specified $ index to $ newval . */
2004-04-25 19:14:11 +08:00
SPL_METHOD ( Array , offsetSet )
{
2005-09-19 01:15:04 +08:00
zval * index , * value ;
2004-04-25 19:14:11 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " zz " , & index , & value ) = = FAILURE ) {
return ;
}
2005-03-03 18:35:34 +08:00
spl_array_write_dimension_ex ( 0 , getThis ( ) , index , value TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
} /* }}} */
2004-11-01 08:26:59 +08:00
void spl_array_iterator_append ( zval * object , zval * append_value TSRMLS_DC ) /* { { { */
2004-04-25 21:04:36 +08:00
{
2004-04-30 06:25:45 +08:00
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2004-04-30 06:25:45 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
if ( Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
2006-05-11 16:06:22 +08:00
php_error_docref ( NULL TSRMLS_CC , E_RECOVERABLE_ERROR , " Cannot append properties to objects, use %s::offsetSet() instead " , Z_OBJCE_P ( object ) - > name ) ;
2006-03-06 01:39:49 +08:00
return ;
2004-04-30 06:25:45 +08:00
}
2004-11-01 08:26:59 +08:00
spl_array_write_dimension ( object , NULL , append_value TSRMLS_CC ) ;
2004-04-30 06:25:45 +08:00
if ( ! intern - > pos ) {
2008-11-19 22:41:40 +08:00
spl_array_set_pos ( intern , aht - > pListTail ) ;
2004-04-30 06:25:45 +08:00
}
2004-04-25 21:04:36 +08:00
} /* }}} */
2004-11-01 08:26:59 +08:00
/* {{{ proto void ArrayObject::append(mixed $newval)
proto void ArrayIterator : : append ( mixed $ newval )
2008-08-26 03:07:20 +08:00
Appends the value ( cannot be called for objects ) . */
2004-11-01 08:26:59 +08:00
SPL_METHOD ( Array , append )
{
zval * value ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & value ) = = FAILURE ) {
return ;
}
spl_array_iterator_append ( getThis ( ) , value TSRMLS_CC ) ;
} /* }}} */
2004-04-30 06:52:49 +08:00
/* {{{ proto void ArrayObject::offsetUnset(mixed $index)
proto void ArrayIterator : : offsetUnset ( mixed $ index )
2008-08-26 03:07:20 +08:00
Unsets the value at the specified $ index . */
2004-04-25 19:14:11 +08:00
SPL_METHOD ( Array , offsetUnset )
{
zval * index ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & index ) = = FAILURE ) {
return ;
}
2005-03-03 18:35:34 +08:00
spl_array_unset_dimension_ex ( 0 , getThis ( ) , index TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
} /* }}} */
2007-12-17 21:46:27 +08:00
/* {{{ proto array ArrayObject::getArrayCopy()
2004-04-30 06:52:49 +08:00
proto array ArrayIterator : : getArrayCopy ( )
2008-08-26 03:07:20 +08:00
Return a copy of the contained array */
2004-04-25 19:14:11 +08:00
SPL_METHOD ( Array , getArrayCopy )
{
zval * object = getThis ( ) , * tmp ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
array_init ( return_value ) ;
2005-06-20 08:19:18 +08:00
zend_hash_copy ( HASH_OF ( return_value ) , spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , ( copy_ctor_func_t ) zval_add_ref , & tmp , sizeof ( zval * ) ) ;
2004-04-25 19:14:11 +08:00
} /* }}} */
2005-05-19 23:52:02 +08:00
static HashTable * spl_array_get_properties ( zval * object TSRMLS_DC ) /* { { { */
2003-07-20 04:54:22 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2011-11-18 13:22:35 +08:00
HashTable * result ;
2003-07-20 04:54:22 +08:00
2011-11-18 13:22:35 +08:00
if ( intern - > nApplyCount > 1 ) {
php_error_docref ( NULL TSRMLS_CC , E_ERROR , " Nesting level too deep - recursive dependency? " ) ;
}
intern - > nApplyCount + + ;
result = spl_array_get_hash_table ( intern , 1 TSRMLS_CC ) ;
intern - > nApplyCount - - ;
return result ;
2005-05-19 23:52:02 +08:00
} /* }}} */
2007-11-03 03:40:39 +08:00
static HashTable * spl_array_get_debug_info ( zval * obj , int * is_temp TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( obj TSRMLS_CC ) ;
zval * tmp , * storage ;
int name_len ;
char * zname ;
zend_class_entry * base ;
2009-08-14 06:07:05 +08:00
* is_temp = 0 ;
2007-11-03 03:40:39 +08:00
if ( HASH_OF ( intern - > array ) = = intern - > std . properties ) {
return intern - > std . properties ;
} else {
2009-08-14 06:07:05 +08:00
if ( intern - > debug_info = = NULL ) {
ALLOC_HASHTABLE ( intern - > debug_info ) ;
ZEND_INIT_SYMTABLE_EX ( intern - > debug_info , zend_hash_num_elements ( intern - > std . properties ) + 1 , 0 ) ;
}
2007-11-03 03:40:39 +08:00
2009-08-14 06:07:05 +08:00
if ( intern - > debug_info - > nApplyCount = = 0 ) {
2009-09-22 15:54:06 +08:00
zend_hash_clean ( intern - > debug_info ) ;
2009-08-14 06:07:05 +08:00
zend_hash_copy ( intern - > debug_info , intern - > std . properties , ( copy_ctor_func_t ) zval_add_ref , ( void * ) & tmp , sizeof ( zval * ) ) ;
2007-11-03 03:40:39 +08:00
2009-08-14 06:07:05 +08:00
storage = intern - > array ;
zval_add_ref ( & storage ) ;
2007-11-03 03:40:39 +08:00
2009-08-14 06:07:05 +08:00
base = ( Z_OBJ_HT_P ( obj ) = = & spl_handler_ArrayIterator ) ? spl_ce_ArrayIterator : spl_ce_ArrayObject ;
zname = spl_gen_private_prop_name ( base , " storage " , sizeof ( " storage " ) - 1 , & name_len TSRMLS_CC ) ;
zend_symtable_update ( intern - > debug_info , zname , name_len + 1 , & storage , sizeof ( zval * ) , NULL ) ;
efree ( zname ) ;
}
2007-11-03 03:40:39 +08:00
2009-08-14 06:07:05 +08:00
return intern - > debug_info ;
2007-11-03 03:40:39 +08:00
}
}
/* }}} */
2005-05-19 23:52:02 +08:00
static zval * spl_array_read_property ( zval * object , zval * member , int type TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0
& & ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
return spl_array_read_dimension ( object , member , type TSRMLS_CC ) ;
}
return std_object_handlers . read_property ( object , member , type TSRMLS_CC ) ;
} /* }}} */
static void spl_array_write_property ( zval * object , zval * member , zval * value TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0
& & ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
2005-05-25 01:59:42 +08:00
spl_array_write_dimension ( object , member , value TSRMLS_CC ) ;
return ;
2005-05-19 23:52:02 +08:00
}
std_object_handlers . write_property ( object , member , value TSRMLS_CC ) ;
} /* }}} */
static zval * * spl_array_get_property_ptr_ptr ( zval * object , zval * member TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0
& & ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
2010-05-13 16:09:54 +08:00
return spl_array_get_dimension_ptr_ptr ( 1 , object , member , BP_VAR_RW TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
}
return std_object_handlers . get_property_ptr_ptr ( object , member TSRMLS_CC ) ;
} /* }}} */
static int spl_array_has_property ( zval * object , zval * member , int has_set_exists TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2009-05-21 21:26:14 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0
& & ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
2008-07-26 20:34:10 +08:00
return spl_array_has_dimension ( object , member , has_set_exists TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
}
2009-05-21 21:26:14 +08:00
return std_object_handlers . has_property ( object , member , has_set_exists TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
} /* }}} */
static void spl_array_unset_property ( zval * object , zval * member TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0
& & ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
spl_array_unset_dimension ( object , member TSRMLS_CC ) ;
spl_array_rewind ( intern TSRMLS_CC ) ; /* because deletion might invalidate position */
return ;
}
std_object_handlers . unset_property ( object , member TSRMLS_CC ) ;
} /* }}} */
2003-07-20 04:54:22 +08:00
2012-03-11 01:19:39 +08:00
static int spl_array_compare_objects ( zval * o1 , zval * o2 TSRMLS_DC ) /* { { { */
{
HashTable * ht1 ,
* ht2 ;
spl_array_object * intern1 ,
* intern2 ;
int result = 0 ;
zval temp_zv ;
intern1 = ( spl_array_object * ) zend_object_store_get_object ( o1 TSRMLS_CC ) ;
intern2 = ( spl_array_object * ) zend_object_store_get_object ( o2 TSRMLS_CC ) ;
ht1 = spl_array_get_hash_table ( intern1 , 0 TSRMLS_CC ) ;
ht2 = spl_array_get_hash_table ( intern2 , 0 TSRMLS_CC ) ;
zend_compare_symbol_tables ( & temp_zv , ht1 , ht2 TSRMLS_CC ) ;
result = ( int ) Z_LVAL ( temp_zv ) ;
/* if we just compared std.properties, don't do it again */
if ( result = = 0 & &
! ( ht1 = = intern1 - > std . properties & & ht2 = = intern2 - > std . properties ) ) {
result = std_object_handlers . compare_objects ( o1 , o2 TSRMLS_CC ) ;
}
return result ;
} /* }}} */
2008-11-19 22:41:40 +08:00
static int spl_array_skip_protected ( spl_array_object * intern , HashTable * aht TSRMLS_DC ) /* { { { */
2004-04-25 19:14:11 +08:00
{
char * string_key ;
uint string_length ;
ulong num_key ;
if ( Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
do {
if ( zend_hash_get_current_key_ex ( aht , & string_key , & string_length , & num_key , 0 , & intern - > pos ) = = HASH_KEY_IS_STRING ) {
if ( ! string_length | | string_key [ 0 ] ) {
2004-04-27 23:42:45 +08:00
return SUCCESS ;
2004-04-25 19:14:11 +08:00
}
} else {
2004-04-27 23:42:45 +08:00
return SUCCESS ;
2004-04-25 19:14:11 +08:00
}
if ( zend_hash_has_more_elements_ex ( aht , & intern - > pos ) ! = SUCCESS ) {
2004-04-27 23:42:45 +08:00
return FAILURE ;
2004-04-25 19:14:11 +08:00
}
zend_hash_move_forward_ex ( aht , & intern - > pos ) ;
2008-11-19 22:41:40 +08:00
spl_array_update_pos ( intern ) ;
2004-04-25 19:14:11 +08:00
} while ( 1 ) ;
}
2004-04-27 23:42:45 +08:00
return FAILURE ;
2008-11-19 22:41:40 +08:00
} /* }}} */
2004-04-25 19:14:11 +08:00
2008-11-19 22:41:40 +08:00
static int spl_array_next_no_verify ( spl_array_object * intern , HashTable * aht TSRMLS_DC ) /* { { { */
2004-04-27 23:42:45 +08:00
{
2008-11-19 22:41:40 +08:00
zend_hash_move_forward_ex ( aht , & intern - > pos ) ;
spl_array_update_pos ( intern ) ;
if ( Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
return spl_array_skip_protected ( intern , aht TSRMLS_CC ) ;
} else {
return zend_hash_has_more_elements_ex ( aht , & intern - > pos ) ;
}
} /* }}} */
2004-04-27 23:42:45 +08:00
2008-11-19 22:41:40 +08:00
static int spl_array_next_ex ( spl_array_object * intern , HashTable * aht TSRMLS_DC ) /* { { { */
{
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2005-01-27 08:22:06 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
return FAILURE ;
2004-04-27 23:42:45 +08:00
}
2008-11-19 22:41:40 +08:00
return spl_array_next_no_verify ( intern , aht TSRMLS_CC ) ;
} /* }}} */
static int spl_array_next ( spl_array_object * intern TSRMLS_DC ) /* { { { */
{
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
return spl_array_next_ex ( intern , aht TSRMLS_CC ) ;
2004-04-27 23:42:45 +08:00
} /* }}} */
2004-04-25 19:14:11 +08:00
/* define an overloaded iterator structure */
typedef struct {
2006-05-10 08:03:38 +08:00
zend_user_iterator intern ;
2004-04-25 19:14:11 +08:00
spl_array_object * object ;
} spl_array_it ;
static void spl_array_it_dtor ( zend_object_iterator * iter TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
2006-05-10 08:03:38 +08:00
zend_user_it_invalidate_current ( iter TSRMLS_CC ) ;
zval_ptr_dtor ( ( zval * * ) & iterator - > intern . it . data ) ;
2004-04-25 19:14:11 +08:00
efree ( iterator ) ;
}
/* }}} */
static int spl_array_it_valid ( zend_object_iterator * iter TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
spl_array_object * object = iterator - > object ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( object , 0 TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
2006-05-10 08:03:38 +08:00
if ( object - > ar_flags & SPL_ARRAY_OVERLOADED_VALID ) {
return zend_user_it_valid ( iter TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
} else {
2006-05-10 08:03:38 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::valid(): Array was modified outside object and is no longer an array " ) ;
return FAILURE ;
}
2008-11-19 22:41:40 +08:00
if ( object - > pos & & ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( object , aht TSRMLS_CC ) = = FAILURE ) {
2006-05-10 08:03:38 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::valid(): Array was modified outside object and internal position is no longer valid " ) ;
return FAILURE ;
} else {
return zend_hash_has_more_elements_ex ( aht , & object - > pos ) ;
}
2004-04-25 19:14:11 +08:00
}
}
/* }}} */
static void spl_array_it_get_current_data ( zend_object_iterator * iter , zval * * * data TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
spl_array_object * object = iterator - > object ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( object , 0 TSRMLS_CC ) ;
2006-05-10 08:03:38 +08:00
if ( object - > ar_flags & SPL_ARRAY_OVERLOADED_CURRENT ) {
zend_user_it_get_current_data ( iter , data TSRMLS_CC ) ;
} else {
if ( zend_hash_get_current_data_ex ( aht , ( void * * ) data , & object - > pos ) = = FAILURE ) {
* data = NULL ;
}
2004-04-25 19:14:11 +08:00
}
}
/* }}} */
static int spl_array_it_get_current_key ( zend_object_iterator * iter , char * * str_key , uint * str_key_len , ulong * int_key TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
spl_array_object * object = iterator - > object ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( object , 0 TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
2006-05-10 08:03:38 +08:00
if ( object - > ar_flags & SPL_ARRAY_OVERLOADED_KEY ) {
return zend_user_it_get_current_key ( iter , str_key , str_key_len , int_key TSRMLS_CC ) ;
} else {
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::current(): Array was modified outside object and is no longer an array " ) ;
return HASH_KEY_NON_EXISTANT ;
}
2008-11-19 22:41:40 +08:00
if ( ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( object , aht TSRMLS_CC ) = = FAILURE ) {
2006-05-10 08:03:38 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::current(): Array was modified outside object and internal position is no longer valid " ) ;
return HASH_KEY_NON_EXISTANT ;
}
return zend_hash_get_current_key_ex ( aht , str_key , str_key_len , int_key , 1 , & object - > pos ) ;
2004-04-25 19:14:11 +08:00
}
}
/* }}} */
static void spl_array_it_move_forward ( zend_object_iterator * iter TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
spl_array_object * object = iterator - > object ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( object , 0 TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
2006-05-10 08:03:38 +08:00
if ( object - > ar_flags & SPL_ARRAY_OVERLOADED_NEXT ) {
zend_user_it_move_forward ( iter TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
} else {
2006-05-10 08:03:38 +08:00
zend_user_it_invalidate_current ( iter TSRMLS_CC ) ;
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::current(): Array was modified outside object and is no longer an array " ) ;
return ;
}
2008-11-19 22:41:40 +08:00
if ( ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( object , aht TSRMLS_CC ) = = FAILURE ) {
2006-05-10 08:03:38 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::next(): Array was modified outside object and internal position is no longer valid " ) ;
} else {
2008-11-19 22:41:40 +08:00
spl_array_next_no_verify ( object , aht TSRMLS_CC ) ;
2006-05-10 08:03:38 +08:00
}
2004-04-25 19:14:11 +08:00
}
}
/* }}} */
2008-11-19 22:41:40 +08:00
static void spl_array_rewind_ex ( spl_array_object * intern , HashTable * aht TSRMLS_DC ) /* { { { */
{
zend_hash_internal_pointer_reset_ex ( aht , & intern - > pos ) ;
spl_array_update_pos ( intern ) ;
spl_array_skip_protected ( intern , aht TSRMLS_CC ) ;
} /* }}} */
2005-03-22 04:07:33 +08:00
static void spl_array_rewind ( spl_array_object * intern TSRMLS_DC ) /* { { { */
2004-04-25 19:14:11 +08:00
{
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2004-04-25 19:14:11 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::rewind(): Array was modified outside object and is no longer an array " ) ;
return ;
}
2008-11-19 22:41:40 +08:00
spl_array_rewind_ex ( intern , aht TSRMLS_CC ) ;
2005-03-22 04:07:33 +08:00
}
/* }}} */
static void spl_array_it_rewind ( zend_object_iterator * iter TSRMLS_DC ) /* { { { */
{
spl_array_it * iterator = ( spl_array_it * ) iter ;
spl_array_object * object = iterator - > object ;
2006-05-10 08:03:38 +08:00
if ( object - > ar_flags & SPL_ARRAY_OVERLOADED_REWIND ) {
zend_user_it_rewind ( iter TSRMLS_CC ) ;
} else {
zend_user_it_invalidate_current ( iter TSRMLS_CC ) ;
spl_array_rewind ( object TSRMLS_CC ) ;
}
2004-04-25 19:14:11 +08:00
}
/* }}} */
2008-08-04 19:45:21 +08:00
/* {{{ spl_array_set_array */
static void spl_array_set_array ( zval * object , spl_array_object * intern , zval * * array , long ar_flags , int just_array TSRMLS_DC ) {
if ( Z_TYPE_PP ( array ) = = IS_ARRAY ) {
SEPARATE_ZVAL_IF_NOT_REF ( array ) ;
}
if ( Z_TYPE_PP ( array ) = = IS_OBJECT & & ( Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayObject | | Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayIterator ) ) {
zval_ptr_dtor ( & intern - > array ) ;
if ( just_array ) {
spl_array_object * other = ( spl_array_object * ) zend_object_store_get_object ( * array TSRMLS_CC ) ;
ar_flags = other - > ar_flags & ~ SPL_ARRAY_INT_MASK ;
}
ar_flags | = SPL_ARRAY_USE_OTHER ;
intern - > array = * array ;
} else {
if ( Z_TYPE_PP ( array ) ! = IS_OBJECT & & Z_TYPE_PP ( array ) ! = IS_ARRAY ) {
zend_throw_exception ( spl_ce_InvalidArgumentException , " Passed variable is not an array or object, using empty array instead " , 0 TSRMLS_CC ) ;
return ;
}
zval_ptr_dtor ( & intern - > array ) ;
intern - > array = * array ;
}
if ( object = = * array ) {
intern - > ar_flags | = SPL_ARRAY_IS_SELF ;
intern - > ar_flags & = ~ SPL_ARRAY_USE_OTHER ;
} else {
intern - > ar_flags & = ~ SPL_ARRAY_IS_SELF ;
}
intern - > ar_flags | = ar_flags ;
Z_ADDREF_P ( intern - > array ) ;
if ( Z_TYPE_PP ( array ) = = IS_OBJECT ) {
zend_object_get_properties_t handler = Z_OBJ_HANDLER_PP ( array , get_properties ) ;
if ( ( handler ! = std_object_handlers . get_properties & & handler ! = spl_array_get_properties )
| | ! spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ) {
zend_throw_exception_ex ( spl_ce_InvalidArgumentException , 0 TSRMLS_CC , " Overloaded object of type %s is not compatible with %s " , Z_OBJCE_PP ( array ) - > name , intern - > std . ce - > name ) ;
}
}
spl_array_rewind ( intern TSRMLS_CC ) ;
}
/* }}} */
2004-04-25 19:14:11 +08:00
/* iterator handler table */
zend_object_iterator_funcs spl_array_it_funcs = {
spl_array_it_dtor ,
spl_array_it_valid ,
spl_array_it_get_current_data ,
spl_array_it_get_current_key ,
spl_array_it_move_forward ,
spl_array_it_rewind
} ;
2006-05-10 08:03:38 +08:00
zend_object_iterator * spl_array_get_iterator ( zend_class_entry * ce , zval * object , int by_ref TSRMLS_DC ) /* { { { */
2004-04-25 19:14:11 +08:00
{
2006-05-10 08:03:38 +08:00
spl_array_it * iterator ;
2004-04-25 19:14:11 +08:00
spl_array_object * array_object = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2006-05-10 08:03:38 +08:00
if ( by_ref & & ( array_object - > ar_flags & SPL_ARRAY_OVERLOADED_CURRENT ) ) {
zend_error ( E_ERROR , " An iterator cannot be used with foreach by reference " ) ;
}
iterator = emalloc ( sizeof ( spl_array_it ) ) ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( object ) ;
2006-05-10 08:03:38 +08:00
iterator - > intern . it . data = ( void * ) object ;
iterator - > intern . it . funcs = & spl_array_it_funcs ;
iterator - > intern . ce = ce ;
iterator - > intern . value = NULL ;
2004-04-25 19:14:11 +08:00
iterator - > object = array_object ;
return ( zend_object_iterator * ) iterator ;
}
/* }}} */
2005-09-19 01:15:04 +08:00
/* {{{ proto void ArrayObject::__construct(array|object ar = array() [, int flags = 0 [, string iterator_class = "ArrayIterator"]])
2005-05-19 23:52:02 +08:00
proto void ArrayIterator : : __construct ( array | object ar = array ( ) [ , int flags = 0 ] )
2008-08-26 03:07:20 +08:00
Constructs a new array iterator from a path . */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , __construct )
2003-07-20 04:54:22 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern ;
2007-06-27 20:30:28 +08:00
zval * * array ;
2005-05-19 23:52:02 +08:00
long ar_flags = 0 ;
2008-10-20 02:00:24 +08:00
zend_class_entry * ce_get_iterator = spl_ce_Iterator ;
2008-11-19 10:00:53 +08:00
zend_error_handling error_handling ;
2003-07-20 04:54:22 +08:00
if ( ZEND_NUM_ARGS ( ) = = 0 ) {
return ; /* nothing to do */
}
2008-08-09 06:07:07 +08:00
2008-11-19 10:00:53 +08:00
zend_replace_error_handling ( EH_THROW , spl_ce_InvalidArgumentException , & error_handling TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
2004-04-14 03:06:16 +08:00
intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2008-10-20 02:00:24 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " Z|lC " , & array , & ar_flags , & ce_get_iterator ) = = FAILURE ) {
2008-11-19 10:00:53 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
return ;
}
2005-09-19 01:15:04 +08:00
if ( ZEND_NUM_ARGS ( ) > 2 ) {
2008-10-20 02:00:24 +08:00
intern - > ce_get_iterator = ce_get_iterator ;
2005-09-19 01:15:04 +08:00
}
2005-06-20 08:19:18 +08:00
ar_flags & = ~ SPL_ARRAY_INT_MASK ;
2008-08-04 19:45:21 +08:00
spl_array_set_array ( object , intern , array , ar_flags , ZEND_NUM_ARGS ( ) = = 1 TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
2008-11-19 10:00:53 +08:00
zend_restore_error_handling ( & error_handling TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
}
2007-12-05 23:56:41 +08:00
/* }}} */
2005-05-19 23:52:02 +08:00
2005-09-19 01:15:04 +08:00
/* {{{ proto void ArrayObject::setIteratorClass(string iterator_class)
Set the class used in getIterator . */
SPL_METHOD ( Array , setIteratorClass )
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2008-10-20 02:00:24 +08:00
zend_class_entry * ce_get_iterator = spl_ce_Iterator ;
2005-09-19 01:15:04 +08:00
2008-10-20 02:00:24 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " C " , & ce_get_iterator ) = = FAILURE ) {
2005-09-19 01:15:04 +08:00
return ;
}
2008-10-20 02:00:24 +08:00
intern - > ce_get_iterator = ce_get_iterator ;
2005-09-19 01:15:04 +08:00
}
/* }}} */
/* {{{ proto string ArrayObject::getIteratorClass()
Get the class used in getIterator . */
SPL_METHOD ( Array , getIteratorClass )
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2005-09-19 01:15:04 +08:00
RETURN_STRING ( intern - > ce_get_iterator - > name , 1 ) ;
}
/* }}} */
2005-05-19 23:52:02 +08:00
/* {{{ proto int ArrayObject::getFlags()
Get flags */
SPL_METHOD ( Array , getFlags )
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2005-05-19 23:52:02 +08:00
RETURN_LONG ( intern - > ar_flags & ~ SPL_ARRAY_INT_MASK ) ;
}
/* }}} */
/* {{{ proto void ArrayObject::setFlags(int flags)
Set flags */
SPL_METHOD ( Array , setFlags )
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
long ar_flags = 0 ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & ar_flags ) = = FAILURE ) {
return ;
}
intern - > ar_flags = ( intern - > ar_flags & SPL_ARRAY_INT_MASK ) | ( ar_flags & ~ SPL_ARRAY_INT_MASK ) ;
}
/* }}} */
/* {{{ proto Array|Object ArrayObject::exchangeArray(Array|Object ar = array())
Replace the referenced array or object with a new one and return the old one ( right now copy - to be changed ) */
SPL_METHOD ( Array , exchangeArray )
{
zval * object = getThis ( ) , * tmp , * * array ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2006-03-06 01:39:49 +08:00
array_init ( return_value ) ;
2005-06-20 08:19:18 +08:00
zend_hash_copy ( HASH_OF ( return_value ) , spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , ( copy_ctor_func_t ) zval_add_ref , & tmp , sizeof ( zval * ) ) ;
2005-05-19 23:52:02 +08:00
2006-02-13 00:44:36 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " Z " , & array ) = = FAILURE ) {
2006-11-03 23:13:17 +08:00
return ;
2003-07-20 04:54:22 +08:00
}
2008-08-04 19:45:21 +08:00
spl_array_set_array ( object , intern , array , 0L , 1 TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
}
/* }}} */
2003-11-27 07:28:35 +08:00
/* {{{ proto ArrayIterator ArrayObject::getIterator()
2003-11-17 13:32:43 +08:00
Create a new iterator from a ArrayObject instance */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , getIterator )
2003-07-20 09:22:03 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
spl_array_object * iterator ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2003-07-20 09:22:03 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
return_value - > type = IS_OBJECT ;
2006-04-05 03:53:21 +08:00
return_value - > value . obj = spl_array_object_new_ex ( intern - > ce_get_iterator , & iterator , object , 0 TSRMLS_CC ) ;
2007-10-07 13:22:07 +08:00
Z_SET_REFCOUNT_P ( return_value , 1 ) ;
Z_SET_ISREF_P ( return_value ) ;
2003-07-20 09:22:03 +08:00
}
/* }}} */
2003-11-27 07:28:35 +08:00
/* {{{ proto void ArrayIterator::rewind()
2003-07-20 04:54:22 +08:00
Rewind array back to the start */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , rewind )
2003-07-20 04:54:22 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2003-07-20 09:22:03 +08:00
2005-03-22 04:07:33 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
}
/* }}} */
2004-04-30 06:52:49 +08:00
/* {{{ proto void ArrayIterator::seek(int $position)
2008-08-26 03:07:20 +08:00
Seek to position . */
2004-04-27 23:42:45 +08:00
SPL_METHOD ( Array , seek )
{
2005-03-01 18:06:11 +08:00
long opos , position ;
2004-04-27 23:42:45 +08:00
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2005-03-01 18:06:11 +08:00
int result ;
2004-04-27 23:42:45 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " l " , & position ) = = FAILURE ) {
return ;
}
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2005-03-01 18:06:11 +08:00
opos = position ;
2005-03-05 19:35:13 +08:00
if ( position > = 0 ) { /* negative values are not supported */
2008-07-24 23:54:41 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
2006-02-03 06:17:42 +08:00
result = SUCCESS ;
2005-03-05 19:35:13 +08:00
while ( position - - > 0 & & ( result = spl_array_next ( intern TSRMLS_CC ) ) = = SUCCESS ) ;
2006-02-03 06:17:42 +08:00
if ( result = = SUCCESS & & zend_hash_has_more_elements_ex ( aht , & intern - > pos ) = = SUCCESS ) {
return ; /* ok */
2005-03-01 18:06:11 +08:00
}
}
zend_throw_exception_ex ( spl_ce_OutOfBoundsException , 0 TSRMLS_CC , " Seek position %ld is out of range " , opos ) ;
2004-04-27 23:42:45 +08:00
} /* }}} */
2008-07-21 00:32:55 +08:00
int static spl_array_object_count_elements_helper ( spl_array_object * intern , long * count TSRMLS_DC ) /* { { { */
2004-04-29 05:45:41 +08:00
{
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2004-04-29 05:45:41 +08:00
HashPosition pos ;
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
2004-05-06 16:57:20 +08:00
* count = 0 ;
return FAILURE ;
2004-04-29 05:45:41 +08:00
}
2004-04-29 15:22:02 +08:00
if ( Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
2004-05-06 16:57:20 +08:00
/* We need to store the 'pos' since we'll modify it in the functions
* we ' re going to call and which do not support ' pos ' as parameter . */
2004-04-29 15:22:02 +08:00
pos = intern - > pos ;
2004-05-06 16:57:20 +08:00
* count = 0 ;
2008-07-24 23:54:41 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
2004-09-01 04:54:00 +08:00
while ( intern - > pos & & spl_array_next ( intern TSRMLS_CC ) = = SUCCESS ) {
2004-05-06 16:57:20 +08:00
( * count ) + + ;
2004-04-29 15:22:02 +08:00
}
2008-11-19 22:41:40 +08:00
spl_array_set_pos ( intern , pos ) ;
2004-05-06 16:57:20 +08:00
return SUCCESS ;
2004-04-29 15:22:02 +08:00
} else {
2004-05-06 16:57:20 +08:00
* count = zend_hash_num_elements ( aht ) ;
return SUCCESS ;
2004-04-29 15:22:02 +08:00
}
2004-05-06 16:57:20 +08:00
} /* }}} */
2008-07-07 07:45:56 +08:00
int spl_array_object_count_elements ( zval * object , long * count TSRMLS_DC ) /* { { { */
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
if ( intern - > fptr_count ) {
zval * rv ;
zend_call_method_with_0_params ( & object , intern - > std . ce , & intern - > fptr_count , " count " , & rv ) ;
if ( rv ) {
zval_ptr_dtor ( & intern - > retval ) ;
MAKE_STD_ZVAL ( intern - > retval ) ;
ZVAL_ZVAL ( intern - > retval , rv , 1 , 1 ) ;
convert_to_long ( intern - > retval ) ;
* count = ( long ) Z_LVAL_P ( intern - > retval ) ;
return SUCCESS ;
}
* count = 0 ;
return FAILURE ;
}
return spl_array_object_count_elements_helper ( intern , count TSRMLS_CC ) ;
} /* }}} */
2004-05-06 16:57:20 +08:00
/* {{{ proto int ArrayObject::count()
proto int ArrayIterator : : count ( )
2008-08-26 03:07:20 +08:00
Return the number of elements in the Iterator . */
2004-05-06 16:57:20 +08:00
SPL_METHOD ( Array , count )
{
long count ;
2008-07-07 07:45:56 +08:00
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( getThis ( ) TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2008-07-07 07:45:56 +08:00
spl_array_object_count_elements_helper ( intern , & count TSRMLS_CC ) ;
2004-05-06 16:57:20 +08:00
RETURN_LONG ( count ) ;
2004-04-29 05:45:41 +08:00
} /* }}} */
2008-02-05 00:48:06 +08:00
static void spl_array_method ( INTERNAL_FUNCTION_PARAMETERS , char * fname , int fname_len , int use_arg ) /* { { { */
2006-05-10 08:03:38 +08:00
{
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( getThis ( ) TSRMLS_CC ) ;
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2008-07-19 21:13:57 +08:00
zval * tmp , * arg ;
2008-09-19 20:48:33 +08:00
zval * retval_ptr = NULL ;
2006-05-10 08:03:38 +08:00
2008-07-19 21:13:57 +08:00
MAKE_STD_ZVAL ( tmp ) ;
Z_TYPE_P ( tmp ) = IS_ARRAY ;
Z_ARRVAL_P ( tmp ) = aht ;
2006-05-10 08:03:38 +08:00
if ( use_arg ) {
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & arg ) = = FAILURE ) {
2008-10-18 06:09:44 +08:00
Z_TYPE_P ( tmp ) = IS_NULL ;
zval_ptr_dtor ( & tmp ) ;
2006-05-10 08:03:38 +08:00
zend_throw_exception ( spl_ce_BadMethodCallException , " Function expects exactly one argument " , 0 TSRMLS_CC ) ;
return ;
}
2010-05-13 16:09:54 +08:00
aht - > nApplyCount + + ;
2008-09-19 20:48:33 +08:00
zend_call_method ( NULL , NULL , NULL , fname , fname_len , & retval_ptr , 2 , tmp , arg TSRMLS_CC ) ;
2010-05-13 16:09:54 +08:00
aht - > nApplyCount - - ;
2006-05-10 08:03:38 +08:00
} else {
2010-05-13 16:09:54 +08:00
aht - > nApplyCount + + ;
2008-09-19 20:48:33 +08:00
zend_call_method ( NULL , NULL , NULL , fname , fname_len , & retval_ptr , 1 , tmp , NULL TSRMLS_CC ) ;
2010-05-13 16:09:54 +08:00
aht - > nApplyCount - - ;
2006-05-10 08:03:38 +08:00
}
2008-07-19 21:13:57 +08:00
Z_TYPE_P ( tmp ) = IS_NULL ; /* we want to destroy the zval, not the hashtable */
zval_ptr_dtor ( & tmp ) ;
2008-09-19 20:48:33 +08:00
if ( retval_ptr ) {
COPY_PZVAL_TO_ZVAL ( * return_value , retval_ptr ) ;
}
2008-02-05 00:48:06 +08:00
} /* }}} */
2006-05-10 08:03:38 +08:00
# define SPL_ARRAY_METHOD(cname, fname, use_arg) \
SPL_METHOD ( cname , fname ) \
{ \
spl_array_method ( INTERNAL_FUNCTION_PARAM_PASSTHRU , # fname , sizeof ( # fname ) - 1 , use_arg ) ; \
}
/* {{{ proto int ArrayObject::asort()
proto int ArrayIterator : : asort ( )
2008-08-26 03:07:20 +08:00
Sort the entries by values . */
2007-12-05 23:56:41 +08:00
SPL_ARRAY_METHOD ( Array , asort , 0 ) /* }}} */
2006-05-10 08:03:38 +08:00
/* {{{ proto int ArrayObject::ksort()
proto int ArrayIterator : : ksort ( )
2008-08-26 03:07:20 +08:00
Sort the entries by key . */
2007-12-05 23:56:41 +08:00
SPL_ARRAY_METHOD ( Array , ksort , 0 ) /* }}} */
2006-05-10 08:03:38 +08:00
/* {{{ proto int ArrayObject::uasort(callback cmp_function)
proto int ArrayIterator : : uasort ( callback cmp_function )
2008-08-26 03:07:20 +08:00
Sort the entries by values user defined function . */
2007-12-05 23:56:41 +08:00
SPL_ARRAY_METHOD ( Array , uasort , 1 ) /* }}} */
2006-05-10 08:03:38 +08:00
/* {{{ proto int ArrayObject::uksort(callback cmp_function)
proto int ArrayIterator : : uksort ( callback cmp_function )
2008-08-26 03:07:20 +08:00
Sort the entries by key using user defined function . */
2007-12-05 23:56:41 +08:00
SPL_ARRAY_METHOD ( Array , uksort , 1 ) /* }}} */
2006-05-10 08:03:38 +08:00
/* {{{ proto int ArrayObject::natsort()
proto int ArrayIterator : : natsort ( )
2008-08-26 03:07:20 +08:00
Sort the entries by values using " natural order " algorithm . */
2007-12-05 23:56:41 +08:00
SPL_ARRAY_METHOD ( Array , natsort , 0 ) /* }}} */
2006-05-10 08:03:38 +08:00
/* {{{ proto int ArrayObject::natcasesort()
proto int ArrayIterator : : natcasesort ( )
2008-08-26 03:07:20 +08:00
Sort the entries by key using case insensitive " natural order " algorithm . */
2007-12-17 02:31:07 +08:00
SPL_ARRAY_METHOD ( Array , natcasesort , 0 ) /* }}} */
2006-05-10 08:03:38 +08:00
2004-03-21 00:09:42 +08:00
/* {{{ proto mixed|NULL ArrayIterator::current()
2003-07-20 04:54:22 +08:00
Return current array entry */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , current )
2003-07-20 04:54:22 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
zval * * entry ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2003-07-20 04:54:22 +08:00
2003-07-20 09:22:03 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2008-11-19 22:41:40 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2003-07-20 09:22:03 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
2004-03-21 00:09:42 +08:00
return ;
2003-07-20 09:22:03 +08:00
}
if ( zend_hash_get_current_data_ex ( aht , ( void * * ) & entry , & intern - > pos ) = = FAILURE ) {
2004-03-21 00:09:42 +08:00
return ;
2003-07-20 04:54:22 +08:00
}
2005-03-11 08:44:34 +08:00
RETVAL_ZVAL ( * entry , 1 , 0 ) ;
2003-07-20 04:54:22 +08:00
}
/* }}} */
2004-03-21 00:09:42 +08:00
/* {{{ proto mixed|NULL ArrayIterator::key()
2003-07-20 04:54:22 +08:00
Return current array key */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , key )
2003-07-20 04:54:22 +08:00
{
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2006-05-10 08:03:38 +08:00
spl_array_iterator_key ( getThis ( ) , return_value TSRMLS_CC ) ;
2007-12-05 23:56:41 +08:00
} /* }}} */
2006-05-10 08:03:38 +08:00
void spl_array_iterator_key ( zval * object , zval * return_value TSRMLS_DC ) /* { { { */
{
2003-07-20 04:54:22 +08:00
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
char * string_key ;
uint string_length ;
ulong num_key ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2003-07-20 09:22:03 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2003-07-20 04:54:22 +08:00
2008-11-19 22:41:40 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2003-07-20 09:22:03 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
2004-03-21 00:09:42 +08:00
return ;
2003-07-20 09:22:03 +08:00
}
2004-04-25 19:14:11 +08:00
switch ( zend_hash_get_current_key_ex ( aht , & string_key , & string_length , & num_key , 1 , & intern - > pos ) ) {
2003-07-20 04:54:22 +08:00
case HASH_KEY_IS_STRING :
2004-04-25 19:14:11 +08:00
RETVAL_STRINGL ( string_key , string_length - 1 , 0 ) ;
2003-07-20 04:54:22 +08:00
break ;
case HASH_KEY_IS_LONG :
RETVAL_LONG ( num_key ) ;
break ;
case HASH_KEY_NON_EXISTANT :
return ;
}
}
/* }}} */
2003-11-27 07:28:35 +08:00
/* {{{ proto void ArrayIterator::next()
2003-07-20 04:54:22 +08:00
Move to next entry */
2003-11-09 22:05:36 +08:00
SPL_METHOD ( Array , next )
2003-07-20 04:54:22 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2003-07-20 09:22:03 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2008-11-19 22:41:40 +08:00
spl_array_next_ex ( intern , aht TSRMLS_CC ) ;
2003-07-20 04:54:22 +08:00
}
2007-12-07 00:04:17 +08:00
/* }}} */
2003-07-20 04:54:22 +08:00
2004-03-09 01:33:31 +08:00
/* {{{ proto bool ArrayIterator::valid()
2003-07-20 04:54:22 +08:00
Check whether array contains more entries */
2004-03-09 01:33:31 +08:00
SPL_METHOD ( Array , valid )
2003-07-20 04:54:22 +08:00
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2003-07-20 09:22:03 +08:00
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2003-07-20 09:22:03 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2003-07-20 04:54:22 +08:00
2008-11-19 22:41:40 +08:00
if ( intern - > pos & & ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2003-07-20 09:22:03 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
RETURN_FALSE ;
} else {
RETURN_BOOL ( zend_hash_has_more_elements_ex ( aht , & intern - > pos ) = = SUCCESS ) ;
}
2003-07-20 04:54:22 +08:00
}
/* }}} */
2005-09-19 01:15:04 +08:00
/* {{{ proto bool RecursiveArrayIterator::hasChildren()
Check whether current element has children ( e . g . is an array ) */
SPL_METHOD ( Array , hasChildren )
{
zval * object = getThis ( ) , * * entry ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2005-09-19 01:15:04 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
RETURN_FALSE ;
}
2008-11-19 22:41:40 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2005-09-19 01:15:04 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
RETURN_FALSE ;
}
if ( zend_hash_get_current_data_ex ( aht , ( void * * ) & entry , & intern - > pos ) = = FAILURE ) {
RETURN_FALSE ;
}
2007-12-05 23:56:41 +08:00
RETURN_BOOL ( Z_TYPE_PP ( entry ) = = IS_ARRAY | | ( Z_TYPE_PP ( entry ) = = IS_OBJECT & & ( intern - > ar_flags & SPL_ARRAY_CHILD_ARRAYS_ONLY ) = = 0 ) ) ;
2005-09-19 01:15:04 +08:00
}
/* }}} */
/* {{{ proto object RecursiveArrayIterator::getChildren()
Create a sub iterator for the current element ( same class as $ this ) */
SPL_METHOD ( Array , getChildren )
{
2007-10-18 11:55:43 +08:00
zval * object = getThis ( ) , * * entry , * flags ;
2005-09-19 01:15:04 +08:00
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2005-09-19 01:15:04 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
2008-11-19 22:41:40 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos_ex ( intern , aht TSRMLS_CC ) = = FAILURE ) {
2005-09-19 01:15:04 +08:00
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and internal position is no longer valid " ) ;
return ;
}
if ( zend_hash_get_current_data_ex ( aht , ( void * * ) & entry , & intern - > pos ) = = FAILURE ) {
return ;
}
2006-03-06 01:39:49 +08:00
2007-12-05 23:56:41 +08:00
if ( Z_TYPE_PP ( entry ) = = IS_OBJECT ) {
if ( ( intern - > ar_flags & SPL_ARRAY_CHILD_ARRAYS_ONLY ) ! = 0 ) {
return ;
}
if ( instanceof_function ( Z_OBJCE_PP ( entry ) , Z_OBJCE_P ( getThis ( ) ) TSRMLS_CC ) ) {
RETURN_ZVAL ( * entry , 0 , 0 ) ;
}
2005-10-03 17:14:30 +08:00
}
2005-09-19 01:15:04 +08:00
2007-12-05 23:56:41 +08:00
MAKE_STD_ZVAL ( flags ) ;
ZVAL_LONG ( flags , SPL_ARRAY_USE_OTHER | intern - > ar_flags ) ;
2007-10-18 11:55:43 +08:00
spl_instantiate_arg_ex2 ( Z_OBJCE_P ( getThis ( ) ) , & return_value , 0 , * entry , flags TSRMLS_CC ) ;
zval_ptr_dtor ( & flags ) ;
2005-09-19 01:15:04 +08:00
}
/* }}} */
2008-08-26 02:40:44 +08:00
smart_str spl_array_serialize_helper ( spl_array_object * intern , php_serialize_data_t * var_hash_p TSRMLS_DC ) { /* {{{ */
2007-12-07 00:04:17 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2007-12-18 03:00:07 +08:00
zval members , * pmembers ;
2007-12-07 21:33:10 +08:00
smart_str buf = { 0 } ;
2008-08-26 02:40:44 +08:00
zval * flags ;
2010-11-15 02:40:08 +08:00
2007-12-07 00:04:17 +08:00
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
2008-08-26 02:40:44 +08:00
return buf ;
2007-12-07 00:04:17 +08:00
}
2008-08-26 02:40:44 +08:00
MAKE_STD_ZVAL ( flags ) ;
ZVAL_LONG ( flags , ( intern - > ar_flags & SPL_ARRAY_CLONE_MASK ) ) ;
2007-12-07 00:04:17 +08:00
/* storage */
2008-08-26 02:40:44 +08:00
smart_str_appendl ( & buf , " x: " , 2 ) ;
php_var_serialize ( & buf , & flags , var_hash_p TSRMLS_CC ) ;
zval_ptr_dtor ( & flags ) ;
2007-12-07 00:04:17 +08:00
if ( ! ( intern - > ar_flags & SPL_ARRAY_IS_SELF ) ) {
2008-08-26 02:40:44 +08:00
php_var_serialize ( & buf , & intern - > array , var_hash_p TSRMLS_CC ) ;
2007-12-07 00:04:17 +08:00
smart_str_appendc ( & buf , ' ; ' ) ;
}
/* members */
smart_str_appendl ( & buf , " m: " , 2 ) ;
INIT_PZVAL ( & members ) ;
Z_ARRVAL ( members ) = intern - > std . properties ;
Z_TYPE ( members ) = IS_ARRAY ;
pmembers = & members ;
2008-08-26 02:40:44 +08:00
php_var_serialize ( & buf , & pmembers , var_hash_p TSRMLS_CC ) ; /* finishes the string */
2007-12-07 00:04:17 +08:00
/* done */
2008-08-26 02:40:44 +08:00
return buf ;
}
/* }}} */
/* {{{ proto string ArrayObject::serialize()
2008-08-26 03:07:20 +08:00
Serialize the object */
2008-08-26 02:40:44 +08:00
SPL_METHOD ( Array , serialize )
{
zval * object = getThis ( ) ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
int was_in_serialize = intern - > serialize_data ! = NULL ;
smart_str buf ;
2010-11-15 02:40:08 +08:00
if ( zend_parse_parameters_none ( ) = = FAILURE ) {
return ;
}
2008-08-26 02:40:44 +08:00
if ( ! was_in_serialize ) {
intern - > serialize_data = emalloc ( sizeof ( php_serialize_data_t ) ) ;
PHP_VAR_SERIALIZE_INIT ( * intern - > serialize_data ) ;
}
buf = spl_array_serialize_helper ( intern , intern - > serialize_data TSRMLS_CC ) ;
if ( ! was_in_serialize ) {
PHP_VAR_SERIALIZE_DESTROY ( * intern - > serialize_data ) ;
efree ( intern - > serialize_data ) ;
intern - > serialize_data = NULL ;
}
2007-12-07 00:04:17 +08:00
if ( buf . c ) {
RETURN_STRINGL ( buf . c , buf . len , 0 ) ;
}
2007-12-12 11:29:31 +08:00
RETURN_NULL ( ) ;
2007-12-07 00:04:17 +08:00
} /* }}} */
2008-08-26 03:07:20 +08:00
int spl_array_serialize ( zval * object , unsigned char * * buffer , zend_uint * buf_len , zend_serialize_data * data TSRMLS_DC ) /* { { { */
{
2008-08-26 02:40:44 +08:00
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ;
2007-12-07 00:04:17 +08:00
2008-08-26 02:40:44 +08:00
if ( intern - > fptr_serialize ) {
int retval ;
php_serialize_data_t * before ;
before = intern - > serialize_data ;
intern - > serialize_data = ( php_serialize_data_t * ) data ;
retval = zend_user_serialize ( object , buffer , buf_len , data TSRMLS_CC ) ;
intern - > serialize_data = before ;
return retval ;
} else {
smart_str buf ;
buf = spl_array_serialize_helper ( intern , ( php_serialize_data_t * ) data TSRMLS_CC ) ;
if ( buf . c ) {
* buffer = ( unsigned char * ) estrndup ( buf . c , buf . len ) ;
* buf_len = buf . len ;
efree ( buf . c ) ;
return SUCCESS ;
} else {
return FAILURE ;
}
}
}
/* }}} */
2008-08-26 03:07:20 +08:00
void spl_array_unserialize_helper ( spl_array_object * intern , const unsigned char * buf , int buf_len , php_unserialize_data_t * var_hash_p TSRMLS_DC ) /* { { { */
{
2007-12-07 00:04:17 +08:00
const unsigned char * p , * s ;
2007-12-18 03:00:07 +08:00
zval * pmembers , * pflags = NULL ;
2007-12-07 00:04:17 +08:00
long flags ;
/* storage */
2008-08-26 02:40:44 +08:00
s = p = buf ;
2007-12-07 00:04:17 +08:00
if ( * p ! = ' x ' | | * + + p ! = ' : ' ) {
goto outexcept ;
}
+ + p ;
ALLOC_INIT_ZVAL ( pflags ) ;
2008-08-26 02:40:44 +08:00
if ( ! php_var_unserialize ( & pflags , & p , s + buf_len , var_hash_p TSRMLS_CC ) | | Z_TYPE_P ( pflags ) ! = IS_LONG ) {
2007-12-07 00:04:17 +08:00
zval_ptr_dtor ( & pflags ) ;
goto outexcept ;
}
- - p ; /* for ';' */
flags = Z_LVAL_P ( pflags ) ;
zval_ptr_dtor ( & pflags ) ;
/* flags needs to be verified and we also need to verify whether the next
* thing we get is ' ; ' . After that we require an ' m ' or somethign else
* where ' m ' stands for members and anything else should be an array . If
* neither ' a ' or ' m ' follows we have an error . */
if ( * p ! = ' ; ' ) {
goto outexcept ;
}
+ + p ;
if ( * p ! = ' m ' ) {
2008-09-30 06:45:28 +08:00
if ( * p ! = ' a ' & & * p ! = ' O ' & & * p ! = ' C ' ) {
2007-12-07 00:04:17 +08:00
goto outexcept ;
}
intern - > ar_flags & = ~ SPL_ARRAY_CLONE_MASK ;
intern - > ar_flags | = flags & SPL_ARRAY_CLONE_MASK ;
zval_ptr_dtor ( & intern - > array ) ;
ALLOC_INIT_ZVAL ( intern - > array ) ;
2008-08-26 02:40:44 +08:00
if ( ! php_var_unserialize ( & intern - > array , & p , s + buf_len , var_hash_p TSRMLS_CC ) ) {
2007-12-07 00:04:17 +08:00
goto outexcept ;
}
}
if ( * p ! = ' ; ' ) {
goto outexcept ;
}
+ + p ;
/* members */
if ( * p ! = ' m ' | | * + + p ! = ' : ' ) {
goto outexcept ;
}
+ + p ;
ALLOC_INIT_ZVAL ( pmembers ) ;
2008-08-26 02:40:44 +08:00
if ( ! php_var_unserialize ( & pmembers , & p , s + buf_len , var_hash_p TSRMLS_CC ) ) {
2007-12-07 00:04:17 +08:00
zval_ptr_dtor ( & pmembers ) ;
goto outexcept ;
}
/* copy members */
zend_hash_copy ( intern - > std . properties , Z_ARRVAL_P ( pmembers ) , ( copy_ctor_func_t ) zval_add_ref , ( void * ) NULL , sizeof ( zval * ) ) ;
zval_ptr_dtor ( & pmembers ) ;
/* done reading $serialized */
return ;
outexcept :
2008-08-26 02:40:44 +08:00
zend_throw_exception_ex ( spl_ce_UnexpectedValueException , 0 TSRMLS_CC , " Error at offset %ld of %d bytes " , ( long ) ( ( char * ) p - ( char * ) buf ) , buf_len ) ;
2007-12-07 00:04:17 +08:00
return ;
2008-08-26 02:40:44 +08:00
}
/* }}} */
/* {{{ proto void ArrayObject::unserialize(string serialized)
2008-08-26 03:07:20 +08:00
Unserialize the object */
2008-08-26 02:40:44 +08:00
SPL_METHOD ( Array , unserialize )
{
char * buf ;
int buf_len ;
spl_array_object * intern = ( spl_array_object * ) zend_object_store_get_object ( getThis ( ) TSRMLS_CC ) ;
int was_in_unserialize = intern - > unserialize_data ! = NULL ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & buf , & buf_len ) = = FAILURE ) {
return ;
}
if ( buf_len = = 0 ) {
zend_throw_exception_ex ( spl_ce_UnexpectedValueException , 0 TSRMLS_CC , " Empty serialized string cannot be empty " ) ;
return ;
}
if ( ! was_in_unserialize ) {
intern - > unserialize_data = emalloc ( sizeof ( php_unserialize_data_t ) ) ;
PHP_VAR_UNSERIALIZE_INIT ( * intern - > unserialize_data ) ;
}
spl_array_unserialize_helper ( intern , ( const unsigned char * ) buf , buf_len , intern - > unserialize_data TSRMLS_CC ) ;
if ( ! was_in_unserialize ) {
PHP_VAR_UNSERIALIZE_DESTROY ( * intern - > unserialize_data ) ;
efree ( intern - > unserialize_data ) ;
intern - > unserialize_data = NULL ;
}
2007-12-07 00:04:17 +08:00
} /* }}} */
2008-08-26 03:38:04 +08:00
int spl_array_unserialize ( zval * * object , zend_class_entry * ce , const unsigned char * buf , zend_uint buf_len , zend_unserialize_data * data TSRMLS_DC )
2008-08-26 02:40:44 +08:00
{
spl_array_object * intern ;
object_init_ex ( * object , ce ) ;
intern = ( spl_array_object * ) zend_object_store_get_object ( * object TSRMLS_CC ) ;
if ( intern - > fptr_unserialize ) {
zval * zdata ;
php_unserialize_data_t * before ;
MAKE_STD_ZVAL ( zdata ) ;
2009-01-27 22:50:27 +08:00
ZVAL_STRINGL ( zdata , ( char * ) buf , buf_len , 1 ) ;
2008-08-26 02:40:44 +08:00
before = intern - > unserialize_data ;
intern - > unserialize_data = ( php_unserialize_data_t * ) data ;
zend_call_method_with_1_params ( object , ce , & ce - > unserialize_func , " unserialize " , NULL , zdata ) ;
intern - > unserialize_data = before ;
zval_ptr_dtor ( & zdata ) ;
} else {
spl_array_unserialize_helper ( intern , buf , buf_len , ( php_unserialize_data_t * ) data TSRMLS_CC ) ;
}
if ( EG ( exception ) ) {
return FAILURE ;
} else {
return SUCCESS ;
}
}
/* }}} */
2007-12-05 23:56:41 +08:00
/* {{{ arginfo and function tbale */
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array___construct , 0 )
ZEND_ARG_INFO ( 0 , array )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_array_offsetGet , 0 , 0 , 1 )
ZEND_ARG_INFO ( 0 , index )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO_EX ( arginfo_array_offsetSet , 0 , 0 , 2 )
ZEND_ARG_INFO ( 0 , index )
ZEND_ARG_INFO ( 0 , newval )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_append , 0 )
ZEND_ARG_INFO ( 0 , value )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_seek , 0 )
ZEND_ARG_INFO ( 0 , position )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_exchangeArray , 0 )
ZEND_ARG_INFO ( 0 , array )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_setFlags , 0 )
ZEND_ARG_INFO ( 0 , flags )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_setIteratorClass , 0 )
ZEND_ARG_INFO ( 0 , iteratorClass )
2006-03-23 05:56:40 +08:00
ZEND_END_ARG_INFO ( )
2005-09-19 01:15:04 +08:00
2006-05-10 08:03:38 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_uXsort , 0 )
2007-12-07 00:04:17 +08:00
ZEND_ARG_INFO ( 0 , cmp_function )
ZEND_END_ARG_INFO ( ) ;
ZEND_BEGIN_ARG_INFO ( arginfo_array_unserialize , 0 )
ZEND_ARG_INFO ( 0 , serialized )
2006-05-10 08:03:38 +08:00
ZEND_END_ARG_INFO ( ) ;
2009-07-05 04:31:27 +08:00
ZEND_BEGIN_ARG_INFO ( arginfo_array_void , 0 )
ZEND_END_ARG_INFO ( )
2007-09-28 02:00:48 +08:00
static const zend_function_entry spl_funcs_ArrayObject [ ] = {
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , __construct , arginfo_array___construct , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetExists , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetGet , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetSet , arginfo_array_offsetSet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetUnset , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , append , arginfo_array_append , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , getArrayCopy , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , count , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getFlags , arginfo_array_void , ZEND_ACC_PUBLIC )
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , setFlags , arginfo_array_setFlags , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , asort , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , ksort , arginfo_array_void , ZEND_ACC_PUBLIC )
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , uasort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uksort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , natsort , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natcasesort , arginfo_array_void , ZEND_ACC_PUBLIC )
2007-12-07 00:04:17 +08:00
SPL_ME ( Array , unserialize , arginfo_array_unserialize , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , serialize , arginfo_array_void , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
/* ArrayObject specific */
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , getIterator , arginfo_array_void , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
SPL_ME ( Array , exchangeArray , arginfo_array_exchangeArray , ZEND_ACC_PUBLIC )
SPL_ME ( Array , setIteratorClass , arginfo_array_setIteratorClass , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , getIteratorClass , arginfo_array_void , ZEND_ACC_PUBLIC )
2011-07-25 19:42:53 +08:00
PHP_FE_END
2005-09-19 01:15:04 +08:00
} ;
2007-09-28 02:00:48 +08:00
static const zend_function_entry spl_funcs_ArrayIterator [ ] = {
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , __construct , arginfo_array___construct , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetExists , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetGet , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetSet , arginfo_array_offsetSet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , offsetUnset , arginfo_array_offsetGet , ZEND_ACC_PUBLIC )
SPL_ME ( Array , append , arginfo_array_append , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , getArrayCopy , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , count , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getFlags , arginfo_array_void , ZEND_ACC_PUBLIC )
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , setFlags , arginfo_array_setFlags , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , asort , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , ksort , arginfo_array_void , ZEND_ACC_PUBLIC )
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , uasort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uksort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , natsort , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natcasesort , arginfo_array_void , ZEND_ACC_PUBLIC )
2007-12-07 00:04:17 +08:00
SPL_ME ( Array , unserialize , arginfo_array_unserialize , ZEND_ACC_PUBLIC )
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , serialize , arginfo_array_void , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
/* ArrayIterator specific */
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , rewind , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , current , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , key , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , next , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , valid , arginfo_array_void , ZEND_ACC_PUBLIC )
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , seek , arginfo_array_seek , ZEND_ACC_PUBLIC )
2011-07-25 19:42:53 +08:00
PHP_FE_END
2005-09-19 01:15:04 +08:00
} ;
2007-09-28 02:00:48 +08:00
static const zend_function_entry spl_funcs_RecursiveArrayIterator [ ] = {
2009-07-05 04:31:27 +08:00
SPL_ME ( Array , hasChildren , arginfo_array_void , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getChildren , arginfo_array_void , ZEND_ACC_PUBLIC )
2011-07-25 19:42:53 +08:00
PHP_FE_END
2005-09-19 01:15:04 +08:00
} ;
2007-12-05 23:56:41 +08:00
/* }}} */
2005-09-19 01:15:04 +08:00
2004-05-06 16:57:20 +08:00
/* {{{ PHP_MINIT_FUNCTION(spl_array) */
PHP_MINIT_FUNCTION ( spl_array )
{
REGISTER_SPL_STD_CLASS_EX ( ArrayObject , spl_array_object_new , spl_funcs_ArrayObject ) ;
2005-03-07 07:09:21 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayObject , Aggregate ) ;
REGISTER_SPL_IMPLEMENTS ( ArrayObject , ArrayAccess ) ;
2007-12-07 00:04:17 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayObject , Serializable ) ;
2008-08-26 02:40:44 +08:00
spl_ce_ArrayObject - > serialize = spl_array_serialize ;
spl_ce_ArrayObject - > unserialize = spl_array_unserialize ;
2004-05-06 16:57:20 +08:00
memcpy ( & spl_handler_ArrayObject , zend_get_std_object_handlers ( ) , sizeof ( zend_object_handlers ) ) ;
2006-03-06 01:39:49 +08:00
2004-05-06 16:57:20 +08:00
spl_handler_ArrayObject . clone_obj = spl_array_object_clone ;
spl_handler_ArrayObject . read_dimension = spl_array_read_dimension ;
spl_handler_ArrayObject . write_dimension = spl_array_write_dimension ;
spl_handler_ArrayObject . unset_dimension = spl_array_unset_dimension ;
spl_handler_ArrayObject . has_dimension = spl_array_has_dimension ;
spl_handler_ArrayObject . count_elements = spl_array_object_count_elements ;
2005-05-19 23:52:02 +08:00
spl_handler_ArrayObject . get_properties = spl_array_get_properties ;
2007-11-03 03:40:39 +08:00
spl_handler_ArrayObject . get_debug_info = spl_array_get_debug_info ;
2005-05-19 23:52:02 +08:00
spl_handler_ArrayObject . read_property = spl_array_read_property ;
spl_handler_ArrayObject . write_property = spl_array_write_property ;
spl_handler_ArrayObject . get_property_ptr_ptr = spl_array_get_property_ptr_ptr ;
spl_handler_ArrayObject . has_property = spl_array_has_property ;
spl_handler_ArrayObject . unset_property = spl_array_unset_property ;
2012-03-11 01:19:39 +08:00
spl_handler_ArrayObject . compare_objects = spl_array_compare_objects ;
2004-05-06 16:57:20 +08:00
REGISTER_SPL_STD_CLASS_EX ( ArrayIterator , spl_array_object_new , spl_funcs_ArrayIterator ) ;
2005-03-07 07:09:21 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayIterator , Iterator ) ;
REGISTER_SPL_IMPLEMENTS ( ArrayIterator , ArrayAccess ) ;
2004-05-06 16:57:20 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayIterator , SeekableIterator ) ;
2007-12-07 00:04:17 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayIterator , Serializable ) ;
2008-08-26 02:40:44 +08:00
spl_ce_ArrayIterator - > serialize = spl_array_serialize ;
spl_ce_ArrayIterator - > unserialize = spl_array_unserialize ;
2004-05-06 16:57:20 +08:00
memcpy ( & spl_handler_ArrayIterator , & spl_handler_ArrayObject , sizeof ( zend_object_handlers ) ) ;
spl_ce_ArrayIterator - > get_iterator = spl_array_get_iterator ;
2005-09-19 01:15:04 +08:00
REGISTER_SPL_SUB_CLASS_EX ( RecursiveArrayIterator , ArrayIterator , spl_array_object_new , spl_funcs_RecursiveArrayIterator ) ;
REGISTER_SPL_IMPLEMENTS ( RecursiveArrayIterator , RecursiveIterator ) ;
2006-05-10 08:03:38 +08:00
spl_ce_RecursiveArrayIterator - > get_iterator = spl_array_get_iterator ;
2004-05-06 16:57:20 +08:00
2004-11-01 18:45:54 +08:00
REGISTER_SPL_IMPLEMENTS ( ArrayObject , Countable ) ;
REGISTER_SPL_IMPLEMENTS ( ArrayIterator , Countable ) ;
2005-09-15 11:33:04 +08:00
REGISTER_SPL_CLASS_CONST_LONG ( ArrayObject , " STD_PROP_LIST " , SPL_ARRAY_STD_PROP_LIST ) ;
REGISTER_SPL_CLASS_CONST_LONG ( ArrayObject , " ARRAY_AS_PROPS " , SPL_ARRAY_ARRAY_AS_PROPS ) ;
REGISTER_SPL_CLASS_CONST_LONG ( ArrayIterator , " STD_PROP_LIST " , SPL_ARRAY_STD_PROP_LIST ) ;
REGISTER_SPL_CLASS_CONST_LONG ( ArrayIterator , " ARRAY_AS_PROPS " , SPL_ARRAY_ARRAY_AS_PROPS ) ;
2008-05-07 07:08:06 +08:00
REGISTER_SPL_CLASS_CONST_LONG ( RecursiveArrayIterator , " CHILD_ARRAYS_ONLY " , SPL_ARRAY_CHILD_ARRAYS_ONLY ) ;
2004-05-06 16:57:20 +08:00
return SUCCESS ;
}
/* }}} */
2003-05-02 07:28:28 +08:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : fdm = marker
* vim : noet sw = 4 ts = 4
*/