Back to index

php5  5.3.10
Classes | Defines | Typedefs | Enumerations | Functions | Variables
spl_observer.c File Reference
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
#include "ext/standard/php_var.h"
#include "ext/standard/php_smart_str.h"
#include "zend_interfaces.h"
#include "zend_exceptions.h"
#include "php_spl.h"
#include "spl_functions.h"
#include "spl_engine.h"
#include "spl_observer.h"
#include "spl_iterators.h"
#include "spl_array.h"
#include "spl_exceptions.h"

Go to the source code of this file.

Classes

struct  _spl_SplObjectStorage
struct  _spl_SplObjectStorageElement

Defines

#define SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT   1
#define SPL_MULTIPLE_ITERATOR_GET_ALL_KEY   2

Typedefs

typedef struct
_spl_SplObjectStorage 
spl_SplObjectStorage
typedef struct
_spl_SplObjectStorageElement 
spl_SplObjectStorageElement

Enumerations

enum  MultipleIteratorFlags { MIT_NEED_ANY = 0, MIT_NEED_ALL = 1, MIT_KEYS_NUMERIC = 0, MIT_KEYS_ASSOC = 2 }

Functions

 SPL_METHOD (SplObserver, update)
 SPL_METHOD (SplSubject, attach)
 SPL_METHOD (SplSubject, detach)
 SPL_METHOD (SplSubject, notify)
 ZEND_END_ARG_INFO ()
void spl_SplOjectStorage_free_storage (void *object TSRMLS_DC)
static void spl_object_storage_dtor (spl_SplObjectStorageElement *element)
spl_SplObjectStorageElementspl_object_storage_get (spl_SplObjectStorage *intern, zval *obj TSRMLS_DC)
void spl_object_storage_attach (spl_SplObjectStorage *intern, zval *obj, zval *inf TSRMLS_DC)
int spl_object_storage_detach (spl_SplObjectStorage *intern, zval *obj TSRMLS_DC)
void spl_object_storage_addall (spl_SplObjectStorage *intern, spl_SplObjectStorage *other TSRMLS_DC)
static zend_object_value spl_object_storage_new_ex (zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC)
static zend_object_value spl_object_storage_clone (zval *zobject TSRMLS_DC)
static HashTablespl_object_storage_debug_info (zval *obj, int *is_temp TSRMLS_DC)
static HashTablespl_object_storage_get_properties (zval *obj TSRMLS_DC)
static int spl_object_storage_compare_info (spl_SplObjectStorageElement *e1, spl_SplObjectStorageElement *e2 TSRMLS_DC)
static int spl_object_storage_compare_objects (zval *o1, zval *o2 TSRMLS_DC)
static zend_object_value spl_SplObjectStorage_new (zend_class_entry *class_type TSRMLS_DC)
int spl_object_storage_contains (spl_SplObjectStorage *intern, zval *obj TSRMLS_DC)
 SPL_METHOD (SplObjectStorage, attach)
 SPL_METHOD (SplObjectStorage, detach)
 SPL_METHOD (SplObjectStorage, offsetGet)
 SPL_METHOD (SplObjectStorage, addAll)
 SPL_METHOD (SplObjectStorage, removeAll)
 SPL_METHOD (SplObjectStorage, removeAllExcept)
 SPL_METHOD (SplObjectStorage, contains)
 SPL_METHOD (SplObjectStorage, count)
 SPL_METHOD (SplObjectStorage, rewind)
 SPL_METHOD (SplObjectStorage, valid)
 SPL_METHOD (SplObjectStorage, key)
 SPL_METHOD (SplObjectStorage, current)
 SPL_METHOD (SplObjectStorage, getInfo)
 SPL_METHOD (SplObjectStorage, setInfo)
 SPL_METHOD (SplObjectStorage, next)
 SPL_METHOD (SplObjectStorage, serialize)
 SPL_METHOD (SplObjectStorage, unserialize)
 SPL_METHOD (MultipleIterator, __construct)
 SPL_METHOD (MultipleIterator, getFlags)
 SPL_METHOD (MultipleIterator, setFlags)
 SPL_METHOD (MultipleIterator, attachIterator)
 SPL_METHOD (MultipleIterator, rewind)
 SPL_METHOD (MultipleIterator, next)
 SPL_METHOD (MultipleIterator, valid)
