]> granicus.if.org Git - php/commitdiff
add setUncompressed(), setCompressedGZ(), setCompressedBZ2() to PharFileInfo, and...
authorGreg Beaver <cellog@php.net>
Mon, 22 Jan 2007 00:13:20 +0000 (00:13 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 22 Jan 2007 00:13:20 +0000 (00:13 +0000)
ext/phar/TODO
ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/tests/phar_oo_compressed_001.phpt [new file with mode: 0644]

index 432e754e8421db15421af811f03ffa1885c1ff78..a35e195a366a6e3d9a100cf5828897e67cd70445 100644 (file)
@@ -15,8 +15,8 @@ Version 1.0.0
  X stream context for specifying compression of a file [Marcus]
  * stream context for specifying meta-data
  X Phar->setStub() for specifying a new stub to the phar [Greg]
* add setUncompressed(), setCompressedGZ() and setCompressedBZ2() to 
-   PharFileInfo class
X add setUncompressed(), setCompressedGZ() and setCompressedBZ2() to 
+   PharFileInfo class [Greg]
  * add uncompressAllFiles(), compressAllFilesGZ() and compressAllFilesBZ2() 
    to Phar class
  X add PharFileInfo::setMetaData($metadata) [Marcus]
index 4e7d9e292af7b24a5fd12d95b77d6c80eb26c512..900f4e83642fabc807bb7c00ed853dba4b8779a1 100644 (file)
@@ -291,6 +291,7 @@ phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char
                etemp.offset_within_phar = -1;
                etemp.is_crc_checked = 1;
                etemp.flags = PHAR_ENT_PERM_DEF_FILE;
+               etemp.phar = phar;
                zend_hash_add(&phar->manifest, etemp.filename, path_len, (void*)&etemp, sizeof(phar_entry_info), NULL);
                /* retrieve the phar manifest copy */
                entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC);
@@ -722,6 +723,7 @@ int phar_open_file(php_stream *fp, char *fname, int fname_len, char *alias, int
                manifest_flags |= (entry.flags & PHAR_ENT_COMPRESSION_MASK);
                entry.is_crc_checked = 0;
                entry.fp = NULL;
+               entry.phar = mydata;
                zend_hash_add(&mydata->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), NULL);
        }
 
index 53f1343e35dbaa267ef37dccb64118cc2939b817..b1e9d2c53dad0b206670474ac19816cd81165f80 100755 (executable)
@@ -134,6 +134,7 @@ typedef union _phar_archive_object  phar_archive_object;
 typedef union _phar_entry_object    phar_entry_object;
 #endif
 
