Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
162
Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp
Normal file
162
Src/external_dependencies/openmpt-trunk/unarchiver/unlha.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* unlha.cpp
|
||||
* ---------
|
||||
* Purpose: Implementation file for extracting modules from .lha archives, making use of lhasa
|
||||
* Notes : (currently none)
|
||||
* Authors: OpenMPT Devs
|
||||
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "unlha.h"
|
||||
|
||||
#ifdef MPT_WITH_LHASA
|
||||
#include "lhasa.h"
|
||||
#endif // MPT_WITH_LHASA
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
#ifdef MPT_WITH_LHASA
|
||||
|
||||
|
||||
static int LHAreadFileReader(void *handle, void *buf, size_t buf_len)
|
||||
{
|
||||
FileReader *f = reinterpret_cast<FileReader*>(handle);
|
||||
int read_len = mpt::saturate_cast<int>(buf_len);
|
||||
int result = mpt::saturate_cast<int>(f->ReadRaw(mpt::span(mpt::void_cast<std::byte*>(buf), read_len)).size());
|
||||
if(result == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int LHAskipFileReader(void *handle, size_t bytes)
|
||||
{
|
||||
FileReader *f = reinterpret_cast<FileReader*>(handle);
|
||||
if(f->CanRead(bytes))
|
||||
{
|
||||
f->Skip(bytes);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LHAcloseFileReader(void * /*handle*/)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static LHAInputStreamType vtable =
|
||||
{
|
||||
LHAreadFileReader,
|
||||
LHAskipFileReader,
|
||||
LHAcloseFileReader
|
||||
};
|
||||
|
||||
|
||||
CLhaArchive::CLhaArchive(FileReader &file) : ArchiveBase(file), inputstream(nullptr), reader(nullptr), firstfile(nullptr)
|
||||
{
|
||||
OpenArchive();
|
||||
for(LHAFileHeader *fileheader = firstfile; fileheader; fileheader = lha_reader_next_file(reader))
|
||||
{
|
||||
ArchiveFileInfo info;
|
||||
info.name = mpt::PathString::FromUnicode(mpt::ToUnicode(mpt::Charset::Amiga_no_C1, fileheader->filename));
|
||||
info.size = fileheader->length;
|
||||
info.type = ArchiveFileType::Normal;
|
||||
contents.push_back(info);
|
||||
}
|
||||
CloseArchive();
|
||||
}
|
||||
|
||||
|
||||
CLhaArchive::~CLhaArchive()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void CLhaArchive::OpenArchive()
|
||||
{
|
||||
inFile.Rewind();
|
||||
inputstream = lha_input_stream_new(&vtable, &inFile);
|
||||
if(inputstream)
|
||||
{
|
||||
reader = lha_reader_new(inputstream);
|
||||
}
|
||||
if(reader)
|
||||
{
|
||||
lha_reader_set_dir_policy(reader, LHA_READER_DIR_END_OF_DIR);
|
||||
firstfile = lha_reader_next_file(reader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CLhaArchive::CloseArchive()
|
||||
{
|
||||
if(reader)
|
||||
{
|
||||
lha_reader_free(reader);
|
||||
reader = nullptr;
|
||||
}
|
||||
if(inputstream)
|
||||
{
|
||||
lha_input_stream_free(inputstream);
|
||||
inputstream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool CLhaArchive::ExtractFile(std::size_t index)
|
||||
{
|
||||
if(index >= contents.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
data.clear();
|
||||
OpenArchive();
|
||||
const std::size_t bufSize = 4096;
|
||||
std::size_t i = 0;
|
||||
for(LHAFileHeader *fileheader = firstfile; fileheader; fileheader = lha_reader_next_file(reader))
|
||||
{
|
||||
if(index == i)
|
||||
{
|
||||
data.clear();
|
||||
std::size_t countRead = 0;
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
data.resize(data.size() + bufSize);
|
||||
} catch(...)
|
||||
{
|
||||
CloseArchive();
|
||||
return false;
|
||||
}
|
||||
countRead = lha_reader_read(reader, &data[data.size() - bufSize], bufSize);
|
||||
if(countRead < bufSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
data.resize(data.size() - (bufSize - countRead));
|
||||
} catch(...)
|
||||
{
|
||||
CloseArchive();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} while(countRead > 0);
|
||||
}
|
||||
++i;
|
||||
}
|
||||
CloseArchive();
|
||||
return data.size() > 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // MPT_WITH_LHASA
|
||||
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue