mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 21:32:23 +08:00

+ added PKGV0004, PKGV0005, PKGV0006 to the list Signed-off-by: Alexis Maiquez <almamu@almamu.com>
194 lines
5.1 KiB
C++
194 lines
5.1 KiB
C++
#include "CPkgReader.h"
|
|
|
|
namespace WallpaperEngine::Irrlicht
|
|
{
|
|
bool isPkgHeaderVersionValid(char* version)
|
|
{
|
|
return strcmp ("PKGV0007", version) == 0 ||
|
|
strcmp ("PKGV0002", version) == 0 ||
|
|
strcmp ("PKGV0001", version) == 0 ||
|
|
strcmp ("PKGV0008", version) == 0 ||
|
|
strcmp ("PKGV0009", version) == 0 ||
|
|
strcmp ("PKGV0004", version) == 0 ||
|
|
strcmp ("PKGV0005", version) == 0 ||
|
|
strcmp ("PKGV0006", version) == 0;
|
|
}
|
|
|
|
CArchiveLoaderPkg::CArchiveLoaderPkg (CContext* context) :
|
|
m_context (context)
|
|
{
|
|
#ifdef _DEBUG
|
|
setDebugName("CArchiveLoaderPKG");
|
|
#endif
|
|
}
|
|
|
|
bool CArchiveLoaderPkg::isALoadableFileFormat(const irr::io::path& filename) const
|
|
{
|
|
return irr::core::hasFileExtension (filename, "pkg");
|
|
}
|
|
|
|
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(const irr::io::path& filename, bool ignoreCase, bool ignorePaths) const
|
|
{
|
|
irr::io::IFileArchive *archive = nullptr;
|
|
irr::io::IReadFile* file = this->m_context->getDevice ()->getFileSystem ()->createAndOpenFile(filename);
|
|
|
|
if (file)
|
|
{
|
|
archive = this->createArchive (file, ignoreCase, ignorePaths);
|
|
file->drop ();
|
|
}
|
|
|
|
return archive;
|
|
}
|
|
|
|
irr::io::IFileArchive* CArchiveLoaderPkg::createArchive(irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
|
|
{
|
|
irr::io::IFileArchive *archive = nullptr;
|
|
|
|
if (file)
|
|
{
|
|
file->seek (0);
|
|
archive = new CPkgReader (this->m_context, file, ignoreCase, ignorePaths);
|
|
}
|
|
|
|
return archive;
|
|
}
|
|
|
|
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::IReadFile* file) const
|
|
{
|
|
unsigned int size;
|
|
char* pointer;
|
|
|
|
file->read (&size, 4);
|
|
|
|
// the string doesnt include the null terminator
|
|
size ++;
|
|
|
|
pointer = new char [size];
|
|
memset (pointer, 0, size);
|
|
|
|
file->read (pointer, size - 1);
|
|
|
|
|
|
if (isPkgHeaderVersionValid (pointer) == false)
|
|
{
|
|
delete [] pointer;
|
|
return false;
|
|
}
|
|
|
|
delete [] pointer;
|
|
return true;
|
|
}
|
|
|
|
//! Check to see if the loader can create archives of this type.
|
|
bool CArchiveLoaderPkg::isALoadableFileFormat(irr::io::E_FILE_ARCHIVE_TYPE fileType) const
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CPkgReader::CPkgReader (CContext* context, irr::io::IReadFile* file, bool ignoreCase, bool ignorePaths)
|
|
: CFileList((file ? file->getFileName() : irr::io::path("")), ignoreCase, ignorePaths),
|
|
m_file(file),
|
|
m_context (context)
|
|
{
|
|
if (this->m_file)
|
|
{
|
|
this->m_file->grab ();
|
|
this->scanPkgHeader ();
|
|
}
|
|
}
|
|
|
|
CPkgReader::~CPkgReader()
|
|
{
|
|
if (this->m_file)
|
|
this->m_file->drop();
|
|
}
|
|
|
|
irr::io::E_FILE_ARCHIVE_TYPE CPkgReader::getType() const
|
|
{
|
|
return irr::io::E_FILE_ARCHIVE_TYPE::EFAT_ZIP;
|
|
}
|
|
|
|
const irr::io::IFileList* CPkgReader::getFileList() const
|
|
{
|
|
return this;
|
|
}
|
|
|
|
void CPkgReader::scanPkgHeader ()
|
|
{
|
|
char* headerVersion = this->readSizedString ();
|
|
|
|
if (isPkgHeaderVersionValid (headerVersion) == false)
|
|
{
|
|
delete [] headerVersion;
|
|
|
|
this->m_context->getDevice ()->getLogger ()->log (
|
|
"unexpected package header", this->m_file->getFileName ().c_str (), irr::ELL_ERROR
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
delete [] headerVersion;
|
|
irr::u32 entriesCount;
|
|
|
|
this->m_file->read (&entriesCount, 4);
|
|
|
|
|
|
for (irr::u32 i = 0; i < entriesCount; i ++)
|
|
{
|
|
char* filename = this->readSizedString ();
|
|
irr::u32 offset, length;
|
|
|
|
this->m_file->read (&offset, 4);
|
|
this->m_file->read (&length, 4);
|
|
|
|
this->addItem (filename, offset, length, false);
|
|
|
|
delete [] filename;
|
|
}
|
|
|
|
// after the header is read we have to update the actual offsets
|
|
for (irr::u32 i = 0; i < this->m_files.size (); i ++)
|
|
{
|
|
this->m_files [i].Offset += this->m_file->getPos ();
|
|
}
|
|
}
|
|
|
|
char* CPkgReader::readSizedString ()
|
|
{
|
|
unsigned int size;
|
|
char* pointer;
|
|
|
|
this->m_file->read (&size, 4);
|
|
|
|
// the string doesnt include the null terminator
|
|
size ++;
|
|
|
|
pointer = new char [size];
|
|
memset (pointer, 0, size);
|
|
|
|
this->m_file->read (pointer, size - 1);
|
|
|
|
return pointer;
|
|
}
|
|
|
|
irr::io::IReadFile* CPkgReader::createAndOpenFile (const irr::io::path& filename)
|
|
{
|
|
irr::s32 index = this->findFile (filename, false);
|
|
|
|
if (index != -1)
|
|
return createAndOpenFile (index);
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
irr::io::IReadFile* CPkgReader::createAndOpenFile (irr::u32 index)
|
|
{
|
|
if (index > this->m_files.size ())
|
|
return nullptr;
|
|
|
|
const SFileListEntry entry = m_files [index];
|
|
return irr::io::createLimitReadFile (entry.FullName, m_file, entry.Offset, entry.Size);
|
|
}
|
|
} |