static void spl_multiple_iterator_get_all (spl_SplObjectStorage *intern, int get_type, zval *return_value TSRMLS_DC)
 SPL_METHOD (MultipleIterator, current)
 SPL_METHOD (MultipleIterator, key)
 PHP_MINIT_FUNCTION (spl_observer)

Variables

static const zend_function_entry spl_funcs_SplObserver []
static const zend_function_entry spl_funcs_SplSubject []
PHPAPI zend_class_entry * spl_ce_SplObserver
PHPAPI zend_class_entry * spl_ce_SplSubject
PHPAPI zend_class_entry * spl_ce_SplObjectStorage
PHPAPI zend_class_entry * spl_ce_MultipleIterator
PHPAPI zend_object_handlers spl_handler_SplObjectStorage
static const zend_function_entry spl_funcs_SplObjectStorage []
static const zend_function_entry spl_funcs_MultipleIterator []

Class Documentation

struct _spl_SplObjectStorage

Definition at line 81 of file spl_observer.c.

Collaboration diagram for _spl_SplObjectStorage:
Class Members
HashTable * debug_info
long flags
long index
HashPosition pos
zend_object std
HashTable storage
struct _spl_SplObjectStorageElement

Definition at line 91 of file spl_observer.c.

Class Members
zval * inf
zval * obj

Define Documentation

Definition at line 884 of file spl_observer.c.

Definition at line 885 of file spl_observer.c.


Typedef Documentation


Enumeration Type Documentation

Enumerator:
MIT_NEED_ANY 
MIT_NEED_ALL 
MIT_KEYS_NUMERIC 
MIT_KEYS_ASSOC 

Definition at line 877 of file spl_observer.c.


Function Documentation

PHP_MINIT_FUNCTION ( spl_observer  )
SPL_METHOD ( SplObserver  ,
update   
)
SPL_METHOD ( SplSubject  ,
attach   
)
SPL_METHOD ( SplSubject  ,
detach   
)
SPL_METHOD ( SplSubject  ,
notify   
)
SPL_METHOD ( SplObjectStorage  ,
attach   
)

Definition at line 394 of file spl_observer.c.

{
       zval *obj, *inf = NULL;

       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|z!", &obj, &inf) == FAILURE) {
              return;
       }
       spl_object_storage_attach(intern, obj, inf TSRMLS_CC);
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
detach   
)

Definition at line 408 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
offsetGet   
)

Definition at line 424 of file spl_observer.c.

{
       zval *obj;
       spl_SplObjectStorageElement *element;
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o", &obj) == FAILURE) {
              return;
       }
       element = spl_object_storage_get(intern, obj TSRMLS_CC);
       if (!element) {
              zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Object not found");
       } else {
              RETURN_ZVAL(element->inf,1, 0);
       }
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
addAll   
)

Definition at line 443 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
removeAll   
)

Definition at line 462 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
removeAllExcept   
)

Definition at line 490 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
contains   
)

Definition at line 520 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
count   
)

Definition at line 533 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
rewind   
)

Definition at line 546 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
valid   
)

Definition at line 560 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
key   
)

Definition at line 573 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
current   
)

Definition at line 586 of file spl_observer.c.

{
       spl_SplObjectStorageElement *element;
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }
       
       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
              return;
       }
       RETVAL_ZVAL(element->obj, 1, 0);
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
getInfo   
)

Definition at line 603 of file spl_observer.c.

{
       spl_SplObjectStorageElement *element;
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }
       
       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
              return;
       }
       RETVAL_ZVAL(element->inf, 1, 0);
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
setInfo   
)

Definition at line 620 of file spl_observer.c.

{
       spl_SplObjectStorageElement *element;
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       zval *inf;
       
       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &inf) == FAILURE) {
              return;
       }

       if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) {
              return;
       }
       zval_ptr_dtor(&element->inf);
       element->inf = inf;
       Z_ADDREF_P(inf);
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
next   
)

Definition at line 640 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
serialize   
)

Definition at line 654 of file spl_observer.c.

