- fseek -> rewind

- fewer read commands, less ugly array stuff :D
- much cleaner way to deal with the version flag, stored files are now differently labeled than deflated files ( we follow the zip spec better than 7-Zip :D )


git-svn-id: file:///svn/phpbb/trunk@5579 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
David M 2006-02-24 05:30:25 +00:00
parent 835c9835d0
commit 37e0e0a4da

View file

@ -152,7 +152,7 @@ class compress_zip extends compress
{ {
// Loop the file, looking for files and folders // Loop the file, looking for files and folders
$dd_try = false; $dd_try = false;
fseek($this->fp, 0); rewind($this->fp);
while (!feof($this->fp)) while (!feof($this->fp))
{ {
@ -163,25 +163,19 @@ class compress_zip extends compress
{ {
// 'Local File Header' // 'Local File Header'
case "\x50\x4b\x03\x04": case "\x50\x4b\x03\x04":
// Get information about the zipped file but skip all the junk we don't need // Lets get everything we need.
fseek($this->fp, 4, SEEK_CUR); // We don't store the version needed to extract, the general purpose bit flag or the date and time fields
$c_method = current(unpack("v", fread($this->fp, 2))); // compression method $data = unpack("@4/vc_method/@10/Vcrc/Vc_size/Vuc_size/vname_len/vextra_field", fread($this->fp, 26));
fseek($this->fp, 4, SEEK_CUR); $file_name = fread($this->fp, $data['name_len']); // filename
$crc = current(unpack("V", fread($this->fp, 4))); // crc value
$c_size = current(unpack("V", fread($this->fp, 4))); // compressed size
$uc_size = current(unpack("V", fread($this->fp, 4))); // uncompressed size
$file_name_length = current(unpack("v", fread($this->fp, 2))); // filename length
$extra_field_length = current(unpack("v", fread($this->fp, 2))); // extra field length
$file_name = fread($this->fp, $file_name_length); // filename
if ($extra_field_length) if ($data['extra_field'])
{ {
fread($this->fp, $extra_field_length); fread($this->fp, $data['extra_field']); // extra field
} }
$target_filename = "$dst$file_name"; $target_filename = "$dst$file_name";
if (!$uc_size && !$crc && substr($file_name, -1, 1) == '/') if (!$data['uc_size'] && !$data['crc'] && substr($file_name, -1, 1) == '/')
{ {
if (!is_dir($target_filename)) if (!is_dir($target_filename))
{ {
@ -206,18 +200,18 @@ class compress_zip extends compress
continue; continue;
} }
if (!$uc_size) if (!$data['uc_size'])
{ {
$content = ''; $content = '';
} }
else else
{ {
$content = fread($this->fp, $c_size); $content = fread($this->fp, $data['c_size']);
} }
$fp = fopen($target_filename, "w"); $fp = fopen($target_filename, "w");
switch ($c_method) switch ($data['c_method'])
{ {
case 0: case 0:
// Not compressed // Not compressed
@ -226,7 +220,7 @@ class compress_zip extends compress
case 8: case 8:
// Deflate // Deflate
fwrite($fp, gzinflate($content, $uc_size)); fwrite($fp, gzinflate($content, $data['uc_size']));
break; break;
case 12: case 12:
@ -287,6 +281,7 @@ class compress_zip extends compress
{ {
$unc_len = $c_len = $crc = 0; $unc_len = $c_len = $crc = 0;
$zdata = ''; $zdata = '';
$var_ext = 10;
} }
else else
{ {
@ -294,12 +289,14 @@ class compress_zip extends compress
$crc = crc32($data); $crc = crc32($data);
$zdata = gzdeflate($data); $zdata = gzdeflate($data);
$c_len = strlen($zdata); $c_len = strlen($zdata);
$var_ext = 20;
// Did we compress? No, then use data as is // Did we compress? No, then use data as is
if ($c_len >= $unc_len) if ($c_len >= $unc_len)
{ {
$zdata = $data; $zdata = $data;
$c_len = $unc_len; $c_len = $unc_len;
$var_ext = 10;
} }
} }
unset($data); unset($data);
@ -309,11 +306,9 @@ class compress_zip extends compress
// Are we a file or a directory? Set archive for file // Are we a file or a directory? Set archive for file
$attrib = ($is_dir) ? 16 : 32; $attrib = ($is_dir) ? 16 : 32;
$var_ext = ($is_dir) ? "\x0a" : "\x14";
// File Record Header // File Record Header
$fr = "\x50\x4b\x03\x04"; // Local file header 4bytes $fr = "\x50\x4b\x03\x04"; // Local file header 4bytes
$fr .= "$var_ext\x00"; // ver needed to extract 2bytes $fr .= pack('v', $var_ext); // ver needed to extract 2bytes
$fr .= "\x00\x00"; // gen purpose bit flag 2bytes $fr .= "\x00\x00"; // gen purpose bit flag 2bytes
$fr .= $c_method; // compression method 2bytes $fr .= $c_method; // compression method 2bytes
$fr .= $hexdtime; // last mod time and date 2+2bytes $fr .= $hexdtime; // last mod time and date 2+2bytes
@ -336,7 +331,7 @@ class compress_zip extends compress
// Central Directory Header // Central Directory Header
$cdrec = "\x50\x4b\x01\x02"; // header 4bytes $cdrec = "\x50\x4b\x01\x02"; // header 4bytes
$cdrec .= "\x00\x00"; // version made by $cdrec .= "\x00\x00"; // version made by
$cdrec .= "$var_ext\x00"; // version needed to extract $cdrec .= pack('v', $var_ext); // version needed to extract
$cdrec .= "\x00\x00"; // gen purpose bit flag $cdrec .= "\x00\x00"; // gen purpose bit flag
$cdrec .= $c_method; // compression method $cdrec .= $c_method; // compression method
$cdrec .= $hexdtime; // last mod time & date $cdrec .= $hexdtime; // last mod time & date