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===