archive7zip.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 168 行
CPP
168 行
#include "StdAfx.h"
#include "Archive7Zip.h"
#include <algorithm>
#include <string.h>
#include "mmgr.h"
// Most of this code is taken from 7zMain.c
SZ_RESULT 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 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;
}
CArchive7Zip::CArchive7Zip(const string& name) :
CArchiveBuffered(name),
curSearchHandle(1),
isOpen(false)
{
SZ_RESULT res;
archiveStream.File = fopen(name.c_str(), "rb");
if (archiveStream.File == 0)
return;
archiveStream.InStream.Read = SzFileReadImp;
archiveStream.InStream.Seek = SzFileSeekImp;
allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree;
allocTempImp.Alloc = SzAllocTemp;
allocTempImp.Free = SzFreeTemp;
InitCrcTable();
SzArDbExInit(&db);
res = SzArchiveOpen(&archiveStream.InStream, &db, &allocImp, &allocTempImp);
if (res != SZ_OK)
return;
isOpen = true;
// Get contents of archive and store name->int mapping
for (unsigned i = 0; i < db.Database.NumFiles; ++i) {
CFileItem* fi = db.Database.Files + i;
if (fi->Size > 0) {
string name = fi->Name;
//SetSlashesForwardToBack(name);
FileData fd;
fd.origName = name;
fd.fp = i;
fd.size = fi->Size;
fd.crc = fi->FileCRC;
StringToLowerInPlace(name);
fileData[name] = fd;
}
}
}
CArchive7Zip::~CArchive7Zip(void)
{
if (archiveStream.File) {
SzArDbExFree(&db, allocImp.Free);
fclose(archiveStream.File);
}
}
unsigned int CArchive7Zip::GetCrc32 (const string& fileName)
{
string lower = StringToLower(fileName);
FileData fd = fileData[lower];
return fd.crc;
}
ABOpenFile_t* CArchive7Zip::GetEntireFile(const string& fName)
{
if (!isOpen)
return NULL;
// Figure out the file index
string fileName = StringToLower(fName);
if (fileData.find(fileName) == fileData.end())
return NULL;
FileData fd = fileData[fileName];
// Get 7zip to decompress it
size_t offset;
size_t outSizeProcessed;
SZ_RESULT res;
// We don't really support solid archives anyway, so these can be reset for each file
UInt32 blockIndex = 0xFFFFFFFF; // it can have any value before first call (if outBuffer = 0)
Byte *outBuffer = 0; // it must be 0 before first call for each new archive.
size_t outBufferSize = 0; // it can have any value before first call (if outBuffer = 0)
res = SzExtract(&archiveStream.InStream, &db, fd.fp,
&blockIndex, &outBuffer, &outBufferSize,
&offset, &outSizeProcessed,
&allocImp, &allocTempImp);
ABOpenFile_t* of = NULL;
if (res == SZ_OK) {
of = SAFE_NEW ABOpenFile_t;
of->pos = 0;
of->size = outSizeProcessed;
of->data = (char*)malloc(of->size);
memcpy(of->data, outBuffer + offset, outSizeProcessed);
}
allocImp.Free(outBuffer);
if (res != SZ_OK)
return NULL;
return of;
}
void CArchive7Zip::SetSlashesForwardToBack(string& name)
{
for (unsigned int i = 0; i < name.length(); ++i) {
if (name[i] == '/')
name[i] = '\\';
}
}
int CArchive7Zip::FindFiles(int cur, string* name, int* size)
{
if (cur == 0) {
curSearchHandle++;
cur = curSearchHandle;
searchHandles[cur] = fileData.begin();
}
if (searchHandles[cur] == fileData.end()) {
searchHandles.erase(cur);
return 0;
}
*name = searchHandles[cur]->second.origName;
*size = searchHandles[cur]->second.size;
searchHandles[cur]++;
return cur;
}
bool CArchive7Zip::IsOpen()
{
return isOpen;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?