|
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <io.h>
#include "unzip/zip.h"
#include "unzip/unzip.h"
class Zip
{
public:
Zip(){_handle=NULL;}
~Zip(){close();}
public:
bool open(const char* lpszFilePath, bool bAppend = false, const char** globalcomment = NULL, zlib_filefunc_def* pzlib_filefunc_def = NULL)
{
if(is_open()) close();
_handle = ::zipOpen2(lpszFilePath, bAppend, globalcomment, pzlib_filefunc_def);
return (_handle != NULL);
}
void close()
{
if(!is_open()) return;
::zipClose(_handle, NULL);
_handle=NULL;
}
bool add_new(FILE* file,
const char* filenameinzip,
void* buf,
size_t buf_size,
const char* comment = NULL,
int level = Z_BEST_COMPRESSION,
int method = Z_DEFLATED,
const void* extrafield_local = NULL,
uInt size_extrafield_local = 0,
const void* extrafield_global = NULL,
uInt size_extrafield_global = 0
)
{
zip_fileinfo zi;
memset(&zi, 0, sizeof(zi));
bool bOK = (buf_size != 0) && filetime(file,&zi.tmz_date,&zi.dosDate);
if (bOK)
{
bOK = open_new(filenameinzip, &zi, comment, level, method, extrafield_local,
size_extrafield_local, extrafield_global, size_extrafield_global);
}
if (bOK)
{
for (unsigned int size_read;;)
{
size_read = (unsigned int)fread(buf, 1, buf_size, file);
if (size_read == 0)
{
break;
}
if (!write_new(buf,size_read))
{
break;
}
}
bOK = close_new();
}
return bOK;
}
bool is_open(void) const
{
return (_handle!=NULL);
}
private:
bool open_new(const char* filename,
const zip_fileinfo* zipfi,
const char* comment = NULL,
int level = Z_BEST_COMPRESSION,
int method = Z_DEFLATED,
const void* extrafield_local = NULL,
uInt size_extrafield_local = 0,
const void* extrafield_global = NULL,
uInt size_extrafield_global = 0
)
{
return (ZIP_OK == ::zipOpenNewFileInZip(_handle, filename, zipfi, extrafield_local, size_extrafield_local,
extrafield_global, size_extrafield_global, comment,
(level != 0) ? method : 0,
level));
}
bool write_new(const voidp p, unsigned int len)
{
if(_handle==NULL) return false;
return (::zipWriteInFileInZip(_handle, p, len) >= 0);
}
bool close_new()
{
if(_handle==NULL) return false;
return (ZIP_OK == ::zipCloseFileInZip(_handle));
}
// Implementation
private:
zipFile _handle;
protected:
static bool filetime(const char *f, tm_zip* tmzip, unsigned long* dt)
{
WIN32_FIND_DATA ff32;
HANDLE handle = ::FindFirstFile(f,&ff32);
bool bOK = (handle != INVALID_HANDLE_VALUE);
if (bOK)
{
FILETIME ftLocal;
::FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
::FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
::FindClose(handle);
}
return bOK;
}
static bool filetime(FILE* file , tm_zip* tmzip, unsigned long* dt)
{
FILETIME ftModify;
bool bOK = (::GetFileTime((HANDLE)_get_osfhandle((int)_fileno(file)), NULL, NULL, &ftModify)==TRUE);
if (bOK)
{
FILETIME ftLocal;
FileTimeToLocalFileTime(&ftModify,&ftLocal);
FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
}
return bOK;
}
};
class Unzip
{
public:
Unzip(){_handle=NULL;}
~Unzip(){}
operator unzFile(void);
public:
bool open(const char* lpszFilePath, zlib_filefunc_def* def = NULL)
{
if(is_open()) close();
_handle = ::unzOpen2(lpszFilePath, def);
return (_handle != NULL);
}
bool is_open(void) const{return _handle!=NULL;}
void close()
{
if(_handle==NULL) return;
::unzClose(_handle);
_handle = NULL;
}
bool get_global_info(unz_global_info *p) const
{
if(!is_open()) return false;
return (UNZ_OK == ::unzGetGlobalInfo(_handle, p));
}
int get_global_count(void) const
{
if(!is_open()) return 0;
unz_global_info info;
return (::unzGetGlobalInfo(_handle, &info) == UNZ_OK) ? info.number_entry : 0;
}
bool get_global_comment(char *szComment, uLong uSizeBuf) const
{
if(!is_open()) return false;
return (UNZ_OK == ::unzGetGlobalComment(_handle, szComment, uSizeBuf));
}
bool goto_first_file(void)
{
if(!is_open()) return false;
return (UNZ_OK == ::unzGoToFirstFile(_handle));
}
bool goto_next_file(void)
{
if(!is_open()) return false;
return (UNZ_OK == ::unzGoToNextFile(_handle));
}
bool get_current_file_info(unz_file_info *pfile_info,
char *szFileName = NULL,
uLong fileNameBufferSize = 0,
void *extraField = NULL,
uLong extraFieldBufferSize = 0,
char *szComment = NULL,
uLong commentBufferSize = 0) const
{
if(!is_open()) return false;
return (UNZ_OK == ::unzGetCurrentFileInfo(_handle,
pfile_info,
szFileName,
fileNameBufferSize,
extraField,
extraFieldBufferSize,
szComment,
commentBufferSize));
}
bool open_current_file(const char* password = NULL)
{
if(!is_open()) return false;
return (UNZ_OK == ::unzOpenCurrentFilePassword(_handle, password));
}
int read_current_file(voidp buf, unsigned int len)
{
if(!is_open()) return 0;
return ::unzReadCurrentFile(_handle, buf, len);
}
bool extract_current_file(FILE* file, void* buf, size_t size_buf)
{
for (bool bOK = true; bOK; )
{
int bytes = read_current_file(buf,(unsigned int)size_buf);
if (bytes < 0)
{
bOK = false;
}
else if (bytes > 0)
{
if (fwrite(buf,bytes,1,file)!=1)
{
bOK = false;
}
}
else
{
break;
}
}
return bOK;
}
bool close_current_file()
{
if(!is_open()) return false;
return (UNZ_OK == ::unzCloseCurrentFile(_handle));
}
bool attach(unzFile uf)
{
if(is_open()) return false;
_handle=uf;
return _handle!=NULL;
}
unzFile detach(void)
{
unzFile ret=_handle;
_handle=NULL;
return ret;
}
static bool change_file_date(LPCTSTR filename,uLong dosdate,tm_unz tmu_date)
{
HANDLE hFile = CreateFile(filename,GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0,NULL);
bool bOK = (hFile != INVALID_HANDLE_VALUE);
if (bOK)
{
FILETIME ftm,ftLocal,ftLastAcc;
bOK = (GetFileTime(hFile,NULL,&ftLastAcc,NULL)==TRUE);
DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
LocalFileTimeToFileTime(&ftLocal,&ftm);
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
CloseHandle(hFile);
}
return bOK;
}
private:
unzFile _handle;
}; |
|