163 lines
3.9 KiB
C++
163 lines
3.9 KiB
C++
typedef const char * LPCSTR;
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <memory.h>
|
|
#include "7zip.h"
|
|
|
|
C7zip::C7zip (LPCSTR FileName) :
|
|
m_blockIndex(0xFFFFFFFF),
|
|
m_outBuffer(0),
|
|
m_outBufferSize(0),
|
|
NotfyCallback(NotfyCallbackDefault),
|
|
NotfyCallbackInfo(NULL),
|
|
m_FileSize(0),
|
|
m_CurrentFile(-1)
|
|
|
|
{
|
|
memset(&m_db,0,sizeof(m_db));
|
|
|
|
m_archiveStream.InStream.Read = SzFileReadImp;
|
|
m_archiveStream.InStream.Seek = SzFileSeekImp;
|
|
|
|
m_allocImp.Alloc = SzAlloc;
|
|
m_allocImp.Free = SzFree;
|
|
|
|
m_allocTempImp.Alloc = SzAllocTemp;
|
|
m_allocTempImp.Free = SzFreeTemp;
|
|
|
|
m_archiveStream.File = fopen(FileName, "rb");
|
|
if (m_archiveStream.File == 0)
|
|
{
|
|
//PrintError("can not open input file");
|
|
return;
|
|
}
|
|
fseek(m_archiveStream.File, 0, SEEK_END);
|
|
m_FileSize = ftell(m_archiveStream.File);
|
|
fseek(m_archiveStream.File, 0, SEEK_SET);
|
|
|
|
char drive[_MAX_DRIVE] ,dir[_MAX_DIR], ext[_MAX_EXT];
|
|
_splitpath( FileName, drive, dir, m_FileName, ext );
|
|
|
|
InitCrcTable();
|
|
SzArDbExInit(&m_db);
|
|
SZ_RESULT res = SzArchiveOpen(&m_archiveStream.InStream, &m_db, &m_allocImp, &m_allocTempImp);
|
|
|
|
}
|
|
|
|
C7zip::~C7zip (void)
|
|
{
|
|
SetNotificationCallback(NULL,NULL);
|
|
SzArDbExFree(&m_db, m_allocImp.Free);
|
|
|
|
if (m_archiveStream.File)
|
|
{
|
|
fclose(m_archiveStream.File);
|
|
}
|
|
if (m_outBuffer)
|
|
{
|
|
m_allocImp.Free(m_outBuffer);
|
|
}
|
|
}
|
|
|
|
void C7zip::SetNotificationCallback (LP7ZNOTIFICATION NotfyFnc, void * CBInfo)
|
|
{
|
|
NotfyCallback = NotfyFnc ? NotfyFnc : NotfyCallbackDefault;
|
|
NotfyCallbackInfo = CBInfo;
|
|
}
|
|
|
|
void C7zip::StatusUpdate(_7Z_STATUS status, int Value1, int Value2, C7zip * _this )
|
|
{
|
|
CFileItem * File = _this->m_CurrentFile >= 0 ? _this->FileItem(_this->m_CurrentFile) : NULL;
|
|
|
|
switch (status)
|
|
{
|
|
case LZMADECODE_START: _this->NotfyCallback("Start decoding",_this->NotfyCallbackInfo); break;
|
|
case LZMADECODE_UPDATE:
|
|
{
|
|
char Msg[200];
|
|
sprintf(Msg,"decoding %s: %0.2f%%",File->Name, (Value1/(float)Value2) * 100);
|
|
_this->NotfyCallback(Msg,_this->NotfyCallbackInfo);
|
|
}
|
|
break;
|
|
case LZMADECODE_DONE: _this->NotfyCallback("Finished decoding",_this->NotfyCallbackInfo); break;
|
|
}
|
|
}
|
|
|
|
bool C7zip::GetFile(int index, Byte * Data, size_t DataLen )
|
|
{
|
|
m_CurrentFile = -1;
|
|
if (Data == NULL || DataLen == 0)
|
|
{
|
|
return false;
|
|
}
|
|
if (m_archiveStream.File == 0)
|
|
{
|
|
return false;
|
|
}
|
|
m_CurrentFile = index;
|
|
|
|
SZ_RESULT res;
|
|
size_t offset;
|
|
size_t outSizeProcessed;
|
|
|
|
char Msg[200];
|
|
CFileItem * f = FileItem(index);
|
|
sprintf(Msg,"Getting %s",f->Name);
|
|
NotfyCallback(Msg,NotfyCallbackInfo);
|
|
|
|
res = SzExtract(&m_archiveStream.InStream, &m_db, index,
|
|
&m_blockIndex, &m_outBuffer, &m_outBufferSize,
|
|
&offset, &outSizeProcessed,
|
|
&m_allocImp, &m_allocTempImp,(LP7ZSTATUS_UPDATE)StatusUpdate, this);
|
|
if (res != SZ_OK)
|
|
{
|
|
m_CurrentFile = -1;
|
|
return false;
|
|
}
|
|
|
|
if (DataLen < outSizeProcessed)
|
|
{
|
|
outSizeProcessed = DataLen;
|
|
}
|
|
memcpy(Data,m_outBuffer + offset,outSizeProcessed);
|
|
NotfyCallback("",NotfyCallbackInfo);
|
|
m_CurrentFile = -1;
|
|
return true;
|
|
}
|
|
|
|
SZ_RESULT C7zip::SzFileReadImp(void *object, void *buffer, size_t size, size_t *processedSize)
|
|
{
|
|
CFileInStream *s = (CFileInStream *)object;
|
|
size_t processedSizeLoc = fread(buffer, 1, size, s->File);
|
|
if (processedSize != 0)
|
|
*processedSize = processedSizeLoc;
|
|
return SZ_OK;
|
|
}
|
|
|
|
SZ_RESULT C7zip::SzFileSeekImp(void *object, CFileSize pos)
|
|
{
|
|
CFileInStream *s = (CFileInStream *)object;
|
|
int res = fseek(s->File, (long)pos, SEEK_SET);
|
|
if (res == 0)
|
|
return SZ_OK;
|
|
return SZE_FAIL;
|
|
}
|
|
|
|
char * C7zip::FileName ( char * FileName, int SizeOfFileName ) const
|
|
{
|
|
if (FileName == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
int Len = strlen(m_FileName);
|
|
if (Len > (SizeOfFileName - 1))
|
|
{
|
|
Len = (SizeOfFileName - 1);
|
|
}
|
|
strncpy(FileName,m_FileName,Len);
|
|
FileName[Len] = 0;
|
|
return FileName;
|
|
}
|