Class for generating compressed files

Source: Internet
Author: User
Tags rewind unpack

<?

// Created by Bouchon
// Http://dev.maxg.info

// Need help? Http://forum.maxg.info

Class zip
{

VaR $ datasec, $ ctrl_dir = array ();
VaR $ eof_ctrl_dir = "/x50/x4b/x05/x06/x00/x00/x00/x00 ";
VaR $ old_offset = 0; var $ dirs = array (".");

Function get_list ($ zip_name)
{
$ Zip = @ fopen ($ zip_name, 'rb ');
If (! $ Zip) Return (0 );
$ Centd = $ this-> readcentraldir ($ zip, $ zip_name );

@ Rewind ($ zip );
@ Fseek ($ zip, $ centd ['offset']);

For ($ I = 0; $ I <$ centd ['entries']; $ I ++)
{
$ Header = $ this-> readcentralfileheaders ($ zip );
$ Header ['index'] = $ I; $ info ['filename'] = $ header ['filename'];
$ Info ['stored _ filename'] = $ header ['stored _ filename'];
$ Info ['SIZE'] = $ header ['SIZE']; $ info ['compressed _ size'] = $ header ['compressed _ size'];
$ Info ['crc '] = strtoupper (dechex ($ header ['crc']);
$ Info ['mtime'] = $ header ['mtime']; $ info ['comment'] = $ header ['comment'];
$ Info ['folder'] = ($ header ['external '] = 0x41ff0010 | $ header ['external'] = 16 )? 1:0;
$ Info ['index'] = $ header ['index']; $ info ['status'] = $ header ['status'];
$ RET [] = $ Info; unset ($ header );
}
Return $ ret;
}

Function add ($ files, $ compact)
{
If (! Is_array ($ files [0]) $ files = array ($ files );

For ($ I = 0; $ files [$ I]; $ I ++ ){
$ Fn = $ files [$ I];
If (! In_array (dirname ($ FN [0]), $ this-> dirs ))
$ This-> add_dir (dirname ($ FN [0]);
If (basename ($ FN [0])
$ RET [basename ($ FN [0])] = $ this-> add_file ($ FN [1], $ FN [0], $ compact );
}
Return $ ret;
}

Function get_file ()
{
$ DATA = implode ('', $ this-> datasec );
$ Ctrldir = implode ('', $ this-> ctrl_dir );

Return $ data. $ ctrldir. $ this-> eof_ctrl_dir.
Pack ('V', sizeof ($ this-> ctrl_dir). Pack ('V', sizeof ($ this-> ctrl_dir )).
Pack ('V', strlen ($ ctrldir). Pack ('V', strlen ($ data). "/x00/x00 ";
}

Function add_dir ($ name)
{
$ Name = str_replace ("//", "/", $ name );
$ Fr = "/x50/x4b/x03/x04/x0a/x00/x00/x00/x00/x00/x00/x00/x00/x00 ";

$ Fr. = pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 ). pack ("V", strlen ($ name ));
$ Fr. = pack ("V", 0 ). $ name. pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 );
$ This-> datasec [] = $ fr;

$ New_offset = strlen (implode ("", $ this-> datasec ));

$ Cdrec = "/x50/x4b/x01/x02/x00/x00/x0a/x00/x00/x00/x00/x00/x00/x00/x00/x00 ";
$ Cdrec. = pack ("V", 0 ). pack ("V", 0 ). pack ("V", 0 ). pack ("V", strlen ($ name ));
$ Cdrec. = pack ("V", 0). Pack ("V", 0). Pack ("V", 0). Pack ("V", 0 );
$ Ext = "/xFF ";
$ Cdrec. = pack ("V", 16). Pack ("V", $ this-> old_offset). $ name;

$ This-> ctrl_dir [] = $ cdrec;
$ This-> old_offset = $ new_offset;
$ This-> dirs [] = $ name;
}

Function add_file ($ data, $ name, $ compact = 1)
{
$ Name = str_replace ('//', '/', $ name );
$ Dtime = dechex ($ this-> dostime ());

$ Hexdtime = '/X'. $ dtime [6]. $ dtime [7].'/X'. $ dtime [4]. $ dtime [5]
. '/X'. $ dtime [2]. $ dtime [3].'/X'. $ dtime [0]. $ dtime [1];
Eval ('$ hexdtime = "'. $ hexdtime .'";');

If ($ compact)
$ Fr = "/x50/x4b/x03/x04/x14/x00/x00/x00/x08/x00". $ hexdtime;
Else $ Fr = "/x50/x4b/x03/x04/x0a/x00/x00/x00/x00/x00". $ hexdtime;
$ Unc_len = strlen ($ data); $ CRC = CRC32 ($ data );

If ($ compact ){
$ Zdata = gzcompress ($ data); $ c_len = strlen ($ zdata );
$ Zdata = substr ($ zdata, 0, strlen ($ zdata)-4), 2 );
} Else {
$ Zdata = $ data;
}
$ C_len = strlen ($ zdata );
$ Fr. = pack ('V', $ CRC). Pack ('V', $ c_len). Pack ('V', $ unc_len );
$ Fr. = pack ('V', strlen ($ name). Pack ('V', 0). $ name. $ zdata;

$ Fr. = pack ('V', $ CRC). Pack ('V', $ c_len). Pack ('V', $ unc_len );

$ This-> datasec [] = $ fr;
$ New_offset = strlen (implode ('', $ this-> datasec ));
If ($ compact)
$ Cdrec = "/x50/x4b/x01/x02/x00/x00/x14/x00/x00/x00/x08/x00 ";
Else $ cdrec = "/x50/x4b/x01/x02/x14/x00/x0a/x00/x00/x00/x00/x00 ";
$ Cdrec. = $ hexdtime. Pack ('V', $ CRC). Pack ('V', $ c_len). Pack ('V', $ unc_len );
$ Cdrec. = pack ('V', strlen ($ name). Pack ('V', 0). Pack ('V', 0 );
$ Cdrec. = pack ('V', 0). Pack ('V', 0). Pack ('V', 32 );
$ Cdrec. = pack ('V', $ this-> old_offset );

$ This-> old_offset = $ new_offset;
$ Cdrec. = $ name;
$ This-> ctrl_dir [] = $ cdrec;
Return true;
}
Bytes -------------------------------------------------------------------------------------------------------------------------

Function dostime (){
$ Timearray = getdate ();
If ($ timearray ['Year'] <1980 ){
$ Timearray ['Year'] = 1980; $ timearray ['mon'] = 1;
$ Timearray ['mday'] = 1; $ timearray ['hours'] = 0;
$ Timearray ['minutes '] = 0; $ timearray ['seconds'] = 0;
}
Return ($ timearray ['Year']-1980) <25) | ($ timearray ['mon'] <21) | ($ timearray ['mday'] <16) | ($ timearray ['hours'] <11) |
($ Timearray ['minutes '] <5) | ($ timearray ['seconds']> 1 );
}

Function extract ($ Zn, $ to, $ Index = array (-1 ))
{
$ OK = 0; $ zip = @ fopen ($ Zn, 'rb ');
If (! $ Zip) Return (-1 );
$ Cdir = $ this-> readcentraldir ($ zip, $ Zn );
$ Pos_entry = $ cdir ['offset'];

If (! Is_array ($ index) {$ Index = array ($ index );}
For ($ I = 0; $ Index [$ I]; $ I ++ ){
If (intval ($ Index [$ I])! = $ Index [$ I] | $ Index [$ I]> $ cdir ['entries'])
Return (-1 );
}

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 (in_array ("-1", $ index) | in_array ($ I, $ index ))
$ Stat [$ header ['filename'] = $ this-> extractfile ($ header, $ to, $ zip );

}
Fclose ($ zip );
Return $ Stat;
}

Function readfileheader ($ zip)
{
$ Binary_data = fread ($ zip, 30 );
$ DATA = unpack ('vchk/Vid/vversion/vflag/vcompression/vmtime/vmdate/vcrc/vcompressed_size/vsize/vfilename_len/vextra_len ', $ binary_data );

$ Header ['filename'] = fread ($ zip, $ data ['filename _ len']);
If ($ data ['extra _ len']! = 0 ){
$ Header ['extra '] = fread ($ zip, $ data ['extra _ len']);
} Else {$ header ['extra '] = '';}

$ Header ['compression'] = $ data ['compression']; $ header ['SIZE'] = $ data ['SIZE'];
$ Header ['compressed _ size'] = $ data ['compressed _ size'];
$ Header ['crc '] = $ data ['crc']; $ header ['flag'] = $ data ['flag'];
$ Header ['mdate'] = $ data ['mdate']; $ header ['mtime'] = $ data ['mtime'];

If ($ header ['mdate'] & $ header ['mtime']) {
$ Hour = ($ header ['mtime'] & 0xf800)> 11; $ minute = ($ header ['mtime'] & 0x07e0)> 5;
$ Seconde = ($ header ['mtime'] & 0x001f) * 2; $ year = ($ header ['mdate'] & 0xfe00)> 9) + 1980;
$ Month = ($ header ['mdate'] & 0x01e0)> 5; $ day = $ header ['mdate'] & 0x001f;
$ Header ['mtime'] = mktime ($ hour, $ minute, $ seconde, $ month, $ day, $ year );
} Else {$ header ['mtime'] = Time ();}

$ Header ['stored _ filename'] = $ header ['filename'];
$ Header ['status'] = "OK ";
Return $ header;
}

Function readcentralfileheaders ($ zip ){
$ Binary_data = fread ($ zip, 46 );
$ Header = unpack ('vchkid/Vid/vversion/kernel/vflag/vcompression/vmtime/vmdate/vcrc/kernel/vsize/kernel/vextra_len/vcomment_len/vdisk/vinternal/vexternal/ voffset ', $ binary_data );

If ($ header ['filename _ len']! = 0)
$ Header ['filename'] = fread ($ zip, $ header ['filename _ len']);
Else $ header ['filename'] = '';

If ($ header ['extra _ len']! = 0)
$ Header ['extra '] = fread ($ zip, $ header ['extra _ len']);
Else $ header ['extra '] = '';

If ($ header ['comment _ len']! = 0)
$ Header ['comment'] = fread ($ zip, $ header ['comment _ len']);
Else $ header ['comment'] = '';

If ($ header ['mdate'] & $ header ['mtime'])
{
$ Hour = ($ header ['mtime'] & 0xf800)> 11;
$ Minute = ($ header ['mtime'] & 0x07e0)> 5;
$ Seconde = ($ header ['mtime'] & 0x001f) * 2;
$ Year = ($ header ['mdate'] & 0xfe00)> 9) + 1980;
$ Month = ($ header ['mdate'] & 0x01e0)> 5;
$ Day = $ header ['mdate'] & 0x001f;
$ Header ['mtime'] = mktime ($ hour, $ minute, $ seconde, $ month, $ day, $ year );
} Else {
$ Header ['mtime'] = Time ();
}
$ Header ['stored _ filename'] = $ header ['filename'];
$ Header ['status'] = 'OK ';
If (substr ($ header ['filename'],-1) = '/')
$ Header ['external '] = 0x41ff0010;
Return $ header;
}

Function readcentraldir ($ zip, $ zip_name)
{
$ Size = filesize ($ zip_name );
If ($ size <277) $ maximum_size = $ size;
Else $ maximum_size = 277;

@ Fseek ($ zip, $ size-$ maximum_size );
$ Pos = ftell ($ zip); $ bytes = 0x00000000;

While ($ POS <$ size)
{
$ Byte = @ fread ($ zip, 1); $ bytes = ($ bytes <8) | ord ($ byte );
If ($ bytes = 0x504b0506) {$ POS ++; break;} $ POS ++;
}

$ DATA = unpack ('vdisk/vdisk_start/vdisk_entries/ventries/vsize/voffset/vcomment_size ',
Fread ($ zip, 18 ));

If ($ data ['comment _ size']! = 0)
$ Centd ['comment'] = fread ($ zip, $ data ['comment _ size']);
Else $ centd ['comment'] = ''; $ centd ['entries'] = $ data ['entries'];
$ Centd ['disk _ entries'] = $ data ['disk _ entries'];
$ Centd ['offset'] = $ data ['offset']; $ centd ['disk _ start'] = $ data ['disk _ start'];
$ Centd ['SIZE'] = $ data ['SIZE']; $ centd ['disk'] = $ data ['disk'];
Return $ centd;
}

Function extractfile ($ header, $ to, $ zip)
{
$ Header = $ this-> readfileheader ($ zip );

If (substr ($ to,-1 )! = "/") $ To. = "/";
If (! @ Is_dir ($ to) @ mkdir ($ to, 0777 );

$ PTH = explode ("/", dirname ($ header ['filename']);
For ($ I = 0; isset ($ PTH [$ I]); $ I ++ ){
If (! $ PTH [$ I]) continue;
If (! Is_dir ($ to. $ PTH [$ I]) @ mkdir ($ to. $ PTH [$ I], 0777 );
}
If (! ($ Header ['external '] = 0x41ff0010 )&&! ($ Header ['external '] = 16 ))
{
If ($ header ['compression'] = 0)
{
$ Fp = @ fopen ($ to. $ header ['filename'], 'wb ');
If (! $ FP) Return (-1 );
$ Size = $ header ['compressed _ size'];

While ($ size! = 0)
{
$ Read_size = ($ size <2048? $ Size: 2048 );
$ Buffer = fread ($ zip, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ FP, $ binary_data, $ read_size );
$ Size-= $ read_size;
}
Fclose ($ FP );
Touch ($ to. $ header ['filename'], $ header ['mtime']);

} Else {
$ Fp = @fopen($to.w.header='filename'{.'.gz ', 'wb ');
If (! $ FP) Return (-1 );
$ Binary_data = pack ('va1a1va1a1 ', 0x8b1f, CHR ($ header ['compression']),
CHR (0x00), time (), CHR (0x00), CHR (3 ));

Fwrite ($ FP, $ binary_data, 10 );
$ Size = $ header ['compressed _ size'];

While ($ size! = 0)
{
$ Read_size = ($ size <1024? $ Size: 1024 );
$ Buffer = fread ($ zip, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ FP, $ binary_data, $ read_size );
$ Size-= $ read_size;
}

$ Binary_data = pack ('vv ', $ header ['crc'], $ header ['SIZE']);
Fwrite ($ FP, $ binary_data, 8); fclose ($ FP );

$ Gzp = @gzopen({to.w.header='filename'{.'.gz ', 'rb') or die ("Cette archive est compress é e ");
If (! $ Gzp) Return (-2 );
$ Fp = @ fopen ($ to. $ header ['filename'], 'wb ');
If (! $ FP) Return (-1 );
$ Size = $ header ['SIZE'];

While ($ size! = 0)
{
$ Read_size = ($ size <2048? $ Size: 2048 );
$ Buffer = gzread ($ gzp, $ read_size );
$ Binary_data = pack ('A'. $ read_size, $ buffer );
@ Fwrite ($ FP, $ binary_data, $ read_size );
$ Size-= $ read_size;
}
Fclose ($ FP); gzclose ($ gzp );

Touch ($ to. $ header ['filename'], $ header ['mtime']);
@ Unlink(%to.%header%'filename'%.'.gz ');

}}
Return true;
}
}

?>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.