{
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);

       spl_SplObjectStorageElement *element;
       zval members, *pmembers;
       HashPosition      pos;
       php_serialize_data_t var_hash;
       smart_str buf = {0};

       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       PHP_VAR_SERIALIZE_INIT(var_hash);
       
       /* storage */
       smart_str_appendl(&buf, "x:i:", 4);
       smart_str_append_long(&buf, zend_hash_num_elements(&intern->storage));
       smart_str_appendc(&buf, ';');

       zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);

       while(zend_hash_has_more_elements_ex(&intern->storage, &pos) == SUCCESS) {
              if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &pos) == FAILURE) {
                     smart_str_free(&buf);
                     PHP_VAR_SERIALIZE_DESTROY(var_hash);
                     RETURN_NULL();
              }
              php_var_serialize(&buf, &element->obj, &var_hash TSRMLS_CC);
              smart_str_appendc(&buf, ',');
              php_var_serialize(&buf, &element->inf, &var_hash TSRMLS_CC);
              smart_str_appendc(&buf, ';');
              zend_hash_move_forward_ex(&intern->storage, &pos);
       }

       /* members */
       smart_str_appendl(&buf, "m:", 2);
       INIT_PZVAL(&members);
       Z_ARRVAL(members) = intern->std.properties;
       Z_TYPE(members) = IS_ARRAY;
       pmembers = &members;
       php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */

       /* done */
       PHP_VAR_SERIALIZE_DESTROY(var_hash);

       if (buf.c) {
              RETURN_STRINGL(buf.c, buf.len, 0);
       } else {
              RETURN_NULL();
       }
       
} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( SplObjectStorage  ,
unserialize   
)

Definition at line 711 of file spl_observer.c.

{
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);

       char *buf;
       int buf_len;
       const unsigned char *p, *s;
       php_unserialize_data_t var_hash;
       zval *pentry, *pmembers, *pcount = NULL, *pinf;
       long count;
       
       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;
       }

       /* storage */
       s = p = (const unsigned char*)buf;
       PHP_VAR_UNSERIALIZE_INIT(var_hash);

       if (*p!= 'x' || *++p != ':') {
              goto outexcept;
       }
       ++p;

       ALLOC_INIT_ZVAL(pcount);
       if (!php_var_unserialize(&pcount, &p, s + buf_len, NULL TSRMLS_CC) || Z_TYPE_P(pcount) != IS_LONG) {
              zval_ptr_dtor(&pcount);
              goto outexcept;
       }

       --p; /* for ';' */
       count = Z_LVAL_P(pcount);
       zval_ptr_dtor(&pcount);
              
       while(count-- > 0) {
              spl_SplObjectStorageElement *pelement;
              
              if (*p != ';') {
                     goto outexcept;
              }
              ++p;
              if(*p != 'O' && *p != 'C' && *p != 'r') {
                     goto outexcept;
              }
              ALLOC_INIT_ZVAL(pentry);
              if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) {
                     zval_ptr_dtor(&pentry);
                     goto outexcept;
              }
              if(Z_TYPE_P(pentry) != IS_OBJECT) {
                     zval_ptr_dtor(&pentry);
                     goto outexcept;
              }
              ALLOC_INIT_ZVAL(pinf);
              if (*p == ',') { /* new version has inf */
                     ++p;
                     if (!php_var_unserialize(&pinf, &p, s + buf_len, &var_hash TSRMLS_CC)) {
                            zval_ptr_dtor(&pinf);
                            goto outexcept;
                     }
              }
              
              pelement = spl_object_storage_get(intern, pentry TSRMLS_CC);
              if(pelement) {
                     if(pelement->inf) {
                            var_push_dtor(&var_hash, &pelement->inf);
                     }
                     if(pelement->obj) {
                            var_push_dtor(&var_hash, &pelement->obj);
                     }
              } 
              spl_object_storage_attach(intern, pentry, pinf TSRMLS_CC);
              zval_ptr_dtor(&pentry);
              zval_ptr_dtor(&pinf);
       }

       if (*p != ';') {
              goto outexcept;
       }
       ++p;

       /* members */
       if (*p!= 'm' || *++p != ':') {
              goto outexcept;
       }
       ++p;

       ALLOC_INIT_ZVAL(pmembers);
       if (!php_var_unserialize(&pmembers, &p, s + buf_len, &var_hash TSRMLS_CC)) {
              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 */

       PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
       return;

outexcept:
       PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
       zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);
       return;

} /* }}} */

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
__construct   
)

