[dokuwiki] Re: ZipLib

  • From: Danjer <Danjer@xxxxxxxxxxxx>
  • To: dokuwiki@xxxxxxxxxxxxx
  • Date: Mon, 10 Dec 2007 12:24:08 +0100

Hi all,

This is a patch for ZipLib.class.php to add the ability to read a file in a zip without write it.

Best regards,
Danjer

Andreas Gohr wrote:
Danjer writes:

Hi all,

Is it possible to add a function in ZibLib.class.php to extract a file directly in a string ? Actually with the ZibLib class it's not possible to read a file in a zip file without write it on disk before.

$zip = new ZipLib;

$unzipdata1 = $zip->ExtractStr( $zn, 0);
$unzipdata2 = $zip->ExtractStr( $zn, 1);

Feel free to send a patch ;-)

Andi



--- ./site/dokutest/dokuwiki-2007-06-26b/inc/ZipLib.class.php   2007-06-26 
20:27:15.000000000 +0200
+++ /home/danjer/ZipLib.class.php       2007-12-10 12:12:12.000000000 +0100
@@ -349,5 +349,91 @@
     return ap_mkdir($d);  
  }
  //--CS end
+
+
+ function ExtractStr($zn, $name) {
+   $ok = 0; 
+   $zip = @fopen($zn,'rb');
+   if(!$zip) return(NULL);
+   $cdir = $this->ReadCentralDir($zip,$zn);
+   $pos_entry = $cdir['offset'];
+
+   for ($i=0; $i<$cdir['entries']; $i++)
+   {
+     @fseek($zip, $pos_entry);
+     $header = $this->ReadCentralFileHeaders($zip);
+     $header['index'] = $i; 
+     $pos_entry = ftell($zip);
+     @rewind($zip); 
+     fseek($zip, $header['offset']);
+     if ($name == $header['stored_filename'] || $name == $header['filename']) {
+       $str = $this->ExtractStrFile($header, $zip);
+       fclose($zip);
+       return $str;
+     }
+      
+   }
+   fclose($zip);
+   return null;
+ }
+  
+  function ExtractStrFile($header,$zip) {
+    $hdr = $this->readfileheader($zip);
+    $binary_data = '';
+    if (!($header['external']==0x41FF0010) && !($header['external']==16))
+      {
+       if ($header['compression']==0)
+         { 
+           while ($size != 0)
+             {
+               $read_size = ($size < 2048 ? $size : 2048);
+               $buffer = fread($zip, $read_size);
+               $binary_data .= pack('a'.$read_size, $buffer);
+               $size -= $read_size;
+             }
+           return $binary_data;
+         } else {
+           $size = $header['compressed_size'];
+           if ($size == 0) {
+             return '';
+           }
+           //Just in case
+           if ($size > ($this->_ret_bytes(ini_get('memory_limit'))/2)) {
+             die("Compressed file is to huge to be uncompress in memory.");
+           }
+           while ($size != 0)
+             {
+               $read_size = ($size < 2048 ? $size : 2048);
+               $buffer = fread($zip, $read_size);
+               $binary_data .= pack('a'.$read_size, $buffer);
+               $size -= $read_size;
+             }
+           $str = gzinflate($binary_data, $header['size']);
+           if ($header['crc'] == crc32($str)) {
+             return $str;
+           } else {
+             die("Crc Error");
+           }
+         }
+      }
+    return NULL;
+  }
+  
+ function _ret_bytes($val) {
+   $val = trim($val);
+   $last = $val{strlen($val)-1};
+   switch($last) {
+   case 'k':
+   case 'K':
+     return (int) $val * 1024;
+     break;
+   case 'm':
+   case 'M':
+     return (int) $val * 1048576;
+     break;
+   default:
+     return $val;
+   }
+ }
 }
 

Other related posts: