Mesen/Utilities/SZReader.cpp
2017-08-06 11:55:23 -04:00

90 lines
2.2 KiB
C++

#include "stdafx.h"
#include <algorithm>
#include <cstring>
#include "SZReader.h"
#include "UTF8Util.h"
#include "../SevenZip/7zMemBuffer.h"
SZReader::SZReader()
{
}
SZReader::~SZReader()
{
SzArEx_Free(&_archive, &_allocImp);
}
bool SZReader::InternalLoadArchive(void* buffer, size_t size)
{
if(_initialized) {
SzArEx_Free(&_archive, &_allocImp);
_initialized = false;
}
ISzAlloc allocImp{ SzAlloc, SzFree };
ISzAlloc allocTempImp{ SzAllocTemp, SzFreeTemp };
MemBufferInit(&_memBufferStream, &_lookStream, buffer, size);
CrcGenerateTable();
SzArEx_Init(&_archive);
return !SzArEx_Open(&_archive, &_lookStream.s, &allocImp, &allocTempImp);
}
bool SZReader::ExtractFile(string filename, vector<uint8_t> &output)
{
bool result = false;
if(_initialized) {
char16_t *utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
uint32_t blockIndex = 0xFFFFFFFF;
uint8_t *outBuffer = 0;
size_t outBufferSize = 0;
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
size_t offset = 0;
size_t outSizeProcessed = 0;
unsigned isDir = SzArEx_IsDir(&_archive, i);
if(isDir) {
continue;
}
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
string entryName = utf8::utf8::encode(std::u16string(utf16Filename));
if(filename == entryName) {
WRes res = SzArEx_Extract(&_archive, &_lookStream.s, i, &blockIndex, &outBuffer, &outBufferSize, &offset, &outSizeProcessed, &_allocImp, &_allocTempImp);
if(res == SZ_OK) {
output = vector<uint8_t>(outBuffer+offset, outBuffer+offset+outSizeProcessed);
result = true;
}
IAlloc_Free(&_allocImp, outBuffer);
break;
}
}
SzFree(nullptr, utf16Filename);
}
return result;
}
vector<string> SZReader::InternalGetFileList()
{
vector<string> filenames;
char16_t *utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
if(_initialized) {
for(uint32_t i = 0; i < _archive.NumFiles; i++) {
unsigned isDir = SzArEx_IsDir(&_archive, i);
if(isDir) {
continue;
}
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
string filename = utf8::utf8::encode(std::u16string(utf16Filename));
filenames.push_back(filename);
}
}
SzFree(nullptr, utf16Filename);
return filenames;
}