Definition at line 889 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
getFlags   
)

Definition at line 910 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
setFlags   
)

Definition at line 923 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
attachIterator   
)

Definition at line 936 of file spl_observer.c.

{
       spl_SplObjectStorage        *intern;
       zval                        *iterator = NULL, *info = NULL;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|z!", &iterator, zend_ce_iterator, &info) == FAILURE) {
              return;
       }

       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);

       if (info != NULL) {
              spl_SplObjectStorageElement *element;
              zval                         compare_result;

              if (Z_TYPE_P(info) != IS_LONG && Z_TYPE_P(info) != IS_STRING) {
                     zend_throw_exception(spl_ce_InvalidArgumentException, "Info must be NULL, integer or string", 0 TSRMLS_CC);
                     return;
              }

              zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
              while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS) {
                     is_identical_function(&compare_result, info, element->inf TSRMLS_CC);
                     if (Z_LVAL(compare_result)) {
                            zend_throw_exception(spl_ce_InvalidArgumentException, "Key duplication error", 0 TSRMLS_CC);
                            return;
                     }
                     zend_hash_move_forward_ex(&intern->storage, &intern->pos);
              }
       }

       spl_object_storage_attach(intern, iterator, info TSRMLS_CC);
}

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
rewind   
)

Definition at line 973 of file spl_observer.c.

{
       spl_SplObjectStorage        *intern;
       spl_SplObjectStorageElement *element;
       zval                        *it;

       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
              it = element->obj;
              zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_rewind, "rewind", NULL);
              zend_hash_move_forward_ex(&intern->storage, &intern->pos);
       }
}

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
next   
)

Definition at line 996 of file spl_observer.c.

{
       spl_SplObjectStorage        *intern;
       spl_SplObjectStorageElement *element;
       zval                        *it;

       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
              it = element->obj;
              zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_next, "next", NULL);
              zend_hash_move_forward_ex(&intern->storage, &intern->pos);
       }
}

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
valid   
)

Definition at line 1019 of file spl_observer.c.

{
       spl_SplObjectStorage        *intern;
       spl_SplObjectStorageElement *element;
       zval                        *it, *retval = NULL;
       long                         expect, valid;

       intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC);
       
       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       if (!zend_hash_num_elements(&intern->storage)) {
              RETURN_FALSE;
       }

       expect = (intern->flags & MIT_NEED_ALL) ? 1 : 0;

       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
              it = element->obj;
              zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);

              if (retval) {
                     valid = Z_LVAL_P(retval);
                     zval_ptr_dtor(&retval);
              } else {
                     valid = 0;
              }

              if (expect != valid) {
                     RETURN_BOOL(!expect);
              }

              zend_hash_move_forward_ex(&intern->storage, &intern->pos);
       }

       RETURN_BOOL(expect);
}

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
current   
)

Definition at line 1131 of file spl_observer.c.

Here is the call graph for this function:

SPL_METHOD ( MultipleIterator  ,
key   
)

Definition at line 1146 of file spl_observer.c.

Here is the call graph for this function:

static void spl_multiple_iterator_get_all ( spl_SplObjectStorage intern,
int  get_type,
zval *return_value  TSRMLS_DC 
) [static]

Definition at line 1061 of file spl_observer.c.

