public function __construct($handle = null)
 {
     parent::__construct();
     $this->header = parent::HEADER_EXTENDED_TIMESTAMP;
     if ($handle != null) {
         fread($handle, 2);
         $arr = unpack('vlength/cflags', fread($handle, 3));
         $this->length = $arr['length'];
         $this->flags = $arr['flags'] & 0xff;
         $consumed = 1;
         $this->isModTimeSet = ZipUtils::testBit($this->flags, 0);
         $this->isAcTimeSet = ZipUtils::testBit($this->flags, 1);
         $this->isCrTimeSet = ZipUtils::testBit($this->flags, 2);
         if ($this->isModTimeSet && $consumed < $this->length) {
             $arr = unpack('V', fread($handle, 4));
             $this->modTime = $arr[1];
             $consumed += 4;
         }
         if ($this->isAcTimeSet && $consumed < $this->length) {
             $arr = unpack('V', fread($handle, 4));
             $this->acTime = $arr[1];
             $consumed += 4;
         }
         if ($this->isCrTimeSet && $consumed < $this->length) {
             $arr = unpack('V', fread($handle, 4));
             $this->crTime = $arr[1];
         }
     }
 }
 public function parseHeader($handle)
 {
     $pk = fread($handle, 4);
     if ($pk == AbstractZipHeader::ZIP_LOCAL_FILE_HEADER) {
         /*
          * local file header signature     4 bytes  (0x04034b50)
          * version needed to extract       2 bytes
          * general purpose bit flag        2 bytes
          * compression method              2 bytes
          * last mod file time + file date  4 bytes
          * crc-32                          4 bytes
          * compressed size                 4 bytes
          * uncompressed size               4 bytes
          * file name length                2 bytes
          * extra field length              2 bytes
          * ---------------------------------------
          *                                30 bytes
          */
         $this->offset = (int) ftell($handle) - 4;
         $this->versionNeeded = fread($handle, 2);
         $arr = unpack("v2wa", fread($handle, 4));
         $this->gpFlags = $arr['wa1'];
         $this->gzType = $arr['wa2'];
         $this->dosTime = fread($handle, 4);
         $arr = unpack("V3dwa/v2wa", fread($handle, 16));
         $this->fileCRC32 = $arr['dwa1'];
         $this->gzLength = $arr['dwa2'];
         $this->dataLength = $arr['dwa3'];
         $filePathLength = $arr['wa1'];
         $localExtraFieldLength = $arr['wa2'];
         $this->path = fread($handle, $filePathLength);
         $this->dataOffset = 30 + $filePathLength + $localExtraFieldLength;
         if ($localExtraFieldLength > 0) {
             $eoef = ftell($handle) + $localExtraFieldLength;
             while (ftell($handle) < $eoef) {
                 $ef = AbstractExtraField::decodeField($handle);
                 /* @var $ef AbstractExtraField */
                 $this->extraFieldsArray[$ef->header] = $ef;
             }
         }
         $hasDataDescriptor = $this->gpFlags & 4 == 4;
         if ($hasDataDescriptor) {
             $pkHeader = AbstractZipHeader::seekPKHeader($handle);
             if ($pkHeader !== self::ZIP_LOCAL_DATA_DESCRIPTOR) {
                 fseek($handle, -12, SEEK_CUR);
             }
             $arr = unpack("Vdwa", fread($handle, 12));
             $this->fileCRC32 = $arr['dwa1'];
             $this->gzLength = $arr['dwa2'];
             $this->dataLength = $arr['dwa3'];
         } else {
             fseek($handle, $this->gzLength, SEEK_CUR);
         }
         $this->isDirectory = !$hasDataDescriptor && $this->dataLength == 0 && $this->fileCRC32 == 0;
     } else {
         if ($pk == AbstractZipHeader::ZIP_CENTRAL_FILE_HEADER) {
             /*
              * 
              * central file header signature   4 bytes  (0x02014b50)
              * version made by                 2 bytes
              * version needed to extract       2 bytes
              * general purpose bit flag        2 bytes
              * compression method              2 bytes
              * last mod file time              2 bytes
              * last mod file date              2 bytes
              * crc-32                          4 bytes
              * compressed size                 4 bytes
              * uncompressed size               4 bytes
              * file name length                2 bytes
              * extra field length              2 bytes
              * file comment length             2 bytes
              * disk number start               2 bytes
              * internal file attributes        2 bytes
              * external file attributes        4 bytes
              * relative offset of local header 4 bytes
              * ----------------------------------------
              *                                46 bytes
              *
              *  file name (variable size)
              *  extra field (variable size)
              *  file comment (variable size)
              */
             // $this->offset = (int)ftell($handle) - 4;
             $this->versionMadeBy = fread($handle, 2);
             $this->versionNeeded = fread($handle, 2);
             $arr = unpack("v2wa", fread($handle, 4));
             $this->gpFlags = $arr['wa1'];
             $this->gzType = $arr['wa2'];
             $this->dosTime = fread($handle, 4);
             $arr = unpack("V3dwa/v3wa", fread($handle, 18));
             // $this->fileCRC32				= $arr['dwa1'];
             // $this->gzLength				    = $arr['dwa2'];
             // $this->dataLength		    	= $arr['dwa3'];
             $filePathLength = $arr['wa1'];
             $centralExtraFieldLength = $arr['wa2'];
             $fileCommentLength = $arr['wa3'];
             $this->discNumberStart = fread($handle, 2);
             $this->internalFileAttributes = fread($handle, 2);
             $this->externalFileAttributes = fread($handle, 4);
             // $arr = unpack("V", fread($handle, 4));
             // $this->relativeOffsetOfLocalHeader	= $arr[1];
             // $this->path = fread($handle, $filePathLength);
             fseek($handle, 4 + $filePathLength, SEEK_CUR);
             if ($centralExtraFieldLength > 0) {
                 $eoef = ftell($handle) + $centralExtraFieldLength;
                 while (ftell($handle) < $eoef) {
                     $ef = AbstractExtraField::decodeField($handle, false);
                     /* @var $ef AbstractExtraField */
                     $ef2 = $this->extraFieldsArray[$ef->header];
                     if (isset($ef2)) {
                         $ef2->centralData = $ef->centralData;
                     } else {
                         $this->extraFieldsArray[$ef->header] = $ef;
                     }
                 }
             }
             if ($fileCommentLength > 0) {
                 $this->comment = fread($handle, $fileCommentLength);
             }
         } else {
             fseek($handle, -4, SEEK_CUR);
         }
     }
 }