Skip to content

Commit

Permalink
Add support for single-file bz2 and xz archives
Browse files Browse the repository at this point in the history
  • Loading branch information
wapmorgan committed Jan 7, 2017
1 parent 7499677 commit 148b630
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 6 deletions.
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
UnifiedArchive - unified interface to archive (zip # rar # gz # tar # tar.gz #
tar.bz2 # tar.x # tar.Z # iso-9660) for listing, reading, extracting and
creation + built-in console packer and unpacker + fully implemented PclZip-like
interface (create, listContent, extract, properties, add, delete, merge,
UnifiedArchive - unified interface to archive (zip # rar # gz # bz2 # xz # tar #
tar.gz # tar.bz2 # tar.x # tar.Z # iso-9660) for listing, reading, extracting
and creation + built-in console packer and unpacker + fully implemented
PclZip-like interface (create, listContent, extract, properties, add, delete, merge,
duplicate).

[![Composer package](http://xn--e1adiijbgl.xn--p1acf/badge/wapmorgan/unified-archive)](https://packagist.org/packages/wapmorgan/unified-archive) [![Latest Stable Version](https://poser.pugx.org/wapmorgan/unified-archive/v/stable)](https://packagist.org/packages/wapmorgan/unified-archive) [![Total Downloads](https://poser.pugx.org/wapmorgan/unified-archive/downloads)](https://packagist.org/packages/wapmorgan/unified-archive) [![License](https://poser.pugx.org/wapmorgan/unified-archive/license)](https://packagist.org/packages/wapmorgan/unified-archive)
Expand Down Expand Up @@ -53,12 +53,20 @@ returned. in case of failure - null
// or
$archive = UnifiedArchive::open('filename.gz');
// or
$archive = UnifiedArchive::open('filename.bz2');
// or
$archive = UnifiedArchive::open('filename.xz');
// or
$archive = UnifiedArchive::open('filename.tar');
// or
$archive = UnifiedArchive::open('filename.tar.gz');
// or
$archive = UnifiedArchive::open('filename.tar.bz2');
// or
$archive = UnifiedArchive::open('filename.tar.xz');
// or
$archive = UnifiedArchive::open('filename.tar.Z');
// or
$archive = UnifiedArchive::open('filename.iso');
```

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "wapmorgan/unified-archive",
"description": "UnifiedArchive - unified interface to archive (zip, rar, gz, tar, tar.gz, tar.bz2, tar.x, tar.Z, iso-9660) for listing, reading, extracting and creation + built-in console packer and unpacker + fully implemented PclZip-like interface (create, listContent, extract, properties, add, delete, merge, duplicate).",
"description": "UnifiedArchive - unified interface to archive (zip, rar, gz, bz2, xz, tar, tar.gz, tar.bz2, tar.x, tar.Z, iso-9660) for listing, reading, extracting and creation + built-in console packer and unpacker + fully implemented PclZip-like interface (create, listContent, extract, properties, add, delete, merge, duplicate).",
"keywords": ["archive", "rar", "zip", "gzip", "tar", "iso-9660", "lzma2", "ncompress"],
"license": "MIT",
"authors": [
Expand Down
136 changes: 135 additions & 1 deletion src/UnifiedArchive.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class UnifiedArchive implements AbstractArchive
const RAR = 'rar';
const TAR = 'tar';
const GZIP = 'gzip';
const BZIP = 'bzip2';
const LZMA = 'lzma2';
const ISO = 'iso';

protected $type;
Expand All @@ -25,6 +27,10 @@ class UnifiedArchive implements AbstractArchive
protected $tarCompressionRatio;
protected $gzipStat;
protected $gzipFilename;
protected $bzipStat;
protected $bzipFilename;
protected $lzmaStat;
protected $lzmaFilename;
protected $iso;
protected $isoBlockSize;
protected $isoFilesData;
Expand All @@ -45,10 +51,14 @@ public static function open($filename)
return new self($filename, self::ZIP);
if ($ext == 'rar' && extension_loaded('rar'))
return new self($filename, self::RAR);
if ($ext == 'tar' || preg_match('~\.tar\.(gz|bz2|xz|Z)$~', $filename))
if (($ext == 'tar' || preg_match('~\.tar\.(gz|bz2|xz|Z)$~', $filename)) && class_exists('\Archive_Tar'))
return new self($filename, self::TAR);
if ($ext == 'gz' && extension_loaded('zlib'))
return new self($filename, self::GZIP);
if ($ext == 'bz2' && extension_loaded('bz2'))
return new self($filename, self::BZIP);
if ($ext == 'xz' && extension_loaded('xz'))
return new self($filename, self::LZMA);
if ($ext == 'iso' && class_exists('\CISOFile'))
return new self($filename, self::ISO);
if (true) return null;
Expand Down Expand Up @@ -146,6 +156,20 @@ public function __construct($filename, $type)
$this->compressedFilesSize = $this->archiveSize;
$this->uncompressedFilesSize = $this->gzipStat['size'];
break;
case self::BZIP:
$this->files = array(basename($filename, '.bz2'));
$this->bzipFilename = $filename;
$this->bzipStat = array('mtime' => filemtime($filename));
$this->compressedFilesSize = $this->archiveSize;
$this->uncompressedFilesSize = $this->archiveSize;
break;
case self::LZMA:
$this->files = array(basename($filename, '.xz'));
$this->lzmaFilename = $filename;
$this->bzipStat = array('mtime' => filemtime($filename));
$this->compressedFilesSize = $this->archiveSize;
$this->uncompressedFilesSize = $this->archiveSize;
break;
case self::ISO:
// load php-iso-files
$this->iso = new \CISOFile;
Expand Down Expand Up @@ -258,6 +282,12 @@ public function countFiles()
case 'gzip':
return 1;
break;
case 'bzip2':
return 1;
break;
case 'lzma2':
return 1;
break;
case 'iso':
return count($this->files);
break;
Expand Down Expand Up @@ -298,6 +328,12 @@ public function getArchiveType()
case 'gzip':
return self::GZIP;
break;
case 'bzip2':
return self::BZIP;
break;
case 'lzma2':
return self::LZMA;
break;
case 'iso':
return self::ISO;
break;
Expand Down Expand Up @@ -387,6 +423,28 @@ public function getFileData($filename)

return $file;
break;
case 'bzip2':
if (!in_array($filename, $this->files)) return false;
$file = new \stdClass;
$file->filename = $filename;
$file->compressed_size = $this->archiveSize;
$file->uncompressed_size = $this->archiveSize;
$file->mtime = $this->bzipStat['mtime'];
$file->is_compressed = true;

return $file;
break;
case 'lzma2':
if (!in_array($filename, $this->files)) return false;
$file = new \stdClass;
$file->filename = $filename;
$file->compressed_size = $this->archiveSize;
$file->uncompressed_size = $this->archiveSize;
$file->mtime = $this->lzmaStat['mtime'];
$file->is_compressed = true;

return $file;
break;
case 'iso':
if (!in_array($filename, $this->files)) return false;
if (!isset($this->isoFilesData[$filename])) return false;
Expand Down Expand Up @@ -435,6 +493,19 @@ public function getFileContent($filename)
if (!in_array($filename, $this->files)) return false;
return gzdecode(file_get_contents($this->gzipFilename));
break;
case 'bzip2':
if (!in_array($filename, $this->files)) return false;
return bzdecompress(file_get_contents($this->bzipFilename));
break;
case 'lzma2':
if (!in_array($filename, $this->files)) return false;
$fp = xzopen($this->lzmaFilename, 'r');
ob_start();
xzpassthru($fp);
$content = ob_get_flush();
xzclose($fp);
return $content;
break;
case 'iso':
if (!in_array($filename, $this->files)) return false;
$Location = array_search($filename, $this->files);
Expand Down Expand Up @@ -536,6 +607,41 @@ public function extractNode($outputFolder, $node = '/')
return 0;
}
break;
case 'bzip2':
if ($node === '') {
$dir = rtrim($outputFolder, '/').'/';
if (!is_dir($dir)) mkdir($dir);
if (file_put_contents($dir.
basename($this->bzipFilename, '.bz2'),
bzdecompress(file_get_contents($this->bzipFilename)))
!== false)
return 1;
else
return false;
} else {
return 0;
}
break;
case 'lzma2':
if ($node === '') {
$dir = rtrim($outputFolder, '/').'/';
if (!is_dir($dir)) mkdir($dir);
$fp = xzopen($this->lzmaFilename, 'r');
ob_start();
xzpassthru($fp);
$content = ob_get_flush();
xzclose($fp);
if (file_put_contents($dir.
basename($this->lzmaFilename, '.xz'),
$content)
!== false)
return 1;
else
return false;
} else {
return 0;
}
break;
}
}

Expand Down Expand Up @@ -622,6 +728,8 @@ public static function archiveNodes($nodes, $aname, $fake = false)
else if ($ext == 'tar' || preg_match('~\.tar\.(gz|bz2|xz|Z)$~', $aname))
$atype = self::TAR;
else if ($ext == 'gz') $atype = self::GZIP;
else if ($ext == 'bz2') $atype = self::BZIP;
else if ($ext == 'xz') $atype = self::LZMA;
else return false;

switch ($atype) {
Expand Down Expand Up @@ -692,6 +800,32 @@ public static function archiveNodes($nodes, $aname, $fake = false)
else
return false;
break;
case self::BZIP:
if (count($files) > 1) return false;
/*if ($localname != basename($aname, '.bz2')) return false;
*/
$filename = array_shift($files);
if (is_null($filename)) return false; // invalid list
if (file_put_contents($aname,
bzcompress(file_get_contents($filename))) !== false)
return 1;
else
return false;
break;
case self::LZMA:
if (count($files) > 1) return false;
/*if ($localname != basename($aname, '.xz')) return false;
*/
$filename = array_shift($files);
if (is_null($filename)) return false; // invalid list
$fp = xzopen($aname, 'w');
$r = xzwrite($fp, file_get_contents($filename));
xzclose($fp);
if ($r !== false)
return 1;
else
return false;
break;
}
}

Expand Down

0 comments on commit 148b630

Please sign in to comment.