{
       spl_SplObjectStorageElement *element;
       zval                        *it, *retval = NULL;
       int                          valid = 1, num_elements;

       num_elements = zend_hash_num_elements(&intern->storage);
       if (num_elements < 1) {
              RETURN_FALSE;
       }

       array_init_size(return_value, num_elements);
       
       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
       while (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == SUCCESS && !EG(exception)) {
              it = element->obj;
              zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_valid, "valid", &retval);

              if (retval) {
                     valid = Z_LVAL_P(retval);
                     zval_ptr_dtor(&retval);
              } else {
                     valid = 0;
              }

              if (valid) {
                     if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
                            zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_current, "current", &retval);
                     } else {
                            zend_call_method_with_0_params(&it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs.zf_key,     "key",     &retval);
                     }
                     if (!retval) {
                            zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0 TSRMLS_CC);
                            return;
                     }
              } else if (intern->flags & MIT_NEED_ALL) {
                     if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
                            zend_throw_exception(spl_ce_RuntimeException, "Called current() with non valid sub iterator", 0 TSRMLS_CC);
                     } else {
                            zend_throw_exception(spl_ce_RuntimeException, "Called key() with non valid sub iterator", 0 TSRMLS_CC);
                     }
                     return;
              } else {
                     ALLOC_INIT_ZVAL(retval);
              }

              if (intern->flags & MIT_KEYS_ASSOC) {
                     switch (Z_TYPE_P(element->inf)) {
                            case IS_LONG:
                                   add_index_zval(return_value, Z_LVAL_P(element->inf), retval);
                                   break;
                            case IS_STRING:
                                   add_assoc_zval_ex(return_value, Z_STRVAL_P(element->inf), Z_STRLEN_P(element->inf)+1U, retval);
                                   break;
                            default:
                                   zval_ptr_dtor(&retval);
                                   zend_throw_exception(spl_ce_InvalidArgumentException, "Sub-Iterator is associated with NULL", 0 TSRMLS_CC);
                                   return;
                     }
              } else {
                     add_next_index_zval(return_value, retval);
              }

              zend_hash_move_forward_ex(&intern->storage, &intern->pos);
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void spl_object_storage_addall ( spl_SplObjectStorage intern,
spl_SplObjectStorage *other  TSRMLS_DC 
)

Definition at line 184 of file spl_observer.c.

                                                                                                    { /* {{{ */
       HashPosition pos;
       spl_SplObjectStorageElement *element;

       zend_hash_internal_pointer_reset_ex(&other->storage, &pos);
       while (zend_hash_get_current_data_ex(&other->storage, (void **)&element, &pos) == SUCCESS) {
              spl_object_storage_attach(intern, element->obj, element->inf TSRMLS_CC);
              zend_hash_move_forward_ex(&other->storage, &pos);
       }

       zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
       intern->index = 0;
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

void spl_object_storage_attach ( spl_SplObjectStorage intern,
zval *  obj,
zval *inf  TSRMLS_DC 
)

Definition at line 139 of file spl_observer.c.

{
       spl_SplObjectStorageElement *pelement, element;
       pelement = spl_object_storage_get(intern, obj TSRMLS_CC);
       if (inf) {
              Z_ADDREF_P(inf);
       } else {
              ALLOC_INIT_ZVAL(inf);
       }
       if (pelement) {
              zval_ptr_dtor(&pelement->inf);
              pelement->inf = inf;
              return;
       }
       Z_ADDREF_P(obj);
       element.obj = obj;
       element.inf = inf;
#if HAVE_PACKED_OBJECT_VALUE
       zend_hash_update(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL);       
#else
       {
              zend_object_value zvalue;
              memset(&zvalue, 0, sizeof(zend_object_value));
              zvalue.handle = Z_OBJ_HANDLE_P(obj);
              zvalue.handlers = Z_OBJ_HT_P(obj);
              zend_hash_update(&intern->storage, (char*)&zvalue, sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL);
       }
#endif
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static zend_object_value spl_object_storage_clone ( zval *zobject  TSRMLS_DC) [static]

Definition at line 226 of file spl_observer.c.

{
       zend_object_value new_obj_val;
       zend_object *old_object;
       zend_object *new_object;
       zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
       spl_SplObjectStorage *intern;

       old_object = zend_objects_get_address(zobject TSRMLS_CC);
       new_obj_val = spl_object_storage_new_ex(old_object->ce, &intern, zobject TSRMLS_CC);
       new_object = &intern->std;

       zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);

       return new_obj_val;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 344 of file spl_observer.c.

{
       zval result;

       if (compare_function(&result, e1->inf, e2->inf TSRMLS_CC) == FAILURE) {
              return 1;
       }

       return Z_LVAL(result);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int spl_object_storage_compare_objects ( zval *  o1,
zval *o2  TSRMLS_DC 
) [static]

Definition at line 356 of file spl_observer.c.

Here is the call graph for this function:

Here is the caller graph for this function:

int spl_object_storage_contains ( spl_SplObjectStorage intern,
zval *obj  TSRMLS_DC 
)

Definition at line 377 of file spl_observer.c.

{
#if HAVE_PACKED_OBJECT_VALUE
       return zend_hash_exists(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value));
#else
       {
              zend_object_value zvalue;
              memset(&zvalue, 0, sizeof(zend_object_value));
              zvalue.handle = Z_OBJ_HANDLE_P(obj);
              zvalue.handlers = Z_OBJ_HT_P(obj);
              return zend_hash_exists(&intern->storage, (char*)&zvalue, sizeof(zend_object_value));
       }
#endif
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static HashTable* spl_object_storage_debug_info ( zval *  obj,
int *is_temp  TSRMLS_DC 
) [static]

Definition at line 244 of file spl_observer.c.

{
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
       spl_SplObjectStorageElement *element;
       HashTable *props;
       HashPosition pos;
       zval *tmp, *storage;
       char md5str[33];
       int name_len;
       char *zname;

       *is_temp = 0;

       props = Z_OBJPROP_P(obj);
       zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));

       if (intern->debug_info == NULL) {
              ALLOC_HASHTABLE(intern->debug_info);
              ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0);
       }

       if (intern->debug_info->nApplyCount == 0) {
              zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

              MAKE_STD_ZVAL(storage);
              array_init(storage);

              zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
              while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
                            php_spl_object_hash(element->obj, md5str TSRMLS_CC);
                            MAKE_STD_ZVAL(tmp);
                            array_init(tmp);
                            /* Incrementing the refcount of obj and inf would confuse the garbage collector.
                             * Prefer to null the destructor */
                            Z_ARRVAL_P(tmp)->pDestructor = NULL;
                            add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj);
                            add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf);
                            add_assoc_zval_ex(storage, md5str, 33, tmp);
                            zend_hash_move_forward_ex(&intern->storage, &pos);
              }

              zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC);
              zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL);
              efree(zname);
       }

       return intern->debug_info;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int spl_object_storage_detach ( spl_SplObjectStorage intern,
zval *obj  TSRMLS_DC 
)

