PHP Classes

File: CFALib

Recommend this page to a friend!
  Classes of Tobias Marstaller   CFA Library   CFALib   Download  
File: CFALib
Role: Class source
Content type: text/plain
Description: All 4 Classes of the Library
Class: CFA Library
Compress and extract files from a single file
Author: By
Last change: Another bug has been fixed, CFAFile should now work properly.
Date: 12 years ago
Size: 10,609 bytes
 

Contents

Class file image Download
<?php class CFACreator { private $source; private $pw; public function __construct($source) { if (!file_exists($source)) { throw new Exception($source." not found."); } if (!is_dir($source)) { throw new Exception("There is no need to pack a single file."); } if (substr($source, strlen($source)-1)!="\\" && substr($source, strlen($source)-1)!="/") $source.="/"; $this->source=$source; } public function setPassword($pw) { $this->pw=$pw; } public function packTo($file, $crypt=false) { $files=$this->listDir($this->source); if ($crypt) { $out_stream=tmpfile(); } else { $out_stream=fopen($file, "w+"); fwrite($out_stream, "r"); } foreach ($files as $name=>$size) { $name=gzcompress($name); fwrite($out_stream, $this->compress(strlen($name))); fwrite($out_stream, chr(255)); fwrite($out_stream, $name); fwrite($out_stream, $this->compress($size)); fwrite($out_stream, chr(255)); } fwrite($out_stream, chr(255)); foreach ($files as $name=>$size) { $fp=fopen($this->source.$name, "r+"); while ($size>=100) { fwrite($out_stream, fread($fp, 100)); $size-=100; } if ($size!=0) fwrite($out_stream, fread($fp, $size)); } if ($crypt) { rewind($out_stream); $tmp=$out_stream; $out_stream=fopen($file, "w+"); fwrite($out_stream, "c"); $iv=$this->pw; if (strlen($iv)>8) { $iv=substr($iv, 0, 8); } elseif (strlen($iv)<8) { $num=round(8/strlen($iv))+1; $iv=str_repeat($iv, $num); $iv=substr($iv, 0, 8); } while (!feof($tmp)) { $part=fread($tmp, 100); $part=mcrypt_encrypt(MCRYPT_BLOWFISH, $this->pw, $part, "cbc", $iv); $part=base64_encode($part); fwrite($out_stream, $part); } fclose($tmp); } fclose($out_stream); } private function listDir($path, $is_root=true, $root=null) { $files=array(); if (substr($path, strlen($path)-1)!="\\" && substr($path, strlen($path)-1)!="/") $path.="/"; if ($root==null && $is_root) $root=$path; if ($dir=opendir($path)) { while ($file=readdir($dir)) { if ($file!=".." && $file!=".") { if (is_dir($path.$file)) { $ar=$this->listDir($path.$file, false, $root); $files=array_merge($files, $ar); } else { if ($is_root) { $name=$file; } else { $name=substr($path.$file, strlen($root)); } $files[$name]=filesize($path.$file); } } } closedir($dir); return $files; } else { throw new Exception("Could not open ".$path); } } public static function compress($int) { $comp=""; $full=0; while ($int>=253) { if ($full==253) { $comp.=chr(253); $full=0; } $full++; $int-=253; } if ($full!=0) $comp.=chr($full); $comp.=chr(254); if ($int!=0) $comp.=chr($int); return $comp; } } class CFAExtractor { private $path; private $pw; public function __construct($path) { if (!file_exists($path)) { throw new Exception($path." not found."); } $this->path=$path; } public function setPassword($pw) { $this->pw=$pw; } public function extractTo($path) { if (!file_exists($this->path)) { throw new Exception($path." not found."); } if (substr($path, strlen($path)-1)!="\\" && substr($path, strlen($path)-1)!="/") $path.="/"; $in_stream=fopen($this->path, "r"); $mode=fread($in_stream, 1); if ($mode!="c" && $mode!="r") { fclose($in_stream); throw new Exception("Invalid file given."); } if ($mode=="c") { // crypted file if ($this->pw==null) { throw new Exception("File encrypted but no password given!"); } $iv=$this->pw; if (strlen($iv)>8) { $iv=substr($iv, 0, 8); } elseif (strlen($iv)<8) { $num=round(8/strlen($iv))+1; $iv=str_repeat($iv, $num); $iv=substr($iv, 0, 8); } $tmp_file=tmpfile(); while (!feof($in_stream)) { $part=fread($in_stream, 136); $part=base64_decode($part); $part=mcrypt_decrypt(MCRYPT_BLOWFISH, $this->pw, $part, "cbc", $iv); fwrite($tmp_file, $part); } fclose($in_stream); rewind($tmp_file); $in_stream=$tmp_file; } $files=array(); $ci=ord(fread($in_stream, 1)); while ($ci!=255) { $name_length=""; while ($ci!=255) { $name_length.=chr($ci); $ci=ord(fread($in_stream, 1)); } $name_length=$this->uncompress($name_length); $name=gzuncompress(fread($in_stream, $name_length)); $size=""; $ci=ord(fread($in_stream, 1)); while ($ci!=255) { $size.=chr($ci); $ci=ord(fread($in_stream, 1)); } $size=$this->uncompress($size); $files[$name]=$size; $ci=ord(fread($in_stream, 1)); } $this->mkdir($path); foreach ($files as $name=>$size) { $this->mkdir(dirname($path.$name)); $fp=fopen($path.$name, "w+"); if (!$fp) { throw new Exception("Could not create ".$path.$name); } while ($size>=100) { fwrite($fp, fread($in_stream, 100)); $size-=100; } if ($size!=0) fwrite($fp, fread($in_stream, $size)); fclose($fp); } fclose($in_stream); } public static function mkdir($path, $rights=0777) { if (file_exists($path)) return; $path=str_replace("\\", "/", $path); if (substr($path, strlen($path)-1)=="/") $path=substr($path, 0, strlen($path)-1); $prev=strrpos($path, "/"); $prev=substr($path, 0, $prev); if (!file_exists($prev)) { self::mkdir($prev, $rights); } mkdir($path); } public static function uncompress($bytes) { $j=strlen($bytes)-1; $full=0; $c=-1; $i=0; $c=ord($bytes[0]); while ($c!=254 && $i!=$j) { $full+=$c; $i++; $c=ord($bytes[$i]); } $size=$full*253; $i++; while ($i<=$j) { $c=$bytes[$i]; $size+=ord($c); $i++; } return $size; } } class CFAFile { private $filename; private $filelist=array(); private $passsword; public function __construct($filename, $pw=null) { $this->filename=$filename; $this->password=$pw; if (file_exists($filename)) { $in_stream=fopen($filename, "r"); $mode=fread($in_stream, 1); if ($mode=="c") { } elseif ($mode!="r") { throw new Exception("Invalid file given."); } $ci=ord(fread($in_stream, 1)); $pos=0; $files=array(); $buffer_size=2; while ($ci!=255) { $name_length=""; while ($ci!=255) { $name_length.=chr($ci); $ci=ord(fread($in_stream, 1)); $buffer_size++; } $name_length=$this->uncompress($name_length); $name=gzuncompress(fread($in_stream, $name_length)); $buffer_size+=$name_length; $size=""; $ci=ord(fread($in_stream, 1)); $buffer_size++; while ($ci!=255) { $size.=chr($ci); $ci=ord(fread($in_stream, 1)); $buffer_size++; } $size=$this->uncompress($size); $files[]=array( "name"=>$name, "size"=>$size, "pos"=>$pos ); $pos+=$size; $ci=ord(fread($in_stream, 1)); $buffer_size++; } fclose($in_stream); foreach($files as $info) { $this->filelist[]=new CFAEntry($info["name"], $filename, $info["size"], $info["pos"]+$buffer_size); $buffer_size+=$info["size"]; } } } public function getFileList() { return $this->filelist; } public function remove($s_entry) { $found=false; foreach ($this->filelist as $k=>$entry) { if ($entry===$s_entry) { $found=true; unset($this->filelist[$k]); } } if ($found) $this->filelist=array_merge($this->filelist, array()); } public function add($entry) { if (!$entry instanceof CFAEntry) return; $this->filelist[]=$entry; } public function flushToFile() { if ($this->password!=null) { $stream=tmpfile(); } else { $stream=fopen($this->filename, "w+"); fwrite($stream, "r"); } foreach ($this->filelist as $entry) { $name=gzcompress($entry->getName()); fwrite($stream, $this->compress(strlen($name))); fwrite($stream, chr(255)); fwrite($stream, $name); fwrite($stream, $this->compress($entry->getSize())); fwrite($stream, chr(255)); } fwrite($stream, chr(255)); foreach ($this->filelist as $entry) { $handle=$entry->getFileHandle(); $POS=ftell($handle); rewind($handle); while (!feof($handle)) { fwrite($stream, fread($handle, 1)); } fseek($handle, $POS); } } public static function uncompress($bytes) { $j=strlen($bytes)-1; $full=0; $c=-1; $i=0; $c=ord($bytes[0]); while ($c!=254 && $i!=$j) { $full+=$c; $i++; $c=ord($bytes[$i]); } $size=$full*253; $i++; while ($i<=$j) { $c=$bytes[$i]; $size+=ord($c); $i++; } return $size; } public static function compress($int) { $comp=""; $full=0; while ($int>=253) { if ($full==253) { $comp.=chr(253); $full=0; } $full++; $int-=253; } if ($full!=0) $comp.=chr($full); $comp.=chr(254); if ($int!=0) $comp.=chr($int); return $comp; } } class CFAEntry { private $sourcefile="unknown"; private $filename; private $size=-1; private $start="unknown"; private $handle; // 1 - Existiert, 2 - Muss erstellt werden private $mode=-1; public function __construct($name, $sourcefile=null, $size=null, $start=null) { if ($sourcefile==null) { $this->filename=$name; $this->mode=2; } else { if (!file_exists($sourcefile)) { throw new Exception($sourcefile." not found."); } $this->sourcefile=$sourcefile; $this->filename=$name; $this->size=$size; $this->start=$start; $this->mode=1; } } public function __destruct() { if ($this->handle!=null) fclose($this->handle); } public function getSize() { if ($this->handle==null) { if ($this->size!=-1) return $this->size; return 0; } else { $info=fstat($this->handle); return $info["size"]; } } public function getName() { return $this->filename; } public function getSourcefile() { return $this->sourcefile; } public function getFileHandle() { if ($this->handle==null) { $this->handle=tmpfile(); if ($this->mode==1) { $nsize=(int) "".$this->size; $sf_stream=fopen($this->sourcefile, "r"); fseek($sf_stream, $this->start); while ($nsize>=100) { fwrite($this->handle, fread($sf_stream, 100)); $nsize-=100; } if ($nsize!=0) fwrite($this->handle, fread($sf_stream, $nsize)); fclose($sf_stream); rewind($this->handle); } } return $this->handle; } } ?>