Mesen-SX/Utilities/SZReader.cpp

101 lines
2.2 KiB
C++
Raw Normal View History

2019-02-13 14:10:36 -05:00
#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)
{
2020-12-19 23:32:47 +03:00
if (_initialized)
{
2019-02-13 14:10:36 -05:00
SzArEx_Free(&_archive, &_allocImp);
_initialized = false;
}
2020-12-19 23:32:47 +03:00
ISzAlloc allocImp{SzAlloc, SzFree};
ISzAlloc allocTempImp{SzAllocTemp, SzFreeTemp};
2019-02-13 14:10:36 -05:00
MemBufferInit(&_memBufferStream, &_lookStream, buffer, size);
CrcGenerateTable();
SzArEx_Init(&_archive);
return !SzArEx_Open(&_archive, &_lookStream.s, &allocImp, &allocTempImp);
}
2020-12-19 23:32:47 +03:00
bool SZReader::ExtractFile(string filename, vector<uint8_t>& output)
2019-02-13 14:10:36 -05:00
{
bool result = false;
2020-12-19 23:32:47 +03:00
if (_initialized)
{
char16_t* utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
2019-02-13 14:10:36 -05:00
uint32_t blockIndex = 0xFFFFFFFF;
2020-12-19 23:32:47 +03:00
uint8_t* outBuffer = 0;
2019-02-13 14:10:36 -05:00
size_t outBufferSize = 0;
2020-12-19 23:32:47 +03:00
for (uint32_t i = 0; i < _archive.NumFiles; i++)
{
2019-02-13 14:10:36 -05:00
size_t offset = 0;
size_t outSizeProcessed = 0;
unsigned isDir = SzArEx_IsDir(&_archive, i);
2020-12-19 23:32:47 +03:00
if (isDir)
{
2019-02-13 14:10:36 -05:00
continue;
}
SzArEx_GetFileNameUtf16(&_archive, i, (uint16_t*)utf16Filename);
string entryName = utf8::utf8::encode(std::u16string(utf16Filename));
2020-12-19 23:32:47 +03:00
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);
2019-02-13 14:10:36 -05:00
result = true;
}
IAlloc_Free(&_allocImp, outBuffer);
break;
}
}
SzFree(nullptr, utf16Filename);
}
return result;
}
vector<string> SZReader::InternalGetFileList()
{
vector<string> filenames;
2020-12-19 23:32:47 +03:00
char16_t* utf16Filename = (char16_t*)SzAlloc(nullptr, 2000);
2019-02-13 14:10:36 -05:00
2020-12-19 23:32:47 +03:00
if (_initialized)
{
for (uint32_t i = 0; i < _archive.NumFiles; i++)
{
2019-02-13 14:10:36 -05:00
unsigned isDir = SzArEx_IsDir(&_archive, i);
2020-12-19 23:32:47 +03:00
if (isDir)
{
2019-02-13 14:10:36 -05:00
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;
2020-12-19 23:32:47 +03:00
}