Definition at line 169 of file spl_observer.c.

{
#if HAVE_PACKED_OBJECT_VALUE
       return zend_hash_del(&intern->storage, (char*)&Z_OBJVAL_P(obj), sizeof(zend_object_value));
#else
       {
              zend_object_value zvalue;
              memset(&zvalue, 0, sizeof(zend_object_value));
              zvalue.handle = Z_OBJ_HANDLE_P(obj);
              zvalue.handlers = Z_OBJ_HT_P(obj);
              return zend_hash_del(&intern->storage, (char*)&zvalue, sizeof(zend_object_value));
       }
#endif
} /* }}}*/

Here is the caller graph for this function:

static void spl_object_storage_dtor ( spl_SplObjectStorageElement element) [static]

Definition at line 112 of file spl_observer.c.

{
       zval_ptr_dtor(&element->obj);
       zval_ptr_dtor(&element->inf);
} /* }}} */

Here is the caller graph for this function:

Definition at line 119 of file spl_observer.c.

{
       spl_SplObjectStorageElement *element;
       zend_object_value *pzvalue; 
#if HAVE_PACKED_OBJECT_VALUE
       pzvalue = &Z_OBJVAL_P(obj);
#else
       zend_object_value zvalue;
       memset(&zvalue, 0, sizeof(zend_object_value));
       zvalue.handle = Z_OBJ_HANDLE_P(obj);
       zvalue.handlers = Z_OBJ_HT_P(obj);
       pzvalue = &zvalue;
#endif
       if (zend_hash_find(&intern->storage, (char*)pzvalue, sizeof(zend_object_value), (void**)&element) == SUCCESS) {
              return element;
       } else {
              return NULL;
       }
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:

static HashTable* spl_object_storage_get_properties ( zval *obj  TSRMLS_DC) [static]

Definition at line 297 of file spl_observer.c.

{
       spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC);
       spl_SplObjectStorageElement *element;
       HashTable *props;
       HashPosition pos;
       zval *gcdata_arr = NULL,
               **gcdata_arr_pp;

       props = std_object_handlers.get_properties(obj TSRMLS_CC);
       
       if (!GC_G(gc_active)) {
              zend_hash_del(props, "\x00gcdata", sizeof("\x00gcdata"));
              return props;
       }

       if (props->nApplyCount > 0) {
              return props;
       }

       /* clean \x00gcdata, as it may be out of date */
       if (zend_hash_find(props, "\x00gcdata", sizeof("\x00gcdata"), (void**) &gcdata_arr_pp) == SUCCESS) {
              gcdata_arr = *gcdata_arr_pp;
              zend_hash_clean(Z_ARRVAL_P(gcdata_arr));
       }

       if (gcdata_arr == NULL) {
              MAKE_STD_ZVAL(gcdata_arr);
              array_init(gcdata_arr);
              /* don't decrease refcount of members when destroying */
              Z_ARRVAL_P(gcdata_arr)->pDestructor = NULL;

              /* name starts with \x00 to make tampering in user-land more difficult */
              zend_hash_add(props, "\x00gcdata", sizeof("\x00gcdata"), &gcdata_arr, sizeof(gcdata_arr), NULL);
       }

       zend_hash_internal_pointer_reset_ex(&intern->storage, &pos);
       while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) {
              add_next_index_zval(gcdata_arr, element->obj);
              add_next_index_zval(gcdata_arr, element->inf);
              zend_hash_move_forward_ex(&intern->storage, &pos);
       }

       return props;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static zend_object_value spl_object_storage_new_ex ( zend_class_entry *  class_type,
spl_SplObjectStorage **  obj,
zval *orig  TSRMLS_DC 
) [static]

