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

Reply via email to