helly Sun Jan 27 18:07:20 2008 UTC Added files: (Branch: PHP_5_3) /php-src/ext/spl/tests observer_006.phpt
Modified files: /php-src NEWS /php-src/ext/spl spl_observer.c /php-src/ext/spl/internal splobjectstorage.inc /php-src/ext/spl/tests observer_004.phpt observer_005.phpt Log: MFH: [DOC] Add ability to store associative infor with objects in SplObjectStorage - Add second parameter to SplObjectStorage::attach() - Add SplObjectStorage::setInfo() - Add SplObjectStorage::getInfo()
http://cvs.php.net/viewvc.cgi/php-src/NEWS?r1=1.2027.2.547.2.965.2.89&r2=1.2027.2.547.2.965.2.90&diff_format=u Index: php-src/NEWS diff -u php-src/NEWS:1.2027.2.547.2.965.2.89 php-src/NEWS:1.2027.2.547.2.965.2.90 --- php-src/NEWS:1.2027.2.547.2.965.2.89 Sun Jan 27 17:29:14 2008 +++ php-src/NEWS Sun Jan 27 18:07:20 2008 @@ -19,6 +19,8 @@ * date_timestamp_set() / DateTime::setTimestamp() to set a Unix timestamp without invoking the date parser. (Scott) +- Added ability to store associative infor with objects in SplObjectStorage. + (Marcus) - Added ability to use Traversable objects instead of plain arrays in ext/soap. (Joshua Reese, Dmitry) - Added "?:" operator. (Marcus) http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_observer.c?r1=1.2.2.6.2.3.2.5&r2=1.2.2.6.2.3.2.6&diff_format=u Index: php-src/ext/spl/spl_observer.c diff -u php-src/ext/spl/spl_observer.c:1.2.2.6.2.3.2.5 php-src/ext/spl/spl_observer.c:1.2.2.6.2.3.2.6 --- php-src/ext/spl/spl_observer.c:1.2.2.6.2.3.2.5 Sun Jan 27 15:23:14 2008 +++ php-src/ext/spl/spl_observer.c Sun Jan 27 18:07:20 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.c,v 1.2.2.6.2.3.2.5 2008/01/27 15:23:14 helly Exp $ */ +/* $Id: spl_observer.c,v 1.2.2.6.2.3.2.6 2008/01/27 18:07:20 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -75,14 +75,18 @@ PHPAPI zend_class_entry *spl_ce_SplObjectStorage; PHPAPI zend_object_handlers spl_handler_SplObjectStorage; -typedef struct _spl_SplObjectStorage { +typedef struct _spl_SplObjectStorage { /* {{{ */ zend_object std; HashTable storage; long index; HashPosition pos; -} spl_SplObjectStorage; +} spl_SplObjectStorage; /* }}} */ -/* storage is an assoc aray of [zend_object_value]=>[zval*] */ +/* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */ +typedef struct _spl_SplObjectStorageElement { + zval* obj; + zval* inf; +} spl_SplObjectStorageElement; /* }}} */ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ { @@ -95,9 +99,10 @@ efree(object); } /* }}} */ -static void spl_object_storage_dtor(zval **element) /* {{{ */ +static void spl_object_storage_dtor(spl_SplObjectStorageElement *element) /* {{{ */ { - zval_ptr_dtor(element); + zval_ptr_dtor(&element->obj); + zval_ptr_dtor(&element->inf); } /* }}} */ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, spl_SplObjectStorage **obj, zval *orig TSRMLS_DC) /* {{{ */ @@ -124,9 +129,10 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); + spl_SplObjectStorageElement *element; HashTable *rv, *props; HashPosition pos; - zval *tmp, *storage, **entry; + zval *tmp, *storage; char md5str[33]; int name_len; char *zname; @@ -143,10 +149,15 @@ array_init(storage); zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); - while (zend_hash_get_current_data_ex(&intern->storage, (void **)&entry, &pos) == SUCCESS) { - php_spl_object_hash(*entry, md5str TSRMLS_CC); - zval_add_ref(entry); - add_assoc_zval_ex(storage, md5str, 33, *entry); + while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { + php_spl_object_hash(element->obj, md5str TSRMLS_CC); + Z_ADDREF_P(element->obj); + Z_ADDREF_P(element->inf); + MAKE_STD_ZVAL(tmp); + array_init(tmp); + 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); } @@ -181,21 +192,53 @@ #endif } /* }}} */ -void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */ +spl_SplObjectStorageElement* spl_object_storage_get(spl_SplObjectStorage *intern, zval *obj TSRMLS_DC) /* {{{ */ { - if (spl_object_storage_contains(intern, obj TSRMLS_CC)) { - return; /* already contained */ + 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; + } +} /* }}} */ + + +void spl_object_storage_attach(spl_SplObjectStorage *intern, zval *obj, zval *inf TSRMLS_DC) /* {{{ */ +{ + 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), &obj, sizeof(zval*), NULL); + 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), &obj, sizeof(zval*), NULL); + zend_hash_update(&intern->storage, (char*)&zvalue, sizeof(zend_object_value), &element, sizeof(spl_SplObjectStorageElement), NULL); } #endif } /* }}} */ @@ -215,18 +258,18 @@ #endif } /* }}}*/ -/* {{{ proto void SplObjectStorage::attach($obj) +/* {{{ proto void SplObjectStorage::attach($obj, $inf = NULL) Attaches an object to the storage if not yet contained */ SPL_METHOD(SplObjectStorage, attach) { - zval *obj; + 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", &obj) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|z!", &obj, &inf) == FAILURE) { return; } - spl_object_storage_attach(intern, obj TSRMLS_CC); + spl_object_storage_attach(intern, obj, inf TSRMLS_CC); } /* }}} */ /* {{{ proto void SplObjectStorage::detach($obj) @@ -268,7 +311,7 @@ } /* }}} */ /* {{{ proto void SplObjectStorage::rewind() - */ + Rewind to first position */ SPL_METHOD(SplObjectStorage, rewind) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); @@ -278,7 +321,7 @@ } /* }}} */ /* {{{ proto bool SplObjectStorage::valid() - */ + Returns whether current position is valid */ SPL_METHOD(SplObjectStorage, valid) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); @@ -287,7 +330,7 @@ } /* }}} */ /* {{{ proto mixed SplObjectStorage::key() - */ + Returns current key */ SPL_METHOD(SplObjectStorage, key) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); @@ -296,20 +339,53 @@ } /* }}} */ /* {{{ proto mixed SplObjectStorage::current() - */ + Returns current element */ SPL_METHOD(SplObjectStorage, current) { - zval **entry; + spl_SplObjectStorageElement *element; + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) { + return; + } + RETVAL_ZVAL(element->obj, 1, 0); +} /* }}} */ + +/* {{{ proto mixed SplObjectStorage::getInfo() + Returns associated information to current element */ +SPL_METHOD(SplObjectStorage, getInfo) +{ + spl_SplObjectStorageElement *element; + spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + + if (zend_hash_get_current_data_ex(&intern->storage, (void**)&element, &intern->pos) == FAILURE) { + return; + } + RETVAL_ZVAL(element->inf, 1, 0); +} /* }}} */ + +/* {{{ proto mixed SplObjectStorage::setInfo(mixed $inf) + Sets associated information of current element to $inf */ +SPL_METHOD(SplObjectStorage, setInfo) +{ + spl_SplObjectStorageElement *element; spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); + zval *inf; - if (zend_hash_get_current_data_ex(&intern->storage, (void**)&entry, &intern->pos) == FAILURE) { + 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; } - RETVAL_ZVAL(*entry, 1, 0); + zval_ptr_dtor(&element->inf); + element->inf = inf; + Z_ADDREF_P(inf); } /* }}} */ /* {{{ proto void SplObjectStorage::next() - */ + Moves position forward */ SPL_METHOD(SplObjectStorage, next) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); @@ -319,12 +395,13 @@ } /* }}} */ /* {{{ proto string SplObjectStorage::serialize() - */ + Serializes storage */ SPL_METHOD(SplObjectStorage, serialize) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - zval **entry, members, *pmembers; + spl_SplObjectStorageElement *element; + zval members, *pmembers; HashPosition pos; php_serialize_data_t var_hash; smart_str buf = {0}; @@ -339,12 +416,14 @@ 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**)&entry, &pos) == FAILURE) { + 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, entry, &var_hash TSRMLS_CC); + 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); } @@ -369,7 +448,7 @@ } /* }}} */ /* {{{ proto void SplObjectStorage::unserialize(string serialized) - */ + Unserializes storage */ SPL_METHOD(SplObjectStorage, unserialize) { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); @@ -378,7 +457,7 @@ int buf_len; const unsigned char *p, *s; php_unserialize_data_t var_hash; - zval *pentry, *pmembers, *pcount = NULL; + zval *pentry, *pmembers, *pcount = NULL, *pinf; long count; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { @@ -419,8 +498,17 @@ zval_ptr_dtor(&pentry); goto outexcept; } - spl_object_storage_attach(intern, pentry TSRMLS_CC); + 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; + } + } + spl_object_storage_attach(intern, pentry, pinf TSRMLS_CC); zval_ptr_dtor(&pentry); + zval_ptr_dtor(&pinf); } if (*p != ';') { @@ -462,12 +550,23 @@ ZEND_END_ARG_INFO(); static +ZEND_BEGIN_ARG_INFO_EX(arginfo_attach, 0, 0, 1) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, inf) +ZEND_END_ARG_INFO(); + +static ZEND_BEGIN_ARG_INFO(arginfo_Serialized, 0) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO(); +static +ZEND_BEGIN_ARG_INFO(arginfo_setInfo, 0) + ZEND_ARG_INFO(0, info) +ZEND_END_ARG_INFO(); + static const zend_function_entry spl_funcs_SplObjectStorage[] = { - SPL_ME(SplObjectStorage, attach, arginfo_Object, 0) + SPL_ME(SplObjectStorage, attach, arginfo_attach, 0) SPL_ME(SplObjectStorage, detach, arginfo_Object, 0) SPL_ME(SplObjectStorage, contains, arginfo_Object, 0) SPL_ME(SplObjectStorage, count, NULL, 0) @@ -478,6 +577,8 @@ SPL_ME(SplObjectStorage, next, NULL, 0) 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) {NULL, NULL, NULL} }; http://cvs.php.net/viewvc.cgi/php-src/ext/spl/internal/splobjectstorage.inc?r1=1.2.2.2.4.1&r2=1.2.2.2.4.2&diff_format=u Index: php-src/ext/spl/internal/splobjectstorage.inc diff -u php-src/ext/spl/internal/splobjectstorage.inc:1.2.2.2.4.1 php-src/ext/spl/internal/splobjectstorage.inc:1.2.2.2.4.2 --- php-src/ext/spl/internal/splobjectstorage.inc:1.2.2.2.4.1 Sun Dec 16 22:19:49 2007 +++ php-src/ext/spl/internal/splobjectstorage.inc Sun Jan 27 18:07:20 2008 @@ -4,7 +4,7 @@ * @ingroup SPL * @brief class SplObjectStorage * @author Marcus Boerger - * @date 2003 - 2005 + * @date 2003 - 2008 * * SPL - Standard PHP Library */ @@ -12,7 +12,7 @@ /** * @brief Object storage * @author Marcus Boerger - * @version 1.0 + * @version 1.1 * @since PHP 5.1.2 * * This container allows to store objects uniquly without the need to compare @@ -50,7 +50,27 @@ */ function current() { - return current($this->storage); + $element = current($this->storage); + return $element ? $element[0] : NULL + } + + /** @return get current object's associated information + * @since 5.3.0 + */ + function getInfo() + { + $element = current($this->storage); + return $element ? $element[1] : NULL + } + + /** @return set current object's associated information + * @since 5.3.0 + */ + function setInfo($inf = NULL) + { + if ($this->valid()) { + $this->storage[$this->index][1] = $inf; + } } /** Forward to next element @@ -75,9 +95,9 @@ { if (is_object($obj)) { - foreach($this->storage as $object) + foreach($this->storage as $element) { - if ($object === $obj) + if ($object === $element[0]) { return true; } @@ -88,11 +108,11 @@ /** @param $obj new object to attach to storage if not yet contained */ - function attach($obj) + function attach($obj, $inf = NULL) { if (is_object($obj) && !$this->contains($obj)) { - $this->storage[] = $obj; + $this->storage[] = array($obj, $inf); } } @@ -102,9 +122,9 @@ { if (is_object($obj)) { - foreach($this->storage as $idx => $object) + foreach($this->storage as $idx => $element) { - if ($object === $obj) + if ($object === $element[0]) { unset($this->storage[$idx]); $this->rewind(); http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/observer_004.phpt?r1=1.3.2.2.2.1&r2=1.3.2.2.2.2&diff_format=u Index: php-src/ext/spl/tests/observer_004.phpt diff -u php-src/ext/spl/tests/observer_004.phpt:1.3.2.2.2.1 php-src/ext/spl/tests/observer_004.phpt:1.3.2.2.2.2 --- php-src/ext/spl/tests/observer_004.phpt:1.3.2.2.2.1 Fri Nov 2 19:41:10 2007 +++ php-src/ext/spl/tests/observer_004.phpt Sun Jan 27 18:07:20 2008 @@ -68,14 +68,24 @@ ["storage":"SplObjectStorage":private]=> array(2) { ["%s"]=> - object(TestClass)#%d (1) { - ["test"]=> - int(1) + array(2) { + ["obj"]=> + object(TestClass)#%d (1) { + ["test"]=> + int(1) + } + ["inf"]=> + NULL } ["%s"]=> - object(TestClass)#%d (1) { - ["test"]=> - int(2) + array(2) { + ["obj"]=> + object(TestClass)#%d (1) { + ["test"]=> + int(2) + } + ["inf"]=> + NULL } } } @@ -90,14 +100,24 @@ ["storage":"SplObjectStorage":private]=> array(2) { ["%s"]=> - object(TestClass)#%d (1) { - ["test"]=> - int(1) + array(2) { + ["obj"]=> + object(TestClass)#%d (1) { + ["test"]=> + int(1) + } + ["inf"]=> + NULL } ["%s"]=> - object(TestClass)#%d (1) { - ["test"]=> - int(2) + array(2) { + ["obj"]=> + object(TestClass)#%d (1) { + ["test"]=> + int(2) + } + ["inf"]=> + NULL } } } http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/observer_005.phpt?r1=1.2.2.2.2.1&r2=1.2.2.2.2.2&diff_format=u Index: php-src/ext/spl/tests/observer_005.phpt diff -u php-src/ext/spl/tests/observer_005.phpt:1.2.2.2.2.1 php-src/ext/spl/tests/observer_005.phpt:1.2.2.2.2.2 --- php-src/ext/spl/tests/observer_005.phpt:1.2.2.2.2.1 Fri Nov 2 19:41:10 2007 +++ php-src/ext/spl/tests/observer_005.phpt Sun Jan 27 18:07:20 2008 @@ -110,26 +110,36 @@ ["storage":"SplObjectStorage":private]=> array(2) { ["%s"]=> - object(TestClass)#%d (4) { - ["def"]=> - int(24) - ["pub"]=> - int(4) - ["pro":protected]=> - int(5) - ["pri":"TestClass":private]=> - int(6) + array(2) { + ["obj"]=> + object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(4) + ["pro":protected]=> + int(5) + ["pri":"TestClass":private]=> + int(6) + } + ["inf"]=> + NULL } ["%s"]=> - object(TestClass)#%d (4) { - ["def"]=> - int(24) - ["pub"]=> - int(7) - ["pro":protected]=> - int(8) - ["pri":"TestClass":private]=> - int(9) + array(2) { + ["obj"]=> + object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(7) + ["pro":protected]=> + int(8) + ["pri":"TestClass":private]=> + int(9) + } + ["inf"]=> + NULL } } } @@ -168,26 +178,36 @@ ["storage":"SplObjectStorage":private]=> array(2) { ["%s"]=> - object(TestClass)#%d (4) { - ["def"]=> - int(24) - ["pub"]=> - int(4) - ["pro":protected]=> - int(5) - ["pri":"TestClass":private]=> - int(6) + array(2) { + ["obj"]=> + object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(4) + ["pro":protected]=> + int(5) + ["pri":"TestClass":private]=> + int(6) + } + ["inf"]=> + NULL } ["%s"]=> - object(TestClass)#%d (4) { - ["def"]=> - int(24) - ["pub"]=> - int(7) - ["pro":protected]=> - int(8) - ["pri":"TestClass":private]=> - int(9) + array(2) { + ["obj"]=> + object(TestClass)#%d (4) { + ["def"]=> + int(24) + ["pub"]=> + int(7) + ["pro":protected]=> + int(8) + ["pri":"TestClass":private]=> + int(9) + } + ["inf"]=> + NULL } } } http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/observer_006.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/observer_006.phpt +++ php-src/ext/spl/tests/observer_006.phpt
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php