cellog          Thu Dec 13 05:22:05 2007 UTC

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

  Modified files:              
    /pecl/phar  phar_object.c 
  Log:
  new test
  now, SplDirectoryIterator can be used directly with Phar->buildFromIterator() 
in order to populate the
  files in a phar archive.  When combined with a RegexIterator and other 
filters, it becomes very easy to create
  a phar archive with 1 line of code
  [DOC]
  
http://cvs.php.net/viewvc.cgi/pecl/phar/phar_object.c?r1=1.74&r2=1.75&diff_format=u
Index: pecl/phar/phar_object.c
diff -u pecl/phar/phar_object.c:1.74 pecl/phar/phar_object.c:1.75
--- pecl/phar/phar_object.c:1.74        Thu Dec 13 01:16:55 2007
+++ pecl/phar/phar_object.c     Thu Dec 13 05:22:05 2007
@@ -17,7 +17,7 @@
   +----------------------------------------------------------------------+
 */
 
-/* $Id: phar_object.c,v 1.74 2007/12/13 01:16:55 cellog Exp $ */
+/* $Id: phar_object.c,v 1.75 2007/12/13 05:22:05 cellog Exp $ */
 
 #include "phar_internal.h"
 
@@ -310,6 +310,7 @@
 {
        zval **value;
        zend_uchar key_type;
+       zend_bool is_splfileinfo = 0;
        ulong int_key;
        struct _t {
                phar_archive_object *p;
@@ -318,11 +319,11 @@
                uint l;
                zval *ret;
        } *p_obj = (struct _t*) puser;
-       uint str_key_len, base_len = p_obj->l;
+       uint str_key_len, base_len = p_obj->l, fname_len;
        phar_entry_data *data;
        php_stream *fp;
        long contents_len;
-       char *fname, *error, *str_key, *base = p_obj->b, *opened, *save;
+       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;
 
@@ -334,27 +335,70 @@
                /* failure in get_current_data */
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Iterator %s returned no value", ce->name);
        }
-       if (Z_TYPE_PP(value) != IS_STRING) {
-               zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Iterator %s returned an invalid value (must return a string)", 
ce->name);
-               return ZEND_HASH_APPLY_STOP;
+       switch (Z_TYPE_PP(value)) {
+               case IS_STRING :
+                       break;
+               case IS_OBJECT :
+                       if (instanceof_function(Z_OBJCE_PP(value), 
spl_ce_SplFileInfo)) {
+                               char *test;
+                               zval dummy;
+                               spl_filesystem_object *intern = 
(spl_filesystem_object*)zend_object_store_get_object(*value TSRMLS_CC);
+
+                               if (!base_len) {
+                                       
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Iterator 
%s returns an SplFileInfo object, so base directory must be specified", 
ce->name);
+                                       return ZEND_HASH_APPLY_STOP;
+                               }
+                               switch (intern->type) {
+                                       case SPL_FS_DIR:
+                                               fname_len = spprintf(&fname, 0, 
"%s%c%s", intern->path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
+                                               php_stat(fname, fname_len, 
FS_IS_DIR, &dummy TSRMLS_CC);
+                                               if (Z_BVAL(dummy)) {
+                                                       /* ignore directories */
+                                                       efree(fname);
+                                                       return 
ZEND_HASH_APPLY_KEEP;
+                                               }
+                                               test = expand_filepath(fname, 
test TSRMLS_CC);
+                                               if (test) {
+                                                       efree(fname);
+                                                       fname = test;
+                                                       fname_len = 
strlen(fname);
+                                               }
+                                               save = fname;
+                                               is_splfileinfo = 1;
+                                               goto phar_spl_fileinfo;
+                                       case SPL_FS_INFO:
+                                       case SPL_FS_FILE:
+                                               return ZEND_HASH_APPLY_KEEP;
+                               }
+                       }
+                       /* fall-through */
+               default :
+                       
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned an invalid value (must return a string)", ce->name);
+                       return ZEND_HASH_APPLY_STOP;
        }
 
        fname = Z_STRVAL_PP(value);
+       fname_len = Z_STRLEN_PP(value);
 