+typedef struct _phar_archive_data phar_archive_data;
 /* entry for one file in a phar file */
 typedef struct _phar_entry_info {
        /* first bytes are exactly as in file */
@@ -152,10 +153,11 @@ typedef struct _phar_entry_info {
        int                      is_crc_checked:1;
        int                      is_modified:1;
        int                      is_deleted:1;
+       phar_archive_data        *phar;
 } phar_entry_info;
 
 /* information about a phar file (the archive itself) */
-typedef struct _phar_archive_data {
+struct _phar_archive_data {
        char                     *fname;
        int                      fname_len;
        char                     *alias;
@@ -175,7 +177,7 @@ typedef struct _phar_archive_data {
        int                      is_explicit_alias:1;
        int                      is_modified:1;
        int                      is_writeable:1;
-} phar_archive_data;
+};
 
 /* stream access data for one file entry in a phar file */
 typedef struct _phar_entry_data {
index eae4a83fb4efe433c66a85687d5332b3b812448a..bfde05a3db544558bb64efe661fae7474a9ddf95 100755 (executable)
@@ -598,6 +598,181 @@ PHP_METHOD(PharFileInfo, setMetadata)
 }
 /* }}} */
 
+/* {{{ proto int PharFileInfo::setCompressedGZ()
+ * Instructs the Phar class to compress the current file using zlib
+ */
+PHP_METHOD(PharFileInfo, setCompressedGZ)
+{
+#if HAVE_ZLIB
+       php_stream *stream, *parent;
+       phar_entry_data *idata;
+       char *fname;
+       int fname_len;
+       PHAR_ENTRY_OBJECT();
+
+       if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) {
+               RETURN_TRUE;
+               return;
+       }
+       if (PHAR_G(readonly)) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Phar is readonly, cannot change compression");
+       }
+       if (entry_obj->ent.entry->is_deleted) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Cannot compress deleted file");
+       }
+       stream = php_stream_fopen_tmpfile();
+       if (!entry_obj->ent.entry->temp_file) {
+               fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename);
+               parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0);
+               efree(fname);
+               php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL);
+               entry_obj->ent.entry->temp_file = stream;
+               php_stream_close(parent);
+       }
+       if (entry_obj->ent.entry->fp) {
+               php_stream_close(entry_obj->ent.entry->fp);
+               entry_obj->ent.entry->fp = 0;
+       }
+       entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
+       entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_GZ;
+       entry_obj->ent.entry->phar->is_modified = 1;
+       entry_obj->ent.entry->is_modified = 1;
+
+       idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
+       idata->fp = 0;
+       idata->internal_file = 0;
+       idata->phar = entry_obj->ent.entry->phar;
+       phar_flush(idata, 0, 0 TSRMLS_CC);
+       efree(idata);
+       RETURN_TRUE;
+#else
+       zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+               "Cannot compress with Gzip compression, zlib extension is not enabled");
+#endif
+}
+/* }}} */
+
+/* {{{ proto int PharFileInfo::setCompressedBZIP2()
+ * Instructs the Phar class to compress the current file using bzip2
+ */
+PHP_METHOD(PharFileInfo, setCompressedBZIP2)
+{
+#if HAVE_BZ2
+       php_stream *stream, *parent;
+       phar_entry_data *idata;
+       char *fname;
+       int fname_len;
+       PHAR_ENTRY_OBJECT();
+
+       if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
+               RETURN_TRUE;
+               return;
+       }
+       if (PHAR_G(readonly)) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Phar is readonly, cannot change compression");
+       }
+       if (entry_obj->ent.entry->is_deleted) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Cannot compress deleted file");
+       }
+       stream = php_stream_fopen_tmpfile();
+       if (!entry_obj->ent.entry->temp_file) {
+               fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename);
+               parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0);
+               efree(fname);
+               php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL);
+               entry_obj->ent.entry->temp_file = stream;
+               php_stream_close(parent);
+       }
+       if (entry_obj->ent.entry->fp) {
+               php_stream_close(entry_obj->ent.entry->fp);
+               entry_obj->ent.entry->fp = 0;
+       }
+       entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
+       entry_obj->ent.entry->flags |= PHAR_ENT_COMPRESSED_BZ2;
+       entry_obj->ent.entry->phar->is_modified = 1;
+       entry_obj->ent.entry->is_modified = 1;
+
+       idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
+       idata->fp = 0;
+       idata->internal_file = 0;
+       idata->phar = entry_obj->ent.entry->phar;
+       phar_flush(idata, 0, 0 TSRMLS_CC);
+       efree(idata);
+       RETURN_TRUE;
+#else
+       zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+               "Cannot compress with Bzip2 compression, bzip2 extension is not enabled");
+#endif
+}
+/* }}} */
+
+/* {{{ proto int PharFileInfo::setUncompressed()
+ * Instructs the Phar class to uncompress the current file
+ */
+PHP_METHOD(PharFileInfo, setUncompressed)
+{
+       php_stream *stream, *parent;
+       phar_entry_data *idata;
+       char *fname;
+       int fname_len;
+       PHAR_ENTRY_OBJECT();
+
+       if ((entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSION_MASK) == 0) {
+               RETURN_TRUE;
+               return;
+       }
+       if (PHAR_G(readonly)) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Phar is readonly, cannot change compression");
+       }
+       if (entry_obj->ent.entry->is_deleted) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Cannot compress deleted file");
+       }
+#if !HAVE_ZLIB
+       if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_GZ) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Cannot uncompress Gzip-compressed file, zlib extension is not enabled");
+       }
+#endif
+#if !HAVE_BZ2
+       if (entry_obj->ent.entry->flags & PHAR_ENT_COMPRESSED_BZ2) {
+               zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC,
+                       "Cannot uncompress Bzip2-compressed file, bzip2 extension is not enabled");
+       }
+#endif
+       stream = php_stream_fopen_tmpfile();
+       if (!entry_obj->ent.entry->temp_file) {
+               fname_len = spprintf(&fname, 0, "phar://%s/%s", entry_obj->ent.entry->phar->fname, entry_obj->ent.entry->filename);
+               parent = php_stream_open_wrapper_ex(fname, "rb", 0, 0, 0);
+               efree(fname);
+               php_stream_copy_to_stream(parent, stream, PHP_STREAM_COPY_ALL);
+               entry_obj->ent.entry->compressed_filesize = entry_obj->ent.entry->uncompressed_filesize;
+               entry_obj->ent.entry->temp_file = stream;
+               php_stream_close(parent);
+       }
+       if (entry_obj->ent.entry->fp) {
+               php_stream_close(entry_obj->ent.entry->fp);
+               entry_obj->ent.entry->fp = 0;
+       }
+       entry_obj->ent.entry->flags &= ~PHAR_ENT_COMPRESSION_MASK;
+       entry_obj->ent.entry->phar->is_modified = 1;
+       entry_obj->ent.entry->is_modified = 1;
+
+       idata = (phar_entry_data *) emalloc(sizeof(phar_entry_data));
+       idata->fp = 0;
+       idata->internal_file = 0;
+       idata->phar = entry_obj->ent.entry->phar;
+       phar_flush(idata, 0, 0 TSRMLS_CC);
+       efree(idata);
+       RETURN_TRUE;
+}
+/* }}} */
+
 #endif /* HAVE_SPL */
 
 /* {{{ phar methods */
