helly Mon Dec 18 22:32:10 2006 UTC Added files: /php-src/ext/spl/tests observer_004.phpt
Modified files: /php-src/ext/spl spl_observer.c /php-src/ext/spl/tests observer_003.phpt Log: - Support members in SplObjectStorage serialization / shorter serialization
http://cvs.php.net/viewvc.cgi/php-src/ext/spl/spl_observer.c?r1=1.12&r2=1.13&diff_format=u Index: php-src/ext/spl/spl_observer.c diff -u php-src/ext/spl/spl_observer.c:1.12 php-src/ext/spl/spl_observer.c:1.13 --- php-src/ext/spl/spl_observer.c:1.12 Sun Dec 17 23:23:33 2006 +++ php-src/ext/spl/spl_observer.c Mon Dec 18 22:32:09 2006 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.c,v 1.12 2006/12/17 23:23:33 helly Exp $ */ +/* $Id: spl_observer.c,v 1.13 2006/12/18 22:32:09 helly Exp $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -272,46 +272,51 @@ { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(getThis() TSRMLS_CC); - zval **entry; + zval **entry, members, *pmembers; HashPosition pos; php_serialize_data_t var_hash; smart_str buf = {0}; - long index = 0; PHP_VAR_SERIALIZE_INIT(var_hash); - smart_str_appendl(&buf, "a:", 2); + /* storage */ + smart_str_appendl(&buf, "x:i:", 4); smart_str_append_long(&buf, zend_hash_num_elements(&intern->storage)); - smart_str_appendl(&buf, ":{", 2); + smart_str_appendc(&buf, ';'); zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); while(zend_hash_has_more_elements_ex(&intern->storage, &pos) == SUCCESS) { - smart_str_appendl(&buf, "i:", 2); - smart_str_append_long(&buf, index++); - smart_str_appendc(&buf, ';'); if (zend_hash_get_current_data_ex(&intern->storage, (void**)&entry, &pos) == FAILURE) { smart_str_free(&buf); PHP_VAR_SERIALIZE_DESTROY(var_hash); - RETURN_FALSE; + RETURN_NULL(); } php_var_serialize(&buf, entry, &var_hash TSRMLS_CC); + smart_str_appendc(&buf, ';'); zend_hash_move_forward_ex(&intern->storage, &pos); } - smart_str_appendc(&buf, '}'); - smart_str_0(&buf); + /* 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_ASCII_STRINGL(buf.c, buf.len, 0); + RETURN_ASCII_STRINGL(buf.c, buf.len, ZSTR_AUTOFREE); } else { RETURN_NULL(); } } /* }}} */ -/* {{{ proto void SplObjectStorage::unserialize(string unserialized) +/* {{{ proto void SplObjectStorage::unserialize(string serialized) */ SPL_METHOD(SplObjectStorage, unserialize) { @@ -319,12 +324,10 @@ char *buf; int buf_len; - const unsigned char *p; + const unsigned char *p, *s; php_unserialize_data_t var_hash; - zval *zentries, **entry; - HashPosition pos; - - ALLOC_INIT_ZVAL(zentries); + zval *pentry, *pmembers, *pcount = NULL; + long count; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { return; @@ -335,36 +338,70 @@ return; } - p = (const unsigned char*)buf; + /* storage */ + s = p = (const unsigned char*)buf; PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (!php_var_unserialize(&zentries, &p, p + buf_len, &var_hash TSRMLS_CC)) { - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); - zval_ptr_dtor(&zentries); - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); - return; + + if (*p!= 'x' || *++p != ':') { + goto outexcept; } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + ++p; - /* move from temp array to storage */ - - if (Z_TYPE_P(zentries) != IS_ARRAY) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Serialize string must contain a single array"); - return; + ALLOC_INIT_ZVAL(pcount); + if (!php_var_unserialize(&pcount, &p, s + buf_len, &var_hash 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) { + if (*p != ';') { + goto outexcept; + } + ++p; + ALLOC_INIT_ZVAL(pentry); + if (!php_var_unserialize(&pentry, &p, s + buf_len, &var_hash TSRMLS_CC)) { + zval_ptr_dtor(&pentry); + goto outexcept; + } + spl_object_storage_attach(intern, pentry TSRMLS_CC); + zval_ptr_dtor(&pentry); } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(zentries), &pos); + if (*p != ';') { + goto outexcept; + } + ++p; - while(zend_hash_has_more_elements_ex(Z_ARRVAL_P(zentries), &pos) == SUCCESS) { - if (zend_hash_get_current_data_ex(Z_ARRVAL_P(zentries), (void**)&entry, &pos) == FAILURE || Z_TYPE_PP(entry) != IS_OBJECT) { - zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Serialize string must only contain objects"); - zval_ptr_dtor(&zentries); - return; - } - spl_object_storage_attach(intern, *entry TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_P(zentries), &pos); + /* members */ + if (*p!= 'm' || *++p != ':') { + goto outexcept; } - - zval_ptr_dtor(&zentries); + ++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; + } /* }}} */ static http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/observer_003.phpt?r1=1.2&r2=1.3&diff_format=u Index: php-src/ext/spl/tests/observer_003.phpt diff -u php-src/ext/spl/tests/observer_003.phpt:1.2 php-src/ext/spl/tests/observer_003.phpt:1.3 --- php-src/ext/spl/tests/observer_003.phpt:1.2 Sun Dec 17 23:23:33 2006 +++ php-src/ext/spl/tests/observer_003.phpt Mon Dec 18 22:32:10 2006 @@ -29,6 +29,7 @@ var_dump($object->test); } +var_dump(serialize($storage)); echo "===UNSERIALIZE===\n"; $storage2 = unserialize(serialize($storage)); @@ -43,12 +44,13 @@ ?> ===DONE=== <?php exit(0); ?> ---EXPECT-- +--EXPECTF-- int(4) int(1) string(1) "2" string(3) "foo" bool(true) +string(%d) "%s" ===UNSERIALIZE=== int(4) int(1) @@ -56,12 +58,13 @@ string(3) "foo" bool(true) ===DONE=== ---UEXPECT-- +--UEXPECTF-- int(4) int(1) unicode(1) "2" unicode(3) "foo" bool(true) +unicode(%d) "%s" ===UNSERIALIZE=== int(4) int(1) http://cvs.php.net/viewvc.cgi/php-src/ext/spl/tests/observer_004.phpt?view=markup&rev=1.1 Index: php-src/ext/spl/tests/observer_004.phpt +++ php-src/ext/spl/tests/observer_004.phpt --TEST-- SPL: SplObjectStorage overloaded & serialization --SKIPIF-- <?php if (!extension_loaded("spl")) print "skip"; ?> --FILE-- <?php class TestClass { public $test = 25; public function __construct($test = 42) { $this->test = $test; } } class MyStorage extends SplObjectStorage { public $bla = 25; public function __construct($bla = 26) { $this->bla = $bla; } } $storage = new MyStorage(); foreach(array(1,2) as $value) { $storage->attach(new TestClass($value)); } var_dump(count($storage)); foreach($storage as $object) { var_dump($object->test); } var_dump($storage); var_dump(serialize($storage)); echo "===UNSERIALIZE===\n"; $storage2 = unserialize(serialize($storage)); var_dump(count($storage2)); foreach($storage2 as $object) { var_dump($object->test); } var_dump($storage2); ?> ===DONE=== <?php exit(0); ?> --EXPECTF-- int(2) int(1) int(2) object(MyStorage)#%d (1) { ["bla"]=> int(26) } string(%d) "%s" ===UNSERIALIZE=== int(2) int(1) int(2) object(MyStorage)#%d (1) { ["bla"]=> int(26) } ===DONE=== --UEXPECTF-- int(2) int(1) int(2) object(MyStorage)#%d (1) { [u"bla"]=> int(26) } unicode(%d) "%s" ===UNSERIALIZE=== int(2) int(1) int(2) object(MyStorage)#%d (1) { [u"bla"]=> int(26) } ===DONE===
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php