[PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc
helly Mon Jan 28 22:43:21 2008 UTC Modified files: /php-src/ext/splspl_observer.c /php-src/ext/spl/internal splobjectstorage.inc Log: - Make SplObjectStorage implement ArrayAccess http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_observer.c?r1=1.22&r2=1.23&diff_format=u Index: php-src/ext/spl/spl_observer.c diff -u php-src/ext/spl/spl_observer.c:1.22 php-src/ext/spl/spl_observer.c:1.23 --- php-src/ext/spl/spl_observer.c:1.22 Sun Jan 27 18:04:54 2008 +++ php-src/ext/spl/spl_observer.c Mon Jan 28 22:43:21 2008 @@ -16,7 +16,7 @@ +--+ */ -/* $Id: spl_observer.c,v 1.22 2008/01/27 18:04:54 helly Exp $ */ +/* $Id: spl_observer.c,v 1.23 2008/01/28 22:43:21 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -288,6 +288,25 @@ intern->index = 0; } /* }}} */ +/* {{{ proto mixed SplObjectStorage::offsetGet($object) U + Returns associated information for a stored object */ +SPL_METHOD(SplObjectStorage, offsetGet) +{ + 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); + } +} /* }}} */ + /* {{{ proto bool SplObjectStorage::contains($obj) U Determine whethe an object is contained in the storage */ SPL_METHOD(SplObjectStorage, contains) @@ -565,20 +584,39 @@ ZEND_ARG_INFO(0, info) ZEND_END_ARG_INFO(); +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetGet, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +static +ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, info) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, attach, arginfo_attach,0) SPL_ME(SplObjectStorage, detach, arginfo_Object,0) SPL_ME(SplObjectStorage, contains,arginfo_Object,0) + SPL_ME(SplObjectStorage, getInfo, NULL, 0) + SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) + /* Countable */ SPL_ME(SplObjectStorage, count, NULL, 0) + /* Iterator */ SPL_ME(SplObjectStorage, rewind, NULL, 0) SPL_ME(SplObjectStorage, valid, NULL, 0) SPL_ME(SplObjectStorage, key, NULL, 0) SPL_ME(SplObjectStorage, current, NULL, 0) SPL_ME(SplObjectStorage, next,NULL, 0) + /* Serializable */ SPL_ME(SplObjectStorage, unserialize, arginfo_Serialized,0) SPL_ME(SplObjectStorage, serialize, NULL, 0) - SPL_ME(SplObjectStorage, getInfo, NULL, 0) - SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) + /* ArrayAccess */ + SPL_MA(SplObjectStorage, offsetExists, SplObjectStorage, contains, arginfo_offsetGet, 0) + SPL_MA(SplObjectStorage, offsetSet,SplObjectStorage, attach, arginfo_offsetSet, 0) + SPL_MA(SplObjectStorage, offsetUnset, SplObjectStorage, detach, arginfo_offsetGet, 0) + SPL_ME(SplObjectStorage, offsetGet,arginfo_offsetGet, 0) {NULL, NULL, NULL} }; @@ -595,6 +633,7 @@ REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Countable); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Iterator); REGISTER_SPL_IMPLEMENTS(SplObjectStorage, Serializable); + REGISTER_SPL_IMPLEMENTS(SplObjectStorage, ArrayAccess); return SUCCESS; } http://cvs.php.net/viewvc.cgi/php-src/ext/spl/internal/splobjectstorage.inc?r1=1.5&r2=1.6&diff_format=u Index: php-src/ext/spl/internal/splobjectstorage.inc diff -u php-src/ext/spl/internal/splobjectstorage.inc:1.5 php-src/ext/spl/internal/splobjectstorage.inc:1.6 --- php-src/ext/spl/internal/splobjectstorage.inc:1.5 Sun Jan 27 18:04:54 2008 +++ php-src/ext/spl/internal/splobjectstorage.inc Mon Jan 28 22:43:21 2008 @@ -20,7 +20,7 @@ * here therefore has a complexity of O(n) while the actual implementation has * complexity O(1). */ -class SplObjectStorage implements Iterator, Countable +class SplObjectStorage implements Iterator, Countable, ArrayAccess { private $storage = array(); private $index = 0; @@ -88,9 +88,9 @@ return count($this->storage); } - /** @param obj object to look for + /** @pa
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
Hello Andrei, it would only help if the schema used is always the same so that it is trustably unique. The following two lines achieve that: char *key; spprintf(&key, 0, "%s::%d", Z_OBJCE_P(obj)->name, obj->value.obj.handle); Yep would help in a few edge cases and allow O(1) implementation of ObjectStorage. regards marcus Thursday, August 11, 2005, 1:30:14 AM, you wrote: > What we really need is a get_hash_t handler on the object, so that each > object knows how to hash itself. This can also come in handy when using > objects as array keys. > -Andrei > On Aug 10, 2005, at 3:39 PM, Marcus Boerger wrote: >> Hello Andrey, >> >> wrong assumption. That is only the handle but only the handle+handler >> combination is unique. >> >> marcus >> >> Thursday, August 11, 2005, 12:32:07 AM, you wrote: >> >>> Marcus Boerger wrote: Hello Andrey, thanks! I wanted to do it earlier but had no idea how to sole the problem. I actually right from the beginning wanted to do all three in there. Anyway you might also want to see t he last slides of my last presentation (the one from OSCON) which you can find here: http://talks.somabo.de/ best regards marcus Thursday, August 11, 2005, 12:04:37 AM, you wrote: > Wonderful idea Helly! > Andrey >> >>> However, I think you are wrong that it cannot be implemented in user >>> land with O(1) >>> complexity. The following one-liner should give you a hint why I >>> think it is possible. >> >>> [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ >>> ob_start(); >>> var_dump($obj); $v=ob_get_contents(); >>> ob_end_clean();var_dump(substr($v, 7, strpos($v, " >>> ", 11) - 7));} get_hash_key(new a);' >>> string(4) "a)#1" >> >>> The string is unique per object. ) and # are noise but they are not a >>> problem. >> >>> Best wishes, >>> Andrey >> >> >> >> Best regards, >> Marcus >> >> -- >> PHP CVS Mailing List (http://www.php.net/) >> To unsubscribe, visit: http://www.php.net/unsub.php Best regards, Marcus -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
What we really need is a get_hash_t handler on the object, so that each object knows how to hash itself. This can also come in handy when using objects as array keys. -Andrei On Aug 10, 2005, at 3:39 PM, Marcus Boerger wrote: Hello Andrey, wrong assumption. That is only the handle but only the handle+handler combination is unique. marcus Thursday, August 11, 2005, 12:32:07 AM, you wrote: Marcus Boerger wrote: Hello Andrey, thanks! I wanted to do it earlier but had no idea how to sole the problem. I actually right from the beginning wanted to do all three in there. Anyway you might also want to see t he last slides of my last presentation (the one from OSCON) which you can find here: http://talks.somabo.de/ best regards marcus Thursday, August 11, 2005, 12:04:37 AM, you wrote: Wonderful idea Helly! Andrey However, I think you are wrong that it cannot be implemented in user land with O(1) complexity. The following one-liner should give you a hint why I think it is possible. [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ ob_start(); var_dump($obj); $v=ob_get_contents(); ob_end_clean();var_dump(substr($v, 7, strpos($v, " ", 11) - 7));} get_hash_key(new a);' string(4) "a)#1" The string is unique per object. ) and # are noise but they are not a problem. Best wishes, Andrey Best regards, Marcus -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
Hello Andrey, wrong assumption. That is only the handle but only the handle+handler combination is unique. marcus Thursday, August 11, 2005, 12:32:07 AM, you wrote: > Marcus Boerger wrote: >> Hello Andrey, >> >> thanks! I wanted to do it earlier but had no idea how to sole the problem. >> I actually right from the beginning wanted to do all three in there. Anyway >> you might also want to see t he last slides of my last presentation (the one >> from OSCON) which you can find here: http://talks.somabo.de/ >> >> best regards >> marcus >> >> Thursday, August 11, 2005, 12:04:37 AM, you wrote: >> >> >>> Wonderful idea Helly! >> >> >>>Andrey >> >> > However, I think you are wrong that it cannot be implemented in user land > with O(1) > complexity. The following one-liner should give you a hint why I think it is > possible. > [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ > ob_start(); > var_dump($obj); $v=ob_get_contents(); > ob_end_clean();var_dump(substr($v, 7, strpos($v, " > ", 11) - 7));} get_hash_key(new a);' > string(4) "a)#1" > The string is unique per object. ) and # are noise but they are not a problem. > Best wishes, > Andrey Best regards, Marcus -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
Marcus Boerger wrote: Hello Andrey, thanks! I wanted to do it earlier but had no idea how to sole the problem. I actually right from the beginning wanted to do all three in there. Anyway you might also want to see t he last slides of my last presentation (the one from OSCON) which you can find here: http://talks.somabo.de/ best regards marcus Thursday, August 11, 2005, 12:04:37 AM, you wrote: Wonderful idea Helly! Andrey However, I think you are wrong that it cannot be implemented in user land with O(1) complexity. The following one-liner should give you a hint why I think it is possible. [EMAIL PROTECTED]:~/test> php -r 'class a{} function get_hash_key($obj){ ob_start(); var_dump($obj); $v=ob_get_contents(); ob_end_clean();var_dump(substr($v, 7, strpos($v, " ", 11) - 7));} get_hash_key(new a);' string(4) "a)#1" The string is unique per object. ) and # are noise but they are not a problem. Best wishes, Andrey -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
Hello Andrey, thanks! I wanted to do it earlier but had no idea how to sole the problem. I actually right from the beginning wanted to do all three in there. Anyway you might also want to see t he last slides of my last presentation (the one from OSCON) which you can find here: http://talks.somabo.de/ best regards marcus Thursday, August 11, 2005, 12:04:37 AM, you wrote: >Wonderful idea Helly! > Andrey > Marcus Boerger wrote: >> helly Wed Aug 10 17:56:02 2005 EDT >> >> Added files: >> /php-src/ext/spl/internal splobjectstorage.inc >> /php-src/ext/spl/testsobserver_002.phpt >> >> Modified files: >> /php-src/ext/spl spl_observer.c >> Log: >> - Implement SplObjectStorage as announced during OSCON >> # This class starts naming of new classes in Spl by prefix Spl as dicussed. >> # The class reduces object storage complexity from O(n) to O(1) which is >> # not possible in user space. >> >> >> >> >> >> >> http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u >> Index: php-src/ext/spl/spl_observer.c >> diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3 >> --- php-src/ext/spl/spl_observer.c:1.2Wed Aug 3 10:07:53 2005 >> +++ php-src/ext/spl/spl_observer.cWed Aug 10 17:56:00 2005 >> @@ -16,7 +16,7 @@ >> >> +--+ >> */ >> >> -/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */ >> +/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */ >> >> #ifdef HAVE_CONFIG_H >> # include "config.h" >> @@ -32,6 +32,8 @@ >> #include "spl_functions.h" >> #include "spl_engine.h" >> #include "spl_observer.h" >> +#include "spl_iterators.h" >> +#include "spl_array.h" >> >> SPL_METHOD(Observer, update); >> SPL_METHOD(Subject, attach); >> @@ -65,14 +67,197 @@ >> {NULL, NULL, NULL} >> }; >> >> -PHPAPI zend_class_entry *spl_ce_Observer; >> -PHPAPI zend_class_entry *spl_ce_Subject; >> +PHPAPI zend_class_entry *spl_ce_Observer; >> +PHPAPI zend_class_entry *spl_ce_Subject; >> +PHPAPI zend_class_entry *spl_ce_SplObjectStorage; >> +PHPAPI zend_object_handlers spl_handler_SplObjectStorage; >> + >> +typedef struct _spl_SplObjectStorage { >> + zend_object std; >> + HashTable storage; >> + long index; >> + HashPosition pos; >> +} spl_SplObjectStorage; >> + >> +/* storage is an assoc aray of [zend_object_value]=>[zval*] */ >> + >> +void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ >> +{ >> + spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object; >> + >> + zend_hash_destroy(intern->std.properties); >> + FREE_HASHTABLE(intern->std.properties); >> + >> + zend_hash_destroy(&intern->storage); >> + >> + efree(object); >> +} /* }}} */ >> + >> +static zend_object_value spl_object_storage_new_ex(zend_class_entry >> *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */ >> +{ >> + zend_object_value retval; >> + spl_SplObjectStorage *intern; >> + zval *tmp; >> + >> + intern = emalloc(sizeof(spl_SplObjectStorage)); >> + memset(intern, 0, sizeof(spl_SplObjectStorage)); >> + intern->std.ce = class_type; >> + *obj = intern; >> + >> + ALLOC_HASHTABLE(intern->std.properties); >> + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); >> + 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, ZVAL_PTR_DTOR, 0); >> + >> + retval.handle = zend_objects_store_put(intern, NULL, >> (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, >> NULL TSRMLS_CC); >> + retval.handlers = &spl_handler_SplObjectStorage; >> + return retval; >> +} >> +/* }}} */ >> + >> +/* {{{ spl_array_object_new */ >> +static zend_object_value spl_SplObjectStorage_new(zend_class_entry >> *class_type TSRMLS_DC) >> +{ >> + spl_SplObjectStorage *tmp; >> + return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC); >> +} >> +/* }}} */ >> + >> +/* {{{ proto void SplObjectStorage::attach($obj) >> + Attaches an object to the storage if not yet contained */ >> +SPL_METHOD(SplObjectStorage, attach) >> +{ >> + zval *obj; >> + 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; >> + } >> + >> + zend_hash_update(&intern->storage, (char*)&obj->value.obj, >> sizeof(obj->value.obj), &obj, sizeof(zval**), NULL); >> + obj->refcount++; >> +} /* }}} */ >> + >> +/* {{{ proto void SplObjectStorage::detach($obj) >> + D
Re: [PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
Wonderful idea Helly! Andrey Marcus Boerger wrote: helly Wed Aug 10 17:56:02 2005 EDT Added files: /php-src/ext/spl/internal splobjectstorage.inc /php-src/ext/spl/tests observer_002.phpt Modified files: /php-src/ext/spl spl_observer.c Log: - Implement SplObjectStorage as announced during OSCON # This class starts naming of new classes in Spl by prefix Spl as dicussed. # The class reduces object storage complexity from O(n) to O(1) which is # not possible in user space. http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u Index: php-src/ext/spl/spl_observer.c diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3 --- php-src/ext/spl/spl_observer.c:1.2 Wed Aug 3 10:07:53 2005 +++ php-src/ext/spl/spl_observer.c Wed Aug 10 17:56:00 2005 @@ -16,7 +16,7 @@ +--+ */ -/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */ +/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -32,6 +32,8 @@ #include "spl_functions.h" #include "spl_engine.h" #include "spl_observer.h" +#include "spl_iterators.h" +#include "spl_array.h" SPL_METHOD(Observer, update); SPL_METHOD(Subject, attach); @@ -65,14 +67,197 @@ {NULL, NULL, NULL} }; -PHPAPI zend_class_entry *spl_ce_Observer; -PHPAPI zend_class_entry *spl_ce_Subject; +PHPAPI zend_class_entry *spl_ce_Observer; +PHPAPI zend_class_entry *spl_ce_Subject; +PHPAPI zend_class_entry *spl_ce_SplObjectStorage; +PHPAPI zend_object_handlers spl_handler_SplObjectStorage; + +typedef struct _spl_SplObjectStorage { + zend_object std; + HashTable storage; + long index; + HashPosition pos; +} spl_SplObjectStorage; + +/* storage is an assoc aray of [zend_object_value]=>[zval*] */ + +void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ +{ + spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object; + + zend_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + zend_hash_destroy(&intern->storage); + + efree(object); +} /* }}} */ + +static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + spl_SplObjectStorage *intern; + zval *tmp; + + intern = emalloc(sizeof(spl_SplObjectStorage)); + memset(intern, 0, sizeof(spl_SplObjectStorage)); + intern->std.ce = class_type; + *obj = intern; + + ALLOC_HASHTABLE(intern->std.properties); + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + 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, ZVAL_PTR_DTOR, 0); + + retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC); + retval.handlers = &spl_handler_SplObjectStorage; + return retval; +} +/* }}} */ + +/* {{{ spl_array_object_new */ +static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC) +{ + spl_SplObjectStorage *tmp; + return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto void SplObjectStorage::attach($obj) + Attaches an object to the storage if not yet contained */ +SPL_METHOD(SplObjectStorage, attach) +{ + zval *obj; + 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; + } + + zend_hash_update(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj), &obj, sizeof(zval**), NULL); + obj->refcount++; +} /* }}} */ + +/* {{{ proto void SplObjectStorage::detach($obj) + Detaches an object from the storage */ +SPL_METHOD(SplObjectStorage, detach) +{ + zval *obj; + 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; + } + + zend_hash_del(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj)); + zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); + intern->index = 0; +} /* }}} */ + +/* {{{ proto bool SplObjectStorage::contains($obj) + Determine whethe an object is contained in the storage */ +SPL_METHOD(SplObjectStorage, contains) +{
[PHP-CVS] cvs: php-src /ext/spl spl_observer.c /ext/spl/internal splobjectstorage.inc /ext/spl/tests observer_002.phpt
helly Wed Aug 10 17:56:02 2005 EDT Added files: /php-src/ext/spl/internal splobjectstorage.inc /php-src/ext/spl/tests observer_002.phpt Modified files: /php-src/ext/splspl_observer.c Log: - Implement SplObjectStorage as announced during OSCON # This class starts naming of new classes in Spl by prefix Spl as dicussed. # The class reduces object storage complexity from O(n) to O(1) which is # not possible in user space. http://cvs.php.net/diff.php/php-src/ext/spl/spl_observer.c?r1=1.2&r2=1.3&ty=u Index: php-src/ext/spl/spl_observer.c diff -u php-src/ext/spl/spl_observer.c:1.2 php-src/ext/spl/spl_observer.c:1.3 --- php-src/ext/spl/spl_observer.c:1.2 Wed Aug 3 10:07:53 2005 +++ php-src/ext/spl/spl_observer.c Wed Aug 10 17:56:00 2005 @@ -16,7 +16,7 @@ +--+ */ -/* $Id: spl_observer.c,v 1.2 2005/08/03 14:07:53 sniper Exp $ */ +/* $Id: spl_observer.c,v 1.3 2005/08/10 21:56:00 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -32,6 +32,8 @@ #include "spl_functions.h" #include "spl_engine.h" #include "spl_observer.h" +#include "spl_iterators.h" +#include "spl_array.h" SPL_METHOD(Observer, update); SPL_METHOD(Subject, attach); @@ -65,14 +67,197 @@ {NULL, NULL, NULL} }; -PHPAPI zend_class_entry *spl_ce_Observer; -PHPAPI zend_class_entry *spl_ce_Subject; +PHPAPI zend_class_entry *spl_ce_Observer; +PHPAPI zend_class_entry *spl_ce_Subject; +PHPAPI zend_class_entry *spl_ce_SplObjectStorage; +PHPAPI zend_object_handlers spl_handler_SplObjectStorage; + +typedef struct _spl_SplObjectStorage { + zend_object std; + HashTable storage; + long index; + HashPosition pos; +} spl_SplObjectStorage; + +/* storage is an assoc aray of [zend_object_value]=>[zval*] */ + +void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ +{ + spl_SplObjectStorage *intern = (spl_SplObjectStorage *)object; + + zend_hash_destroy(intern->std.properties); + FREE_HASHTABLE(intern->std.properties); + + zend_hash_destroy(&intern->storage); + + efree(object); +} /* }}} */ + +static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */ +{ + zend_object_value retval; + spl_SplObjectStorage *intern; + zval *tmp; + + intern = emalloc(sizeof(spl_SplObjectStorage)); + memset(intern, 0, sizeof(spl_SplObjectStorage)); + intern->std.ce = class_type; + *obj = intern; + + ALLOC_HASHTABLE(intern->std.properties); + zend_hash_init(intern->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0); + 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, ZVAL_PTR_DTOR, 0); + + retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) spl_SplOjectStorage_free_storage, NULL TSRMLS_CC); + retval.handlers = &spl_handler_SplObjectStorage; + return retval; +} +/* }}} */ + +/* {{{ spl_array_object_new */ +static zend_object_value spl_SplObjectStorage_new(zend_class_entry *class_type TSRMLS_DC) +{ + spl_SplObjectStorage *tmp; + return spl_object_storage_new_ex(class_type, &tmp, NULL TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto void SplObjectStorage::attach($obj) + Attaches an object to the storage if not yet contained */ +SPL_METHOD(SplObjectStorage, attach) +{ + zval *obj; + 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; + } + + zend_hash_update(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj), &obj, sizeof(zval**), NULL); + obj->refcount++; +} /* }}} */ + +/* {{{ proto void SplObjectStorage::detach($obj) + Detaches an object from the storage */ +SPL_METHOD(SplObjectStorage, detach) +{ + zval *obj; + 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; + } + + zend_hash_del(&intern->storage, (char*)&obj->value.obj, sizeof(obj->value.obj)); + zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos); + intern->index = 0; +} /* }}} */ + +/* {{{ proto bool SplObjectStorage::contains($obj) + Determine whethe an object is contained in the storage */ +SPL_METHOD(SplObjectStorage, contains) +{ + zval *obj; + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_C