Definition at line 198 of file spl_observer.c.

{
       zend_object_value retval;
       spl_SplObjectStorage *intern;
       zval *tmp;

       intern = emalloc(sizeof(spl_SplObjectStorage));
       memset(intern, 0, sizeof(spl_SplObjectStorage));
       *obj = intern;

       zend_object_std_init(&intern->std, class_type TSRMLS_CC);
       zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));

       zend_hash_init(&intern->storage, 0, NULL, (void (*)(void *))spl_object_storage_dtor, 0);

       retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC);
       retval.handlers = &spl_handler_SplObjectStorage;

       if (orig) {
              spl_SplObjectStorage *other = (spl_SplObjectStorage*)zend_object_store_get_object(orig TSRMLS_CC);
              spl_object_storage_addall(intern, other TSRMLS_CC);
       }

       return retval;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static zend_object_value spl_SplObjectStorage_new ( zend_class_entry *class_type  TSRMLS_DC) [static]

Definition at line 370 of file spl_observer.c.

{
       spl_SplObjectStorage *tmp;
       return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void spl_SplOjectStorage_free_storage ( void *object  TSRMLS_DC)

Definition at line 96 of file spl_observer.c.

{
       spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object;

       zend_object_std_dtor(&intern->std TSRMLS_CC);
       
       zend_hash_destroy(&intern->storage);
       
       if (intern->debug_info != NULL) {
              zend_hash_destroy(intern->debug_info);
              efree(intern->debug_info);
       }

       efree(object);
} /* }}} */

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

PHPAPI zend_class_entry* spl_ce_MultipleIterator

Definition at line 77 of file spl_observer.c.

PHPAPI zend_class_entry* spl_ce_SplObjectStorage

Definition at line 76 of file spl_observer.c.

PHPAPI zend_class_entry* spl_ce_SplObserver

Definition at line 74 of file spl_observer.c.

PHPAPI zend_class_entry* spl_ce_SplSubject

Definition at line 75 of file spl_observer.c.

Initial value:
 {







       




       SPL_ME(MultipleIterator,  next,                   arginfo_splobject_void,                     0)
       {NULL, NULL, NULL}
}

Definition at line 1176 of file spl_observer.c.

Initial value:
 {








       

       





       


       



       SPL_ME(SplObjectStorage, offsetGet,    arginfo_offsetGet,     0)
       {NULL, NULL, NULL}
}

Definition at line 849 of file spl_observer.c.

Initial value:
 {
       SPL_ABSTRACT_ME(SplObserver, update,   arginfo_SplObserver_update)
       {NULL, NULL, NULL}
}

Definition at line 51 of file spl_observer.c.

Initial value:
 {


       SPL_ABSTRACT_ME(SplSubject,  notify,   arginfo_SplSubject_void)
       {NULL, NULL, NULL}
}

Definition at line 67 of file spl_observer.c.

PHPAPI zend_object_handlers spl_handler_SplObjectStorage

Definition at line 79 of file spl_observer.c.