⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unzipfile.cpp

📁 一个使用zlib进行压缩和解压的程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
								uDoCopy);

			uf.pfile_in_zip_read->rest_read_uncompressed-=uDoCopy;
			uf.pfile_in_zip_read->stream.avail_in -= uDoCopy;
			uf.pfile_in_zip_read->stream.avail_out -= uDoCopy;
			uf.pfile_in_zip_read->stream.next_out += uDoCopy;
			uf.pfile_in_zip_read->stream.next_in += uDoCopy;
            uf.pfile_in_zip_read->stream.total_out += uDoCopy;
			iRead += uDoCopy;
		}
		else
		{
			uLong uTotalOutBefore = uf.pfile_in_zip_read->stream.total_out;
			const Bytef *bufBefore = uf.pfile_in_zip_read->stream.next_out;
			int flush=Z_SYNC_FLUSH;

			/*
			if ((uf.pfile_in_zip_read->rest_read_uncompressed ==
			         uf.pfile_in_zip_read->stream.avail_out) &&
				(uf.pfile_in_zip_read->rest_read_compressed == 0))
				flush = Z_FINISH;
			*/
			int err = inflate(&uf.pfile_in_zip_read->stream,flush);

			uLong uTotalOutAfter = uf.pfile_in_zip_read->stream.total_out;
			uLong uOutThis = uTotalOutAfter-uTotalOutBefore;
			
			uf.pfile_in_zip_read->crc32 = 
                crc32(uf.pfile_in_zip_read->crc32,bufBefore,
                        (uInt)(uOutThis));

			uf.pfile_in_zip_read->rest_read_uncompressed -=
                uOutThis;

			iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
            
			if (err==Z_STREAM_END)
				return iRead;

			CheckForError(err);
		}
	}

	return iRead;
}

/*
  Read extra field from the current file (opened by OpenCurrentFile)
  This is the local-header version of the extra field (sometimes, there is
    more info in the local-header version than in the central-header)

  if buf==NULL, it return the size of the local extra field that can be read

  if buf!=NULL, len is the size of the buffer, the extra header is copied in
	buf.
  the return value is the number of bytes copied in buf
*/
int CUnzipFile::GetLocalExtrafield (void* buf, UINT len)
{
	if (!uf.pfile_in_zip_read)
		ThrowError(UNZ_PARAMERROR);


	uLong size_to_read = (uf.pfile_in_zip_read->size_local_extrafield - 
				uf.pfile_in_zip_read->pos_local_extrafield);

	if (!buf)
		return (int)size_to_read;
	
	uInt read_now;

	if (len>size_to_read)
		read_now = (uInt)size_to_read;
	else
		read_now = (uInt)len ;

	if (!read_now)
		return 0;

	
	uf.file.Seek(uf.pfile_in_zip_read->offset_local_extrafield + 
			  uf.pfile_in_zip_read->pos_local_extrafield, CFile::begin);


	return (int)uf.file.Read(buf, read_now);
}
/*
  Get the global comment string of the ZipFile, in the szComment buffer.
  uSizeBuf is the size of the szComment buffer.
  return the number of byte copied
*/
int CUnzipFile::GetGlobalComment (char* szComment, uLong uSizeBuf)
{

	uLong uReadThis = uSizeBuf;
	if (uReadThis > uf.gi.size_comment)
		uReadThis = uf.gi.size_comment;

	uf.file.Seek(uf.central_pos+22, CFile::begin);

	if (uReadThis)
    {
      *szComment = '\0';
	  uReadThis = uf.file.Read(szComment, (uInt)uReadThis);
    }

	if (szComment && (uSizeBuf > uf.gi.size_comment))
		*(szComment+uf.gi.size_comment)='\0';

	return (int)uReadThis;
}

/*
  Give the current position in uncompressed data
*/
z_off_t CUnzipFile::tell()
{
	if (!uf.pfile_in_zip_read)
		ThrowError(UNZ_PARAMERROR);

	return (z_off_t)uf.pfile_in_zip_read->stream.total_out;
}


/*
  return true if the end of file was reached, false elsewhere 
*/
bool CUnzipFile::eof()
{

	if (!uf.pfile_in_zip_read)
		ThrowError(UNZ_PARAMERROR);
	
	return uf.pfile_in_zip_read->rest_read_uncompressed == 0;
}

