project64/Source/Project64/3rd Party/7zip.cpp

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;
}