cellog          Fri Dec 14 19:45:21 2007 UTC

  Added files:                 
    /pecl/phar/tests    phar_buildfromiterator9.phpt 

  Modified files:              
    /pecl/phar  phar_object.c 
  Log:
  Phar->buildFromIterator now can also accept a stream handle as a value in 
addition
  to a file path (string) or SplFileInfo object
  [DOC]
  
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.77&r2=1.78&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.77 pecl/phar/phar_object.c:1.78
--- pecl/phar/phar_object.c:1.77        Fri Dec 14 04:10:13 2007
+++ pecl/phar/phar_object.c     Fri Dec 14 19:45:21 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_object.c,v 1.77 2007/12/14 04:10:13 cellog Exp $ */
+/* $Id: phar_object.c,v 1.78 2007/12/14 19:45:21 cellog Exp $ */
 
 #include "phar_internal.h"
 
@@ -310,7 +310,7 @@
 {
        zval **value;
        zend_uchar key_type;
-       zend_bool is_splfileinfo = 0;
+       zend_bool is_splfileinfo = 0, close_fp = 1;
        ulong int_key;
        struct _t {
                phar_archive_object *p;
@@ -326,6 +326,7 @@
        char *fname, *error, *str_key, *base = p_obj->b, *opened, *save = NULL;
        zend_class_entry *ce = p_obj->c;
        phar_archive_object *phar_obj = p_obj->p;
+       char *str = "[stream]";
 
        iter->funcs->get_current_data(iter, &value TSRMLS_CC);
        if (EG(exception)) {
@@ -338,6 +339,30 @@
        switch (Z_TYPE_PP(value)) {
                case IS_STRING :
                        break;
+               case IS_RESOURCE :
+                       php_stream_from_zval_no_verify(fp, value);
+                       if (!fp) {
+                               
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid stream handle", ce->name);
+                               return ZEND_HASH_APPLY_STOP;
+                       }
+                       if (iter->funcs->get_current_key) {
+                               key_type = iter->funcs->get_current_key(iter, 
&str_key, &str_key_len, &int_key TSRMLS_CC);
+                               if (EG(exception)) {
+                                       return ZEND_HASH_APPLY_STOP;
+                               }
+                               if (key_type == HASH_KEY_IS_LONG) {
+                                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid key (must return a string)", ce->name);
+                                       return ZEND_HASH_APPLY_STOP;
+                               }
+                               save = str_key;
+                               if (str_key[str_key_len - 1] == '\0') 
str_key_len--;
+                       } else {
+                               
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid key (must return a string)", ce->name);
+                               return ZEND_HASH_APPLY_STOP;
+                       }
+                       close_fp = 0;
+                       opened = (char *) estrndup(str, sizeof("[stream]") + 1);
+                       goto after_open_fp;
                case IS_OBJECT :
                        if (instanceof_function(Z_OBJCE_PP(value), 
spl_ce_SplFileInfo TSRMLS_CC)) {
                                char *test = NULL;
@@ -443,13 +468,16 @@
                return ZEND_HASH_APPLY_STOP;
        }
 
+after_open_fp:
        if (!(data = 
phar_get_or_create_entry_data(phar_obj->arc.archive->fname, 
phar_obj->arc.archive->fname_len, str_key, str_key_len, "w+b", &error 
TSRMLS_CC))) {
                zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 
TSRMLS_CC, "Entry %s cannot be created: %s", str_key, error);
                efree(error);
                if (save) {
                        efree(save);
                }
-               php_stream_close(fp);
+               if (close_fp) {
+                       php_stream_close(fp);
+               }
                return ZEND_HASH_APPLY_STOP;
        } else {
                if (error) {
@@ -457,7 +485,9 @@
                }
                contents_len = php_stream_copy_to_stream(fp, data->fp, 
PHP_STREAM_COPY_ALL);
        }
-       php_stream_close(fp);
+       if (close_fp) {
+               php_stream_close(fp);
+       }
 
        add_assoc_string(p_obj->ret, str_key, opened, 0);
        if (save) {

http://cvs.php.net/viewvc.cgi/pecl/phar/tests/phar_buildfromiterator9.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/phar_buildfromiterator9.phpt
+++ pecl/phar/tests/phar_buildfromiterator9.phpt
--TEST--
Phar::buildFromIterator() iterator, 1 file resource passed in
--SKIPIF--
<?php if (!extension_loaded("phar")) print "skip"; ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
class myIterator implements Iterator
{
    var $a;
    function __construct(array $a)
    {
        $this->a = $a;
    }
    function next() {
        echo "next\n";
        return next($this->a);
    }
    function current() {
        echo "current\n";
        return current($this->a);
    }
    function key() {
        echo "key\n";
        return key($this->a);
    }
    function valid() {
        echo "valid\n";
        return current($this->a);
    }
    function rewind() {
        echo "rewind\n";
        return reset($this->a);
    }
}
try {
        chdir(dirname(__FILE__));
        $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar');
        var_dump($phar->buildFromIterator(new myIterator(array('a' => $a = 
fopen(basename(__FILE__, 'php') . 'phpt', 'r')))));
        fclose($a);
} catch (Exception $e) {
        var_dump(get_class($e));
        echo $e->getMessage() . "\n";
}
?>
===DONE===
--CLEAN--
<?php 
unlink(dirname(__FILE__) . '/buildfromiterator.phar');
__HALT_COMPILER();
?>
--EXPECTF--
rewind
valid
current
key
next
valid
array(1) {
  ["a"]=>
  string(%d) "[stream]"
}
===DONE===

Reply via email to