PclZip::privReadEndCentralDir PHP Метод

privReadEndCentralDir() публичный Метод

--------------------------------------------------------------------------------
public privReadEndCentralDir ( &$p_central_dir )
    public function privReadEndCentralDir(&$p_central_dir)
    {
        $v_result = 1;
        // ----- Go to the end of the zip file
        $v_size = filesize($this->zipname);
        @fseek($this->zip_fd, $v_size);
        if (@ftell($this->zip_fd) != $v_size) {
            // ----- Error log
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\'');
            // ----- Return
            return PclZip::errorCode();
        }
        // ----- First try : look if this is an archive with no commentaries (most of the time)
        // in this case the end of central dir is at 22 bytes of the file end
        $v_found = 0;
        if ($v_size > 26) {
            @fseek($this->zip_fd, $v_size - 22);
            if (($v_pos = @ftell($this->zip_fd)) != $v_size - 22) {
                // ----- Error log
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
                // ----- Return
                return PclZip::errorCode();
            }
            // ----- Read for bytes
            $v_binary_data = @fread($this->zip_fd, 4);
            $v_data = @unpack('Vid', $v_binary_data);
            // ----- Check signature
            if ($v_data['id'] == 0x6054b50) {
                $v_found = 1;
            }
            $v_pos = ftell($this->zip_fd);
        }
        // ----- Go back to the maximum possible size of the Central Dir End Record
        if (!$v_found) {
            $v_maximum_size = 65557;
            // 0xFFFF + 22;
            if ($v_maximum_size > $v_size) {
                $v_maximum_size = $v_size;
            }
            @fseek($this->zip_fd, $v_size - $v_maximum_size);
            if (@ftell($this->zip_fd) != $v_size - $v_maximum_size) {
                // ----- Error log
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\'');
                // ----- Return
                return PclZip::errorCode();
            }
            // ----- Read byte per byte in order to find the signature
            $v_pos = ftell($this->zip_fd);
            $v_bytes = 0x0;
            while ($v_pos < $v_size) {
                // ----- Read a byte
                $v_byte = @fread($this->zip_fd, 1);
                // -----  Add the byte
                //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
                // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
                // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
                $v_bytes = ($v_bytes & 0xffffff) << 8 | Ord($v_byte);
                // ----- Compare the bytes
                if ($v_bytes == 0x504b0506) {
                    $v_pos++;
                    break;
                }
                $v_pos++;
            }
            // ----- Look if not found end of central dir
            if ($v_pos == $v_size) {
                // ----- Error log
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to find End of Central Dir Record signature');
                // ----- Return
                return PclZip::errorCode();
            }
        }
        // ----- Read the first 18 bytes of the header
        $v_binary_data = fread($this->zip_fd, 18);
        // ----- Look for invalid block size
        if (strlen($v_binary_data) != 18) {
            // ----- Error log
            PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid End of Central Dir Record size : ' . strlen($v_binary_data));
            // ----- Return
            return PclZip::errorCode();
        }
        // ----- Extract the values
        $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
        // ----- Check the global size
        if ($v_pos + $v_data['comment_size'] + 18 != $v_size) {
            // ----- Removed in release 2.2 see readme file
            // The check of the file size is a little too strict.
            // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
            // While decrypted, zip has training 0 bytes
            if (0) {
                // ----- Error log
                PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'The central dir is not at the end of the archive.' . ' Some trailing bytes exists after the archive.');
                // ----- Return
                return PclZip::errorCode();
            }
        }
        // ----- Get comment
        if ($v_data['comment_size'] != 0) {
            $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
        } else {
            $p_central_dir['comment'] = '';
        }
        $p_central_dir['entries'] = $v_data['entries'];
        $p_central_dir['disk_entries'] = $v_data['disk_entries'];
        $p_central_dir['offset'] = $v_data['offset'];
        $p_central_dir['size'] = $v_data['size'];
        $p_central_dir['disk'] = $v_data['disk'];
        $p_central_dir['disk_start'] = $v_data['disk_start'];
        // TBC
        //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
        //}
        // ----- Return
        return $v_result;
    }