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
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-01-01 17:36:18 +08:00
| Copyright ( c ) 1997 - 2007 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"
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
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
2005-09-19 01:15:04 +08:00
# define SPL_ARRAY_CLONE_MASK 0x03000007
2005-05-19 23:52:02 +08:00
2003-07-20 04:54:22 +08:00
typedef struct _spl_array_object {
zend_object std ;
zval * array ;
2005-06-20 11:02:52 +08:00
zval * retval ;
2003-07-20 04:54:22 +08:00
HashPosition pos ;
2005-05-19 23:52:02 +08:00
int ar_flags ;
int is_self ;
2005-03-03 18:35:34 +08:00
zend_function * fptr_offset_get ;
zend_function * fptr_offset_set ;
zend_function * fptr_offset_has ;
zend_function * fptr_offset_del ;
2005-09-19 01:15:04 +08:00
zend_class_entry * ce_get_iterator ;
2003-07-20 04:54:22 +08:00
} spl_array_object ;
2005-06-20 08:19:18 +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 ) ;
}
}
2005-03-22 04:07:33 +08:00
SPL_API int spl_hash_verify_pos ( spl_array_object * intern TSRMLS_DC ) /* { { { */
{
2005-06-20 08:19:18 +08:00
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2005-03-22 04:07:33 +08:00
Bucket * p ;
/* IS_CONSISTENT(ht);*/
/* HASH_PROTECT_RECURSION(ht);*/
p = ht - > pListHead ;
while ( p ! = NULL ) {
if ( p = = intern - > pos ) {
return SUCCESS ;
}
p = p - > pListNext ;
}
/* HASH_UNPROTECT_RECURSION(ht); */
2005-06-20 08:19:18 +08:00
zend_hash_internal_pointer_reset_ex ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , & intern - > pos ) ;
2005-03-22 04:07:33 +08:00
return FAILURE ;
}
/* }}} */
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
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 ) ;
2006-04-05 03:53:21 +08:00
2003-07-20 04:54:22 +08:00
/* {{{ spl_array_object_new */
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 ;
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 ;
}
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 ;
}
}
2005-06-20 08:19:18 +08:00
zend_hash_internal_pointer_reset_ex ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , & intern - > pos ) ;
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 ;
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
2003-07-20 04:54:22 +08:00
switch ( Z_TYPE_P ( offset ) ) {
case IS_STRING :
2005-06-20 08:19:18 +08:00
if ( zend_symtable_find ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & retval ) = = FAILURE ) {
2004-02-13 04:52:48 +08:00
zend_error ( E_NOTICE , " Undefined index: %s " , Z_STRVAL_P ( offset ) ) ;
2005-05-19 23:52:02 +08:00
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 ) ;
}
2005-06-20 08:19:18 +08:00
if ( zend_hash_index_find ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , index , ( void * * ) & retval ) = = FAILURE ) {
2004-02-13 04:52:48 +08:00
zend_error ( E_NOTICE , " Undefined offset: %ld " , Z_LVAL_P ( offset ) ) ;
2005-05-19 23:52:02 +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 ;
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 ) {
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2005-06-20 08:19:18 +08:00
zend_hash_next_index_insert ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , ( 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 :
2005-10-04 01:59:56 +08:00
if ( * Z_STRVAL_P ( offset ) = = ' \0 ' ) {
zend_throw_exception ( spl_ce_InvalidArgumentException , " An offset must not begin with \\ 0 or be empty " , 0 TSRMLS_CC ) ;
return ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2005-06-20 08:19:18 +08:00
zend_symtable_update ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , 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 :
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 ) ;
2005-06-20 08:19:18 +08:00
zend_hash_index_update ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , 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 :
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( value ) ;
2005-06-20 11:02:52 +08:00
zend_hash_next_index_insert ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , ( void * * ) & value , sizeof ( void * ) , NULL ) ;
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 ;
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 :
2005-06-20 08:19:18 +08:00
if ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) = = & 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 {
2005-06-20 08:19:18 +08:00
if ( zend_symtable_del ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , 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 ) ;
}
2005-06-20 08:19:18 +08:00
if ( zend_hash_index_del ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , 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 ) ) {
case IS_STRING :
2007-01-07 11:52:44 +08:00
if ( check_empty ) {
2007-03-21 04:28:08 +08:00
if ( zend_symtable_find ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 , ( void * * ) & tmp ) ! = FAILURE & & zend_is_true ( * tmp ) ) {
2007-01-07 11:52:44 +08:00
return 1 ;
}
return 0 ;
} else {
return zend_symtable_exists ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , Z_STRVAL_P ( offset ) , Z_STRLEN_P ( offset ) + 1 ) ;
}
2003-11-17 13:25:47 +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 ) ;
}
2007-01-07 11:52:44 +08:00
if ( check_empty ) {
HashTable * ht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
if ( zend_hash_index_find ( ht , index , ( void * * ) & tmp ) ! = FAILURE & & zend_is_true ( * tmp ) ) {
return 1 ;
}
return 0 ;
} else {
return zend_hash_index_exists ( spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) , index ) ;
}
2003-11-17 13:25:47 +08:00
default :
zend_error ( E_WARNING , " Illegal offset type " ) ;
}
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 )
2004-04-25 19:14:11 +08:00
Returns whether the requested $ index exists . */
SPL_METHOD ( Array , offsetExists )
{
zval * index ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & index ) = = FAILURE ) {
return ;
}
2007-04-07 01:57:10 +08:00
RETURN_BOOL ( spl_array_has_dimension_ex ( 0 , getThis ( ) , index , 0 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 )
2004-04-25 19:14:11 +08:00
Returns the value at the specified $ index . */
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 )
2004-04-25 19:14:11 +08:00
Sets the value at the specified $ index to $ newval . */
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 ) {
intern - > pos = aht - > pListTail ;
}
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 )
Appends the value ( cannot be called for objects ) . */
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 )
2004-04-25 19:14:11 +08:00
Unsets the value at the specified $ index . */
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
} /* }}} */
/* {{ proto array ArrayObject::getArrayCopy()
2004-04-30 06:52:49 +08:00
proto array ArrayIterator : : getArrayCopy ( )
2004-04-25 19:14:11 +08:00
Return a copy of the contained array */
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 ) ;
2005-06-20 08:19:18 +08:00
return spl_array_get_hash_table ( intern , 1 TSRMLS_CC ) ;
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 ) ;
HashTable * rv ;
zval * tmp , * storage ;
int name_len ;
char * zname ;
zend_class_entry * base ;
if ( HASH_OF ( intern - > array ) = = intern - > std . properties ) {
* is_temp = 0 ;
return intern - > std . properties ;
} else {
* is_temp = 1 ;
ALLOC_HASHTABLE ( rv ) ;
ZEND_INIT_SYMTABLE_EX ( rv , zend_hash_num_elements ( intern - > std . properties ) + 1 , 0 ) ;
zend_hash_copy ( rv , intern - > std . properties , ( copy_ctor_func_t ) zval_add_ref , ( void * ) & tmp , sizeof ( zval * ) ) ;
storage = intern - > array ;
zval_add_ref ( & storage ) ;
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 ( rv , zname , name_len + 1 , & storage , sizeof ( zval * ) , NULL ) ;
efree ( zname ) ;
return rv ;
}
}
/* }}} */
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 ) ) {
return spl_array_get_dimension_ptr_ptr ( 1 , object , member , 0 TSRMLS_CC ) ;
}
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 ) ;
if ( ( intern - > ar_flags & SPL_ARRAY_ARRAY_AS_PROPS ) ! = 0 ) {
if ( ! std_object_handlers . has_property ( object , member , 2 TSRMLS_CC ) ) {
return spl_array_has_dimension ( object , member , has_set_exists TSRMLS_CC ) ;
}
return 0 ; /* if prop doesn't exist at all mode 0/1 cannot return 1 */
}
return std_object_handlers . has_property ( object , member , has_set_exists TSRMLS_CC ) ;
} /* }}} */
static void spl_array_rewind ( spl_array_object * intern TSRMLS_DC ) ;
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
2004-04-27 23:42:45 +08:00
static int spl_array_skip_protected ( spl_array_object * intern TSRMLS_DC ) /* { { { */
2004-04-25 19:14:11 +08:00
{
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 ) ;
2004-04-25 19:14:11 +08:00
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 ) ;
} while ( 1 ) ;
}
2004-04-27 23:42:45 +08:00
return FAILURE ;
2004-04-25 19:14:11 +08:00
}
/* }}} */
2004-04-27 23:42:45 +08:00
static int spl_array_next ( spl_array_object * intern TSRMLS_DC ) /* { { { */
{
2005-06-20 08:19:18 +08:00
HashTable * aht = spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ;
2004-04-27 23:42:45 +08:00
2005-05-19 23:52:02 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern 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
} else {
2005-01-27 08:22:06 +08:00
zend_hash_move_forward_ex ( aht , & intern - > pos ) ;
if ( Z_TYPE_P ( intern - > array ) = = IS_OBJECT ) {
return spl_array_skip_protected ( intern TSRMLS_CC ) ;
} else {
return zend_hash_has_more_elements_ex ( aht , & intern - > pos ) ;
}
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 ;
}
if ( object - > pos & & ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( object TSRMLS_CC ) = = FAILURE ) {
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 ;
}
if ( ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( object TSRMLS_CC ) = = FAILURE ) {
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 ;
}
if ( ( object - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( object TSRMLS_CC ) = = FAILURE ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " ArrayIterator::next(): Array was modified outside object and internal position is no longer valid " ) ;
} else {
spl_array_next ( object TSRMLS_CC ) ;
}
2004-04-25 19:14:11 +08:00
}
}
/* }}} */
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 ;
}
2005-03-22 04:07:33 +08:00
zend_hash_internal_pointer_reset_ex ( aht , & intern - > pos ) ;
spl_array_skip_protected ( intern TSRMLS_CC ) ;
}
/* }}} */
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
}
/* }}} */
/* 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 ] )
2003-07-20 04:54:22 +08:00
Cronstructs 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 ;
2005-09-19 01:15:04 +08:00
char * class_name ;
int class_name_len ;
zend_class_entry * * pce_get_iterator ;
2003-07-20 04:54:22 +08:00
if ( ZEND_NUM_ARGS ( ) = = 0 ) {
return ; /* nothing to do */
}
2004-11-12 04:06:23 +08:00
php_set_error_handling ( EH_THROW , spl_ce_InvalidArgumentException 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 ) ;
2007-06-27 20:30:28 +08:00
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " Z|ls " , & array , & ar_flags , & class_name , & class_name_len ) = = FAILURE ) {
2005-05-19 23:52:02 +08:00
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
return ;
}
2007-06-27 20:30:28 +08:00
if ( Z_TYPE_PP ( array ) = = IS_ARRAY ) {
SEPARATE_ZVAL_IF_NOT_REF ( array ) ;
}
2005-09-19 01:15:04 +08:00
if ( ZEND_NUM_ARGS ( ) > 2 ) {
if ( zend_lookup_class ( class_name , class_name_len , & pce_get_iterator TSRMLS_CC ) = = FAILURE ) {
zend_throw_exception ( spl_ce_InvalidArgumentException , " A class that implements Iterator must be specified " , 0 TSRMLS_CC ) ;
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
return ;
}
intern - > ce_get_iterator = * pce_get_iterator ;
}
2005-06-20 08:19:18 +08:00
ar_flags & = ~ SPL_ARRAY_INT_MASK ;
2007-06-27 20:30:28 +08:00
if ( Z_TYPE_PP ( array ) = = IS_OBJECT & & ( Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayObject | | Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayIterator ) ) {
2005-05-19 23:52:02 +08:00
zval_ptr_dtor ( & intern - > array ) ;
2005-06-20 08:19:18 +08:00
if ( ZEND_NUM_ARGS ( ) = = 1 )
{
2007-06-27 20:30:28 +08:00
spl_array_object * other = ( spl_array_object * ) zend_object_store_get_object ( * array TSRMLS_CC ) ;
2005-06-20 08:19:18 +08:00
ar_flags = other - > ar_flags & ~ SPL_ARRAY_INT_MASK ;
}
ar_flags | = SPL_ARRAY_USE_OTHER ;
2007-06-27 20:30:28 +08:00
intern - > array = * array ;
2005-05-19 23:52:02 +08:00
} else {
2007-06-27 20:30:28 +08:00
if ( Z_TYPE_PP ( array ) ! = IS_OBJECT & & Z_TYPE_PP ( array ) ! = IS_ARRAY ) {
2005-05-19 23:52:02 +08:00
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
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 ) ;
2007-06-27 20:30:28 +08:00
intern - > array = * array ;
2005-05-19 23:52:02 +08:00
}
2007-06-27 20:30:28 +08:00
if ( object = = * array ) {
2005-05-19 23:52:02 +08:00
intern - > ar_flags | = SPL_ARRAY_IS_SELF ;
2006-04-05 03:53:21 +08:00
intern - > ar_flags & = ~ SPL_ARRAY_USE_OTHER ;
2005-05-19 23:52:02 +08:00
} else {
intern - > ar_flags & = ~ SPL_ARRAY_IS_SELF ;
}
2005-06-20 08:19:18 +08:00
intern - > ar_flags | = ar_flags ;
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( intern - > array ) ;
2007-06-27 20:30:28 +08:00
if ( Z_TYPE_PP ( array ) = = IS_OBJECT ) {
zend_object_get_properties_t handler = Z_OBJ_HANDLER_PP ( array , get_properties ) ;
2005-10-09 22:42:08 +08:00
if ( ( handler ! = std_object_handlers . get_properties & & handler ! = spl_array_get_properties )
| | ! spl_array_get_hash_table ( intern , 0 TSRMLS_CC ) ) {
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
2007-06-27 20:30:28 +08:00
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 ) ;
2005-10-09 22:42:08 +08:00
return ;
}
}
2005-05-19 23:52:02 +08:00
spl_array_rewind ( intern TSRMLS_CC ) ;
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
}
/* }}} */
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 ) ;
char * class_name ;
int class_name_len ;
zend_class_entry * * pce_get_iterator ;
if ( zend_parse_parameters ( ZEND_NUM_ARGS ( ) TSRMLS_CC , " s " , & class_name , & class_name_len ) = = FAILURE ) {
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
return ;
}
if ( zend_lookup_class ( class_name , class_name_len , & pce_get_iterator TSRMLS_CC ) = = FAILURE ) {
zend_throw_exception ( spl_ce_InvalidArgumentException , " A class that implements Iterator must be specified " , 0 TSRMLS_CC ) ;
php_set_error_handling ( EH_NORMAL , NULL TSRMLS_CC ) ;
return ;
}
intern - > ce_get_iterator = * pce_get_iterator ;
}
/* }}} */
/* {{{ 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 ) ;
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 ) ;
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
}
2006-02-13 00:44:36 +08:00
if ( Z_TYPE_PP ( array ) = = IS_OBJECT & & intern = = ( spl_array_object * ) zend_object_store_get_object ( object TSRMLS_CC ) ) {
2005-06-20 08:19:18 +08:00
zval_ptr_dtor ( & intern - > array ) ;
array = & object ;
intern - > array = object ;
} else if ( Z_TYPE_PP ( array ) = = IS_OBJECT & & ( Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayObject | | Z_OBJ_HT_PP ( array ) = = & spl_handler_ArrayIterator ) ) {
2004-04-14 03:06:16 +08:00
spl_array_object * other = ( spl_array_object * ) zend_object_store_get_object ( * array TSRMLS_CC ) ;
2005-05-19 23:52:02 +08:00
zval_ptr_dtor ( & intern - > array ) ;
2005-06-20 08:19:18 +08:00
intern - > array = other - > array ;
2004-04-14 03:06:16 +08:00
} else {
2005-05-19 23:52:02 +08:00
if ( Z_TYPE_PP ( array ) ! = IS_OBJECT & & ! HASH_OF ( * array ) ) {
2004-11-12 04:06:23 +08:00
zend_throw_exception ( spl_ce_InvalidArgumentException , " Passed variable is not an array or object, using empty array instead " , 0 TSRMLS_CC ) ;
2004-04-14 03:06:16 +08:00
return ;
}
2005-05-19 23:52:02 +08:00
zval_ptr_dtor ( & intern - > array ) ;
2004-04-14 03:06:16 +08:00
intern - > array = * array ;
2007-07-20 18:53:56 +08:00
intern - > ar_flags & = ~ SPL_ARRAY_USE_OTHER ;
2003-07-20 04:54:22 +08:00
}
2005-05-19 23:52:02 +08:00
if ( object = = * array ) {
intern - > ar_flags | = SPL_ARRAY_IS_SELF ;
} else {
intern - > ar_flags & = ~ SPL_ARRAY_IS_SELF ;
}
2007-10-07 13:22:07 +08:00
Z_ADDREF_P ( intern - > array ) ;
2003-07-20 04:54:22 +08:00
2005-05-19 23:52:02 +08:00
spl_array_rewind ( intern 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 ) ;
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 ) ;
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)
2004-04-27 23:42:45 +08:00
Seek to position . */
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 */
zend_hash_internal_pointer_reset_ex ( aht , & intern - > pos ) ;
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
} /* }}} */
2004-05-06 16:57:20 +08:00
int spl_array_object_count_elements ( zval * object , long * count TSRMLS_DC ) /* { { { */
2004-04-29 05:45:41 +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-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 ;
2004-04-29 15:22:02 +08:00
zend_hash_internal_pointer_reset_ex ( aht , & intern - > pos ) ;
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
}
intern - > pos = 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
} /* }}} */
/* {{{ proto int ArrayObject::count()
proto int ArrayIterator : : count ( )
Return the number of elements in the Iterator . */
SPL_METHOD ( Array , count )
{
long count ;
spl_array_object_count_elements ( getThis ( ) , & count TSRMLS_CC ) ;
RETURN_LONG ( count ) ;
2004-04-29 05:45:41 +08:00
} /* }}} */
2006-05-10 08:03:38 +08:00
static void spl_array_method ( INTERNAL_FUNCTION_PARAMETERS , char * fname , int fname_len , int use_arg )
{
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 ) ;
zval tmp , * arg ;
INIT_PZVAL ( & tmp ) ;
Z_TYPE ( tmp ) = IS_ARRAY ;
Z_ARRVAL ( tmp ) = aht ;
if ( use_arg ) {
if ( ZEND_NUM_ARGS ( ) ! = 1 | | zend_parse_parameters_ex ( ZEND_PARSE_PARAMS_QUIET , ZEND_NUM_ARGS ( ) TSRMLS_CC , " z " , & arg ) = = FAILURE ) {
zend_throw_exception ( spl_ce_BadMethodCallException , " Function expects exactly one argument " , 0 TSRMLS_CC ) ;
return ;
}
zend_call_method ( NULL , NULL , NULL , fname , fname_len , & return_value , 2 , & tmp , arg TSRMLS_CC ) ;
} else {
zend_call_method ( NULL , NULL , NULL , fname , fname_len , & return_value , 1 , & tmp , NULL TSRMLS_CC ) ;
}
}
# 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 ( )
Sort the entries by values . */
SPL_ARRAY_METHOD ( Array , asort , 0 )
/* {{{ proto int ArrayObject::ksort()
proto int ArrayIterator : : ksort ( )
Sort the entries by key . */
SPL_ARRAY_METHOD ( Array , ksort , 0 )
/* {{{ proto int ArrayObject::uasort(callback cmp_function)
proto int ArrayIterator : : uasort ( callback cmp_function )
Sort the entries by values user defined function . */
SPL_ARRAY_METHOD ( Array , uasort , 1 )
/* {{{ proto int ArrayObject::uksort(callback cmp_function)
proto int ArrayIterator : : uksort ( callback cmp_function )
Sort the entries by key using user defined function . */
SPL_ARRAY_METHOD ( Array , uksort , 1 )
/* {{{ proto int ArrayObject::natsort()
proto int ArrayIterator : : natsort ( )
Sort the entries by values using " natural order " algorithm . */
SPL_ARRAY_METHOD ( Array , natsort , 0 )
/* {{{ proto int ArrayObject::natcasesort()
proto int ArrayIterator : : natcasesort ( )
Sort the entries by key using case insensitive " natural order " algorithm . */
SPL_ARRAY_METHOD ( Array , natcasesort , 0 )
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 ) ;
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 ;
}
2005-05-19 23:52:02 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern 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
{
2006-05-10 08:03:38 +08:00
spl_array_iterator_key ( getThis ( ) , return_value TSRMLS_CC ) ;
}
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
2005-05-19 23:52:02 +08:00
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern 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
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 ;
}
2005-01-27 08:22:06 +08:00
spl_array_next ( intern TSRMLS_CC ) ;
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
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
2005-05-19 23:52:02 +08:00
if ( intern - > pos & & ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern 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 ) ;
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
RETURN_FALSE ;
}
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern TSRMLS_CC ) = = FAILURE ) {
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 ;
}
RETURN_BOOL ( Z_TYPE_PP ( entry ) = = IS_ARRAY | | Z_TYPE_PP ( entry ) = = IS_OBJECT ) ;
}
/* }}} */
/* {{{ 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 ) ;
if ( ! aht ) {
php_error_docref ( NULL TSRMLS_CC , E_NOTICE , " Array was modified outside object and is no longer an array " ) ;
return ;
}
if ( ( intern - > ar_flags & SPL_ARRAY_IS_REF ) & & spl_hash_verify_pos ( intern TSRMLS_CC ) = = FAILURE ) {
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
2005-10-03 17:14:30 +08:00
if ( Z_TYPE_PP ( entry ) = = IS_OBJECT & & instanceof_function ( Z_OBJCE_PP ( entry ) , Z_OBJCE_P ( getThis ( ) ) TSRMLS_CC ) ) {
RETURN_ZVAL ( * entry , 0 , 0 ) ;
}
2005-09-19 01:15:04 +08:00
2007-10-18 11:55:43 +08:00
MAKE_STD_ZVAL ( flags ) ;
ZVAL_LONG ( flags , SPL_ARRAY_USE_OTHER ) ;
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
}
/* }}} */
static
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
static
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
static
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
static
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
static
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
static
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
static
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
static
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
static
ZEND_BEGIN_ARG_INFO ( arginfo_array_uXsort , 0 )
ZEND_ARG_INFO ( 0 , cmp_function )
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 )
SPL_ME ( Array , getArrayCopy , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , count , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getFlags , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , setFlags , arginfo_array_setFlags , ZEND_ACC_PUBLIC )
SPL_ME ( Array , asort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , ksort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uasort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uksort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natsort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natcasesort , NULL , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
/* ArrayObject specific */
SPL_ME ( Array , getIterator , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , exchangeArray , arginfo_array_exchangeArray , ZEND_ACC_PUBLIC )
SPL_ME ( Array , setIteratorClass , arginfo_array_setIteratorClass , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getIteratorClass , NULL , ZEND_ACC_PUBLIC )
{ NULL , NULL , NULL }
} ;
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 )
SPL_ME ( Array , getArrayCopy , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , count , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getFlags , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , setFlags , arginfo_array_setFlags , ZEND_ACC_PUBLIC )
SPL_ME ( Array , asort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , ksort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uasort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , uksort , arginfo_array_uXsort , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natsort , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , natcasesort , NULL , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
/* ArrayIterator specific */
2006-05-10 08:03:38 +08:00
SPL_ME ( Array , rewind , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , current , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , key , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , next , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , valid , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , seek , arginfo_array_seek , ZEND_ACC_PUBLIC )
2005-09-19 01:15:04 +08:00
{ NULL , NULL , NULL }
} ;
2007-09-28 02:00:48 +08:00
static const zend_function_entry spl_funcs_RecursiveArrayIterator [ ] = {
2005-09-19 01:15:04 +08:00
SPL_ME ( Array , hasChildren , NULL , ZEND_ACC_PUBLIC )
SPL_ME ( Array , getChildren , NULL , ZEND_ACC_PUBLIC )
{ NULL , NULL , NULL }
} ;
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 ) ;
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 ;
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 ) ;
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 ) ;
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
*/