@@ -680,6 +855,9 @@ zend_function_entry php_entry_methods[] = {
        PHP_ME(PharFileInfo, isCompressed,       NULL,                       0)
        PHP_ME(PharFileInfo, isCompressedGZ,     NULL,                       0)
        PHP_ME(PharFileInfo, isCompressedBZIP2,  NULL,                       0)
+       PHP_ME(PharFileInfo, setUncompressed,    NULL,                       0)
+       PHP_ME(PharFileInfo, setCompressedGZ,    NULL,                       0)
+       PHP_ME(PharFileInfo, setCompressedBZIP2, NULL,                       0)
        PHP_ME(PharFileInfo, getCRC32,           NULL,                       0)
        PHP_ME(PharFileInfo, isCRCChecked,       NULL,                       0)
        PHP_ME(PharFileInfo, getPharFlags,       NULL,                       0)
diff --git a/ext/phar/tests/phar_oo_compressed_001.phpt b/ext/phar/tests/phar_oo_compressed_001.phpt
new file mode 100644 (file)
index 0000000..6809eb9
--- /dev/null
@@ -0,0 +1,69 @@
+--TEST--
+Phar context
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip"; ?>
+<?php if (!extension_loaded("zlib")) print "skip zlib not present"; ?>
+--INI--
+phar.require_hash=0
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://' . $fname;
+$file = '<?php __HALT_COMPILER(); ?>';
+
+$files = array();
+$files['a'] = 'a';
+$files['b'] = 'b';
+$files['c'] = 'c';
+
+include 'phar_test.inc';
+
+$phar = new Phar($fname);
+
+var_dump(file_get_contents($pname . '/a'));
+var_dump($phar['a']->isCompressed());
+var_dump(file_get_contents($pname . '/b'));
+var_dump($phar['b']->isCompressed());
+var_dump(file_get_contents($pname . '/c'));
+var_dump($phar['c']->isCompressed());
+
+$context = stream_context_create(array('phar'=>array('compress'=>Phar::GZ)));
+
+$phar['a'] = 'new a';
+$phar['a']->setUncompressed();
+$phar['b'] = 'new b';
+$phar['b']->setCompressedGZ();
+$phar['d'] = 'new d';
+
+$phar = new Phar($fname);
+var_dump(file_get_contents($pname . '/a'));
+var_dump($phar['a']->isCompressed());
+var_dump(file_get_contents($pname . '/b'));
+var_dump($phar['b']->isCompressed());
+var_dump(file_get_contents($pname . '/c'));
+var_dump($phar['c']->isCompressed());
+var_dump(file_get_contents($pname . '/d'));
+var_dump($phar['d']->isCompressed());
+
+?>
+===DONE===
+--CLEAN--
+<?php 
+unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php');
+?>
+--EXPECTF--
+string(1) "a"
+bool(false)
+string(1) "b"
+bool(false)
+string(1) "c"
+bool(false)
+string(4) "new a"
+bool(false)
+string(4) "new b"
+bool(true)
+string(1) "c"
+bool(false)
+string(4) "new d"
+bool(true)
+===DONE===