CUnzipFile::~CUnzipFile()
{
// 	Close(); // cannot be here: if an exception is thrown strange things can happen

}

void CUnzipFile::unzlocal_getByte(int & pi)
{

    unsigned char c;
	uf.file.Read(&c, 1);
	pi = (int)c;
    
}

void CUnzipFile::unzlocal_getShort (uLong & pX)
{
    int i;

    unzlocal_getByte(i);
    uLong x = (uLong)i;
    unzlocal_getByte(i);
    x += ((uLong)i)<<8;
   
	pX = x;
}

void CUnzipFile::unzlocal_getLong (uLong & pX)
{
	

	uLong x;
	unzlocal_getShort(x);
	uLong y;
	unzlocal_getShort(y);
	x += y << 16;
    pX = x;
}

//    Compare two filename (fileName1,fileName2).
int CUnzipFile::StringFileNameCompare(CString fileName1, CString fileName2, bool caseSensitive)
{
	return caseSensitive ? fileName1.Collate(fileName2) : 	fileName1.CollateNoCase(fileName2);
}

/*
  Locate the Central directory of a zipfile (at the end, just before
    the global comment)
*/
uLong CUnzipFile::unzlocal_SearchCentralDir()
{
	
	uLong uMaxBack=0xffff; /* maximum size of global comment */

	uLong uSizeFile = uf.file.GetLength();

	if (uMaxBack > uSizeFile)
		uMaxBack = uSizeFile;

	char* buf = new char[BUFREADCOMMENT + 4];

	uLong uBackRead = 4;
	uLong uPosFound = 0;

	try
	{
		while ((uBackRead < uMaxBack) && !uPosFound)
		{
			uLong uReadSize,uReadPos ;

			if (uBackRead + BUFREADCOMMENT > uMaxBack) 
				uBackRead = uMaxBack;
			else
				uBackRead += BUFREADCOMMENT;

			uReadPos = uSizeFile - uBackRead ;
			
			uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? 
						 (BUFREADCOMMENT + 4) : (uSizeFile - uReadPos);

			uf.file.Seek(uReadPos, CFile::begin);
			uf.file.Read(buf, uReadSize);

			for (int i= (int)uReadSize - 3; (i--) > 0 ;)
				if (((*(buf+i)) == 0x50) && ((*(buf+i+1))==0x4b) && 
					((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
				{
					uPosFound = uReadPos + i;
					break;
				}

		}
	}
	catch (CException*)
	{
		delete[] buf;
		throw;
	}
	delete[] buf;

	if (!uPosFound)
		ThrowError(UNZ_BADZIPFILE);

	return uPosFound;
	
}

/*
   Translate date/time from Dos format to tm_unz (readable more easilty)
*/
void CUnzipFile::unzlocal_DosDateToTmuDate(unz_file_info &file_info)
{
	CTime t(HIWORD(file_info.dosDate), LOWORD(file_info.dosDate));
	file_info.tmu_date = t;
}


/*
  Get Info about the current file in the zipfile, with internal only info
*/
void CUnzipFile::unzlocal_GetCurrentFileInfoInternal( unz_file_info & file_info,
                                         unz_file_info_internal & file_info_internal,
                                         LPSTR szFileName,
										 uLong fileNameBufferSize,
										 void *extraField,
										 uLong extraFieldBufferSize,
										 LPSTR szComment,
										 uLong commentBufferSize)
{

	
	uf.file.Seek(uf.pos_in_central_dir + uf.byte_before_the_zipfile, CFile::begin);
	
	uLong uMagic;

	/* we check the magic */
	unzlocal_getLong(uMagic);
	if (uMagic != 0x02014b50)
		ThrowError(UNZ_BADZIPFILE);

	unzlocal_getShort(file_info.version);
	unzlocal_getShort(file_info.version_needed);
	unzlocal_getShort(file_info.flag);
	unzlocal_getShort(file_info.compression_method);
	unzlocal_getLong(file_info.dosDate);

    unzlocal_DosDateToTmuDate(file_info);

	unzlocal_getLong(file_info.crc);
	unzlocal_getLong(file_info.compressed_size);
	unzlocal_getLong(file_info.uncompressed_size);
	unzlocal_getShort(file_info.size_filename);
	unzlocal_getShort(file_info.size_file_extra);
	unzlocal_getShort(file_info.size_file_comment);
	unzlocal_getShort(file_info.disk_num_start);
	unzlocal_getShort(file_info.internal_fa);
	unzlocal_getLong(file_info.external_fa);
	unzlocal_getLong(file_info_internal.offset_curfile);

	uLong lSeek = file_info.size_filename;

	if (szFileName)
	{
		uLong uSizeRead ;
		if (file_info.size_filename < fileNameBufferSize)
		{
			*(szFileName + file_info.size_filename) = '\0';
			uSizeRead = file_info.size_filename;
		}
		else
			uSizeRead = fileNameBufferSize;

		if ((file_info.size_filename>0) && (fileNameBufferSize>0))
			uf.file.Read(szFileName, uSizeRead);

		lSeek -= uSizeRead;
	}

	
	if (extraField)
	{
		uLong uSizeRead ;
		if (file_info.size_file_extra < extraFieldBufferSize)
			uSizeRead = file_info.size_file_extra;
		else
			uSizeRead = extraFieldBufferSize;

		if (lSeek != 0)
		{
			uf.file.Seek(lSeek, CFile::begin);
			lSeek=0;
		}
		
		if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
			uf.file.Read(extraField, uSizeRead);

		lSeek += file_info.size_file_extra - uSizeRead;
	}
	else
		lSeek+=file_info.size_file_extra; 

	
	if (szComment)
	{
		uLong uSizeRead ;

		if (file_info.size_file_comment<commentBufferSize)
		{
			*(szComment+file_info.size_file_comment)='\0';
			uSizeRead = file_info.size_file_comment;
		}
		else
			uSizeRead = commentBufferSize;

		if (lSeek != 0)
		{
			uf.file.Seek(lSeek, CFile::begin);
			lSeek=0;
		}

		if ((file_info.size_file_comment>0) && (commentBufferSize>0))
			uf.file.Read(szComment, uSizeRead);
			
		lSeek+=file_info.size_file_comment - uSizeRead;
	}
	else
		lSeek+=file_info.size_file_comment;

}


void CUnzipFile::Open(LPCTSTR lpszPath)
{
	if (!IsClosed())
		return;

	CFileException* e = new CFileException;
	if (!uf.file.Open(lpszPath, CFile::modeRead | CFile::shareDenyWrite, e))
		throw e;
	e->Delete();

	uLong central_pos = unzlocal_SearchCentralDir();

	uf.file.Seek(central_pos, CFile::begin);

	/* the signature, already checked */
	uLong uL;
	unzlocal_getLong(uL);

	uLong number_disk;          /* number of the current dist, used for 
								   spaning ZIP, unsupported, always 0*/
	unzlocal_getShort(number_disk);

	uLong number_disk_with_CD;  /* number the the disk with central dir, used
								   for spaning ZIP, unsupported, always 0*/
	unzlocal_getShort(number_disk_with_CD);

	/* number of the disk with the start of the central directory */
	unzlocal_getShort(uf.gi.number_entry);


	uLong number_entry_CD;      /* total number of entries in
	                               the central dir 
	                               (same than number_entry on nospan) */
	unzlocal_getShort(number_entry_CD);

	
	if ( (number_entry_CD != uf.gi.number_entry) ||
		(number_disk_with_CD != 0) ||
		(number_disk != 0))
			ThrowError(UNZ_BADZIPFILE);

	/* size of the central directory */
	unzlocal_getLong(uf.size_central_dir);

	/* offset of start of central directory with respect to the 
	      starting disk number */
	unzlocal_getLong(uf.offset_central_dir);

	/* zipfile comment length */
	unzlocal_getShort(uf.gi.size_comment);

	if ( central_pos < uf.offset_central_dir + uf.size_central_dir)
		ThrowError(UNZ_BADZIPFILE);


	uf.byte_before_the_zipfile = central_pos -
		(uf.offset_central_dir + uf.size_central_dir);

	uf.central_pos = central_pos;
	
	GoToFirstFile();	

}

void CUnzipFile::UpdateFileStatus(CFile &f, unz_file_info &ui)
{
	CString s = f.GetFilePath();
	f.Close();
	CFileStatus fs;
	fs.m_ctime = fs.m_atime = CTime::GetCurrentTime();
	fs.m_attribute = 0;
	fs.m_mtime = ui.tmu_date;
	CFile::SetStatus(s, fs);
	SetFileAttributes(s, ui.external_fa);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -