aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/functions_compress.php
diff options
context:
space:
mode:
authorDavid M <davidmj@users.sourceforge.net>2006-01-27 06:51:52 +0000
committerDavid M <davidmj@users.sourceforge.net>2006-01-27 06:51:52 +0000
commite78c215eba60bb22dc2c07ebb86061b509205c2d (patch)
treefec07cf896a141c0dbfdba31392f262955c340ff /phpBB/includes/functions_compress.php
parente77bc7e936d8cec58ca62b4afea09204798597f3 (diff)
downloadforums-e78c215eba60bb22dc2c07ebb86061b509205c2d.tar
forums-e78c215eba60bb22dc2c07ebb86061b509205c2d.tar.gz
forums-e78c215eba60bb22dc2c07ebb86061b509205c2d.tar.bz2
forums-e78c215eba60bb22dc2c07ebb86061b509205c2d.tar.xz
forums-e78c215eba60bb22dc2c07ebb86061b509205c2d.zip
- More loose definition regarding what gets to be a folder and what does not (More accurate, we lost folders before...)
- Changed some fread()s to fseek()s - Much faster, single loop ( This might eat up more mem! Please report findings! ) git-svn-id: file:///svn/phpbb/trunk@5498 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes/functions_compress.php')
-rw-r--r--phpBB/includes/functions_compress.php176
1 files changed, 73 insertions, 103 deletions
diff --git a/phpBB/includes/functions_compress.php b/phpBB/includes/functions_compress.php
index c7468d6d30..c99328f54c 100644
--- a/phpBB/includes/functions_compress.php
+++ b/phpBB/includes/functions_compress.php
@@ -154,60 +154,101 @@ class compress_zip extends compress
$dd_try = false;
fseek($this->fp, 0);
- while (true)
+ while (!feof($this->fp))
{
// Check if the signature is valid...
$signature = fread($this->fp, 4);
- if (feof($this->fp))
- {
- break;
- }
- // TODO: Move the extraction loop inside the signature detection code, small speed boost
switch ($signature)
{
// 'Local File Header'
case "\x50\x4b\x03\x04":
// Get information about the zipped file but skip all the junk we don't need
- fread($this->fp, 4);
- $file['c_method'] = unpack("v", fread($this->fp, 2)); // compression method
- fread($this->fp, 8);
- $file['c_size'] = unpack("V", fread($this->fp, 4)); // compressed size
- $file['uc_size'] = unpack("V", fread($this->fp, 4)); // uncompressed size
- $file_name_length = unpack("v", fread($this->fp, 2)); // filename length
- $extra_field_length = unpack("v", fread($this->fp, 2)); // extra field length
- $file_name = fread($this->fp, $file_name_length[1]); // filename
-
- if ($extra_field_length[1])
+ fseek($this->fp, 4, SEEK_CUR);
+ $c_method = current(unpack("v", fread($this->fp, 2))); // compression method
+ fseek($this->fp, 4, SEEK_CUR);
+ $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)
{
- fread($this->fp, $extra_field_length[1]);
+ fread($this->fp, $extra_field_length);
}
- $file['offset'] = ftell($this->fp);
+ $target_filename = "$dst$file_name";
- // Bypass the whole compressed contents, and look for the next file
- fseek($this->fp, $file['c_size'][1], SEEK_CUR);
+ if (!$uc_size && !$crc && substr($file_name, -1, 1) == '/')
+ {
+ if (!is_dir($target_filename))
+ {
+ $str = '';
+ $folders = explode('/', $target_filename);
- // Mount file table
- $seek_ary[$file_name] = array(
- 'c_method' => $file['c_method'][1],
- 'c_size' => $file['c_size'][1],
- 'uc_size' => $file['uc_size'][1],
- 'offset' => $file['offset']
- );
+ // Create and folders and subfolders if they do not exist
+ foreach ($folders as $folder)
+ {
+ $str = (!empty($str)) ? $str . '/' . $folder : $folder;
+ if (!is_dir($str))
+ {
+ if (!@mkdir($str, 0777))
+ {
+ trigger_error("Could not create directory $folder");
+ }
+ @chmod($str, 0777);
+ }
+ }
+ }
+ // This is a directory, we are not writting files
+ continue;
+ }
+
+ if (!$uc_size)
+ {
+ $content = '';
+ }
+ else
+ {
+ $content = fread($this->fp, $c_size);
+ }
+
+ $fp = fopen($target_filename, "w");
+
+ switch ($c_method)
+ {
+ case 0:
+ // Not compressed
+ fwrite($fp, $content);
+ break;
+
+ case 8:
+ // Deflate
+ fwrite($fp, gzinflate($content, $uc_size));
+ break;
+
+ case 12:
+ // Bzip2
+ fwrite($fp, bzdecompress($content));
+ break;
+ }
+
+ fclose($fp);
break;
// 'Central Directory Header'
case "\x50\x4b\x01\x02":
- fread($this->fp, 24);
- fread($this->fp, 12 + current(unpack("v", fread($this->fp, 2))) + current(unpack("v", fread($this->fp, 2))) + current(unpack("v", fread($this->fp, 2))));
+ fseek($this->fp, 24, SEEK_CUR);
+ fseek($this->fp, 12 + current(unpack("v", fread($this->fp, 2))) + current(unpack("v", fread($this->fp, 2))) + current(unpack("v", fread($this->fp, 2))), SEEK_CUR);
break;
- // We safely end the loop as we are totally finished with looking for files and folders
+ // Hit the end of the central directory record, we can safely end the loop as we are totally finished with looking for files and folders
case "\x50\x4b\x05\x06":
break 2;
- // Look for the next signature...
+ // 'Packed to Removable Disk', ignore it and look for the next signature...
case 'PK00':
continue 2;
@@ -221,81 +262,10 @@ class compress_zip extends compress
continue 2;
}
trigger_error("Unexpected header, ending loop");
- break 2;
+ break 2;
}
$dd_try = false;
}
-
- if (sizeof($seek_ary))
- {
- foreach ($seek_ary as $filename => $trash)
- {
- $dirname = dirname($filename);
-
- if (!is_dir("$dst$dirname"))
- {
- $str = '';
- $folders = explode('/', $dirname);
-
- // Create and folders and subfolders if they do not exist
- foreach ($folders as $folder)
- {
- $str = (!empty($str)) ? $str . '/' . $folder : $folder;
-
- if (!is_dir("$dst$str"))
- {
- if (!@mkdir("$dst$str", 0777))
- {
- trigger_error("Could not create directory $folder");
- }
- @chmod("$dst$str", 0777);
- }
- }
- }
-
- if (substr($filename, -1, 1) == '/')
- {
- continue;
- }
-
- $target_filename = "$dst$filename";
- $fdetails = &$seek_ary[$filename];
-
- if (!$fdetails['uc_size'])
- {
- $fp = fopen($target_filename, "w");
- fwrite($fp, '');
- fclose($fp);
- }
-
- fseek($this->fp, $fdetails['offset']);
- $mode = $fdetails['c_method'];
- $content = fread($this->fp, $fdetails['c_size']);
-
-
- $fp = fopen($target_filename, "w");
-
- switch ($mode)
- {
- case 0:
- // Not compressed
- fwrite($fp, $content);
- break;
-
- case 8:
- // Deflate
- fwrite($fp, gzinflate($content, $fdetails['uc_size']));
- break;
-
- case 12:
- // Bzip2
- fwrite($fp, bzdecompress($content));
- break;
- }
-
- fclose($fp);
- }
- }
}
function close()