174 lines
3.2 KiB
C++
174 lines
3.2 KiB
C++
|
/*
|
||
|
* unarchiver.cpp
|
||
|
* --------------
|
||
|
* Purpose: archive loader
|
||
|
* 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 "unarchiver.h"
|
||
|
#include "../common/FileReader.h"
|
||
|
|
||
|
|
||
|
OPENMPT_NAMESPACE_BEGIN
|
||
|
|
||
|
|
||
|
CUnarchiver::CUnarchiver(FileReader &file)
|
||
|
: impl(nullptr)
|
||
|
, inFile(file)
|
||
|
, emptyArchive(inFile)
|
||
|
#if (defined(MPT_WITH_ZLIB) && defined(MPT_WITH_MINIZIP)) || defined(MPT_WITH_MINIZ)
|
||
|
, zipArchive(inFile)
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_LHASA
|
||
|
, lhaArchive(inFile)
|
||
|
#endif
|
||
|
#if defined(MPT_WITH_ZLIB) || defined(MPT_WITH_MINIZ)
|
||
|
, gzipArchive(inFile)
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_UNRAR
|
||
|
, rarArchive(inFile)
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_ANCIENT
|
||
|
, ancientArchive(inFile)
|
||
|
#endif
|
||
|
{
|
||
|
inFile.Rewind();
|
||
|
#if (defined(MPT_WITH_ZLIB) && defined(MPT_WITH_MINIZIP)) || defined(MPT_WITH_MINIZ)
|
||
|
if(zipArchive.IsArchive()) { impl = &zipArchive; return; }
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_LHASA
|
||
|
if(lhaArchive.IsArchive()) { impl = &lhaArchive; return; }
|
||
|
#endif
|
||
|
#if defined(MPT_WITH_ZLIB) || defined(MPT_WITH_MINIZ)
|
||
|
if(gzipArchive.IsArchive()) { impl = &gzipArchive; return; }
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_UNRAR
|
||
|
if(rarArchive.IsArchive()) { impl = &rarArchive; return; }
|
||
|
#endif
|
||
|
#ifdef MPT_WITH_ANCIENT
|
||
|
if(ancientArchive.IsArchive()) { impl = &ancientArchive; return; }
|
||
|
#endif
|
||
|
impl = &emptyArchive;
|
||
|
}
|
||
|
|
||
|
|
||
|
CUnarchiver::~CUnarchiver()
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
static inline std::string GetExtension(const std::string &filename)
|
||
|
{
|
||
|
if(filename.find_last_of(".") != std::string::npos)
|
||
|
{
|
||
|
return mpt::ToLowerCaseAscii(filename.substr(filename.find_last_of(".") + 1));
|
||
|
}
|
||
|
return std::string();
|
||
|
}
|
||
|
|
||
|
|
||
|
std::size_t CUnarchiver::FindBestFile(const std::vector<const char *> &extensions)
|
||
|
{
|
||
|
if(!IsArchive())
|
||
|
{
|
||
|
return failIndex;
|
||
|
}
|
||
|
uint64 biggestSize = 0;
|
||
|
std::size_t bestIndex = failIndex;
|
||
|
for(std::size_t i = 0; i < size(); ++i)
|
||
|
{
|
||
|
if(operator[](i).type != ArchiveFileType::Normal)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
const std::string ext = GetExtension(operator[](i).name.ToUTF8());
|
||
|
|
||
|
if(ext == "diz" || ext == "nfo" || ext == "txt")
|
||
|
{
|
||
|
// we do not want these
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// Compare with list of preferred extensions
|
||
|
if(mpt::contains(extensions, ext))
|
||
|
{
|
||
|
bestIndex = i;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(operator[](i).size >= biggestSize)
|
||
|
{
|
||
|
biggestSize = operator[](i).size;
|
||
|
bestIndex = i;
|
||
|
}
|
||
|
}
|
||
|
return bestIndex;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CUnarchiver::ExtractBestFile(const std::vector<const char *> &extensions)
|
||
|
{
|
||
|
std::size_t bestFile = FindBestFile(extensions);
|
||
|
if(bestFile == failIndex)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
return ExtractFile(bestFile);
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CUnarchiver::IsArchive() const
|
||
|
{
|
||
|
return impl->IsArchive();
|
||
|
}
|
||
|
|
||
|
|
||
|
mpt::ustring CUnarchiver::GetComment() const
|
||
|
{
|
||
|
return impl->GetComment();
|
||
|
}
|
||
|
|
||
|
|
||
|
bool CUnarchiver::ExtractFile(std::size_t index)
|
||
|
{
|
||
|
return impl->ExtractFile(index);
|
||
|
}
|
||
|
|
||
|
|
||
|
FileReader CUnarchiver::GetOutputFile() const
|
||
|
{
|
||
|
return impl->GetOutputFile();
|
||
|
}
|
||
|
|
||
|
|
||
|
std::size_t CUnarchiver::size() const
|
||
|
{
|
||
|
return impl->size();
|
||
|
}
|
||
|
|
||
|
|
||
|
IArchive::const_iterator CUnarchiver::begin() const
|
||
|
{
|
||
|
return impl->begin();
|
||
|
}
|
||
|
|
||
|
|
||
|
IArchive::const_iterator CUnarchiver::end() const
|
||
|
{
|
||
|
return impl->end();
|
||
|
}
|
||
|
|
||
|
|
||
|
const ArchiveFileInfo & CUnarchiver::operator [] (std::size_t index) const
|
||
|
{
|
||
|
return impl->operator[](index);
|
||
|
}
|
||
|
|
||
|
|
||
|
OPENMPT_NAMESPACE_END
|