+phar_spl_fileinfo:
        if (base_len) {
                if (strstr(fname, base)) {
-                       str_key_len = Z_STRLEN_PP(value) - base_len;
+                       str_key_len = fname_len - base_len;
                        if (str_key_len <= 0) {
-                               efree(save);
+                               if (save) {
+                                       efree(save);
+                               }
                                return ZEND_HASH_APPLY_KEEP;
                        }
                        str_key = fname + base_len;
                } else {
                        
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator 
%s returned a path \"%s\" that is not in the base directory \"%s\"", ce->name, 
fname, base);
-                       efree(save);
+                       if (save) {
+                               efree(save);
+                       }
                        return ZEND_HASH_APPLY_STOP;
                }
-       } else  {
+       } else {
                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)) {
@@ -374,14 +418,18 @@
 #if PHP_MAJOR_VERSION < 6
        if (PG(safe_mode) && (!php_checkuid(fname, NULL, 
CHECKUID_ALLOW_ONLY_FILE))) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Iterator %s returned a path \"%s\" that safe mode prevents 
opening", ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 #endif
 
        if (php_check_open_basedir(fname TSRMLS_CC)) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Iterator %s returned a path \"%s\" that open_basedir prevents 
opening", ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 
@@ -389,14 +437,18 @@
        fp = php_stream_open_wrapper(fname, "rb", STREAM_MUST_SEEK|0, &opened);
        if (!fp) {
                zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 
TSRMLS_CC, "Iterator %s returned a file that could not be opened \"%s\"", 
ce->name, fname);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                return ZEND_HASH_APPLY_STOP;
        }
 
        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);
-               efree(save);
+               if (save) {
+                       efree(save);
+               }
                php_stream_close(fp);
                return ZEND_HASH_APPLY_STOP;
        } else {
@@ -408,7 +460,9 @@
        php_stream_close(fp);
 
        add_assoc_string(p_obj->ret, str_key, opened, 0);
-       efree(save);
+       if (save) {
+               efree(save);
+       }
 
        data->internal_file->compressed_filesize = 
data->internal_file->uncompressed_filesize = contents_len;
        phar_entry_delref(data TSRMLS_CC);

http://cvs.php.net/viewvc.cgi/pecl/phar/tests/phar_buildfromiterator8.phpt?view=markup&rev=1.1
Index: pecl/phar/tests/phar_buildfromiterator8.phpt
+++ pecl/phar/tests/phar_buildfromiterator8.phpt
--TEST--
Phar::buildFromIterator() iterator, SplFileInfo as current
--SKIPIF--
<?php if (!extension_loaded("phar")) print "skip"; ?>
--INI--
phar.require_hash=0
phar.readonly=0
--FILE--
<?php
try {
        chdir(dirname(__FILE__));
        $phar = new Phar(dirname(__FILE__) . '/buildfromiterator.phar');
        var_dump($phar->buildFromIterator(new RegexIterator(new 
DirectoryIterator('.'), '/^\d{0,3}\.phpt\\z|^\.\\z|^\.\.\\z/'), 
dirname(__FILE__) . DIRECTORY_SEPARATOR));
} catch (Exception $e) {
        var_dump(get_class($e));
        echo $e->getMessage() . "\n";
}
?>
===DONE===
--CLEAN--
<?php 
unlink(dirname(__FILE__) . '/buildfromiterator.phar');
__HALT_COMPILER();
?>
--EXPECT--
array(33) {
  ["001.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/001.phpt"
  ["002.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/002.phpt"
  ["003.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/003.phpt"
  ["004.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/004.phpt"
  ["005.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/005.phpt"
  ["006.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/006.phpt"
  ["007.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/007.phpt"
  ["008.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/008.phpt"
  ["009.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/009.phpt"
  ["010.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/010.phpt"
  ["011.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/011.phpt"
  ["012.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/012.phpt"
  ["013.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/013.phpt"
  ["014.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/014.phpt"
  ["015.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/015.phpt"
  ["016.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/016.phpt"
  ["017.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/017.phpt"
  ["018.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/018.phpt"
  ["019.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/019.phpt"
  ["020.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/020.phpt"
  ["021.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/021.phpt"
  ["022.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/022.phpt"
  ["023.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/023.phpt"
  ["024.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/024.phpt"
  ["025.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/025.phpt"
  ["026.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/026.phpt"
  ["027.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/027.phpt"
  ["028.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/028.phpt"
  ["029.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/029.phpt"
  ["030.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/030.phpt"
  ["031.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/031.phpt"
  ["032.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/032.phpt"
  ["033.phpt"]=>
  string(51) "/home/cellog/workspace/php5/ext/phar/tests/033.phpt"
}
===DONE===

Reply via email to