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