helly           Wed Mar 17 14:58:33 2004 EDT

  Added files:                 
    /php-src/ext/spl/tests      caching_iterator_str.phpt 

  Modified files:              
    /php-src/ext/spl    spl_iterators.c 
  Log:
  Fix CachingIterator's ability to cache string conversion results.
  Add a test for that.
  
  
http://cvs.php.net/diff.php/php-src/ext/spl/spl_iterators.c?r1=1.27&r2=1.28&ty=u
Index: php-src/ext/spl/spl_iterators.c
diff -u php-src/ext/spl/spl_iterators.c:1.27 php-src/ext/spl/spl_iterators.c:1.28
--- php-src/ext/spl/spl_iterators.c:1.27        Tue Mar 16 05:17:59 2004
+++ php-src/ext/spl/spl_iterators.c     Wed Mar 17 14:58:32 2004
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: spl_iterators.c,v 1.27 2004/03/16 10:17:59 helly Exp $ */
+/* $Id: spl_iterators.c,v 1.28 2004/03/17 19:58:32 helly Exp $ */
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -1054,6 +1054,10 @@
                        zval_ptr_dtor(&retval);         
                }
                if (intern->u.caching.flags & CIT_CALL_TOSTRING) {
+#if MBO_0
+                       /* This version requires zend_make_printable_zval() being able 
to
+                        * call __toString().
+                        */
                        int  use_copy;
                        zval expr_copy;
                        ALLOC_ZVAL(intern->u.caching.zstr);
@@ -1067,6 +1071,29 @@
                        } else {
                                zval_copy_ctor(intern->u.caching.zstr);
                        }
+#else
+                       zval expr_copy;
+                       if (intern->current.data->value.obj.handlers->cast_object &&
+                               
intern->current.data->value.obj.handlers->cast_object(intern->current.data, 
&expr_copy, IS_STRING, 0 TSRMLS_CC) == SUCCESS)
+                       {
+                               ALLOC_ZVAL(intern->u.caching.zstr);
+                               *intern->u.caching.zstr = expr_copy;
+                               INIT_PZVAL(intern->u.caching.zstr);
+                               zval_copy_ctor(intern->u.caching.zstr);
+                               zval_dtor(&expr_copy);
+                       } else {
+                               zend_class_entry *ce_data = 
spl_get_class_entry(intern->current.data TSRMLS_CC);
+                               if (ce_data && 
zend_hash_exists(&ce_data->function_table, "__tostring", sizeof("__tostring"))) {
+                                       
zend_call_method_with_0_params(&intern->current.data, ce_data, NULL, "__tostring", 
&intern->u.caching.zstr);
+                               } else {
+                                       ALLOC_ZVAL(intern->u.caching.zstr);
+                                       *intern->u.caching.zstr = 
*intern->current.data;
+                                       zval_copy_ctor(intern->u.caching.zstr);
+                                       INIT_PZVAL(intern->u.caching.zstr);
+                                       convert_to_string(intern->u.caching.zstr);
+                               }
+                       }
+#endif
                }
                spl_dual_it_next(intern, 0 TSRMLS_CC);  
        } else {

http://cvs.php.net/co.php/php-src/ext/spl/tests/caching_iterator_str.phpt?r=1.1&p=1
Index: php-src/ext/spl/tests/caching_iterator_str.phpt
+++ php-src/ext/spl/tests/caching_iterator_str.phpt
--TEST--
SPL: CachingIterator and __toString()
--SKIPIF--
<?php if (!extension_loaded("spl")) print "skip"; ?>
--FILE--
<?php

class Student
{
        private $id;
        private $name;

    public function __construct($id, $name)
    {
        $this->id = $id;
        $this->name = $name;
    }

        public function __toString()
        {
                return $this->id . ', ' . $this->name;
        }
        
        public function getId()
        {
                return $this->id;
        }
}

class StudentIdFilter extends FilterIterator
{
        private $id;

        public function __construct(ArrayObject $students, Student $other)
        {
                FilterIterator::__construct($students->getIterator());
                $this->id = $other->getId();
        }
        
        public function accept()
        {
                echo "ACCEPT ".$this->current()->getId()." == ".$this->id."\n";
                return $this->current()->getId() == $this->id;
        }
}

class StudentList implements IteratorAggregate
{
        private $students;
        
        public function __construct()
        {
                $this->students = new ArrayObject(array());
        }
        
        public function add(Student $student)
        {
                if (!$this->contains($student)) {
                        $this->students[] = $student;
                }
        }
        
        public function contains(Student $student)
        {
                foreach ($this->students as $s)
                {
                        if ($s->getId() == $student->getId()) {
                                return true;
                        }
                }
                return false;
        }
        
        public function getIterator() {
                return new CachingIterator($this->students->getIterator(), true);
        }
}

$students = new StudentList();
$students->add(new Student('01234123', 'Joe'));
$students->add(new Student('00000014', 'Bob'));
$students->add(new Student('00000014', 'Foo'));

// The goal is to verify we can access the cached string value even if it was
// generated by a call to __toString(). To check this we need to access the
// iterator's __toString() method.
$it = $students->getIterator();
foreach ($it as $student) {
        echo $it->__toString(), "\n";
}
?>
===DONE===
<?php exit(0); ?>
--EXPECT--
01234123, Joe
00000014, Bob
===DONE===

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to