Commit cc173d11 authored by bitplane's avatar bitplane

API Change! File archive API tidied: CFileList now takes care of removing...

API Change! File archive API tidied: CFileList now takes care of removing paths lowering case, finding files, it can hold directory trees and is populated by the filesystem and archives. Archives now inherit it and return a const IFileList pointer rather than implementing each method and requiring special entry types in the API. createFileList works with the virtual filesystem. Separated the mount point stuff from the zip reader to its own files. Added GZIP archive type, fixed problem when loading files without names in gzips. Fixed a crash in the file dialog when the file list was null.

todo: update projects, test properly on Windows and OSX, add #defines for archive loaders

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2590 dfc29bdd-3216-0410-991c-e03cc46cb475
parent e6b350d3
Changes in 1.6 (??.??.2009)
- Added const method for array::binary_search, potentially slow as it doesn't sort the list!
- Add support for scaling button images.
......
......@@ -6,6 +6,7 @@
#define __I_FILE_ARCHIVE_H_INCLUDED__
#include "IReadFile.h"
#include "IFileList.h"
namespace irr
{
......@@ -23,15 +24,18 @@ enum EFileSystemType
//! Contains the different types of archives
enum E_FILE_ARCHIVE_TYPE
{
//! A PKZIP or gzip archive
//! A PKZIP archive
EFAT_ZIP = MAKE_IRR_ID('Z','I','P', 0),
//! A gzip archive
EFAT_GZIP = MAKE_IRR_ID('g','z','i','p'),
//! A virtual directory
EFAT_FOLDER = MAKE_IRR_ID('f','l','d','r'),
//! An ID Software PAK archive
EFAT_PAK = MAKE_IRR_ID('P','A','K', 0),
//! A Tape ARchive
EFAT_TAR = MAKE_IRR_ID('T','A','R', 0),
......@@ -39,7 +43,7 @@ enum E_FILE_ARCHIVE_TYPE
EFAT_UNKNOWN = MAKE_IRR_ID('u','n','k','n')
};
/*
//! Base Info which all File archives must support on browsing
struct IFileArchiveEntry
{
......@@ -50,45 +54,41 @@ struct IFileArchiveEntry
bool operator < (const IFileArchiveEntry& other) const
{
return simpleFileName < other.simpleFileName;
return path < other.path;
}
bool operator == (const IFileArchiveEntry& other) const
{
return simpleFileName == other.simpleFileName;
return path == other.path;
}
};
*/
//! The FileArchive manages files and archives and provides access to them.
/** It manages where files are, so that modules which use the the IO do not
need to know where every file is located. A file could be in a .zip-Archive or
as file on disk, using the IFileSystem makes no difference to this. */
//! The FileArchive manages archives and provides access to files inside them.
class IFileArchive : public virtual IReferenceCounted
{
public:
//! return the id of the file Archive
virtual const core::string<c16>& getArchiveName() =0;
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_UNKNOWN; }
//! opens a file by file name
//! Opens a file based on its name
/** Creates and returns a new IReadFile for a file in the archive.
\param filename The file to open
\return Returns A pointer to the created file on success,
or 0 on failure. */
virtual IReadFile* createAndOpenFile(const core::string<c16>& filename) =0;
//! opens a file by position
//! Opens a file based on its position.
/** Creates and returns
\param index The zero based index of the file.
\return Returns a pointer to the created file on success, or 0 on failure. */
virtual IReadFile* createAndOpenFile(u32 index) =0;
//! returns fileindex
virtual s32 findFile(const core::string<c16>& filename) =0;
//! Returns the amount of files in the filelist.
/** \return Amount of files and directories in the file list. */
virtual u32 getFileCount() const =0;
//! Returns the complete file tree
/** \return Returns the complete directory tree for the archive,
including all files and folders */
virtual const IFileList* getFileList() const =0;
//! returns data of known file
virtual const IFileArchiveEntry* getFileInfo(u32 index) =0;
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_UNKNOWN; }
};
//! Class which is able to create an archive from a file.
......@@ -100,31 +100,32 @@ class IArchiveLoader : public virtual IReferenceCounted
{
public:
//! Check if the file might be loaded by this class
/** Check is based on the file extension (e.g. ".zip")
/** Check based on the file extension (e.g. ".zip")
\param fileName Name of file to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const =0;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const =0;
//! Check if the file might be loaded by this class
/** Check might look into the file.
/** This check may look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const =0;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const =0;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const =0;
//! Creates an archive from the file
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const =0;
//! Returns the type of archive created by this loader
/** When creating your own archive loaders you must specifiy a new unique type identifier.
You can use the MAKE_IRR_ID macro to generate an identifier based on a four character code */
virtual E_FILE_ARCHIVE_TYPE getType() const =0;
};
......
......@@ -13,7 +13,9 @@ namespace irr
namespace io
{
//! The Filelist lists all files in a directory.
//! Provides a list of files and folders.
/** File lists usually contain a list of all files in a given folder,
but can also contain a complete directory structure. */
class IFileList : public virtual IReferenceCounted
{
public:
......@@ -24,21 +26,38 @@ public:
//! Gets the name of a file in the list, based on an index.
/** The path is not included in this name. Use getFullFileName for this.
\param index is the zero based index of the file which name should
be returned. The index has to be smaller than the amount getFileCount() returns.
be returned. The index must be less than the amount getFileCount() returns.
\return File name of the file. Returns 0, if an error occured. */
virtual const core::string<c16>& getFileName(u32 index) const = 0;
//! Gets the full name of a file in the list, path included, based on an index.
//! Gets the full name of a file in the list including the path, based on an index.
/** \param index is the zero based index of the file which name should
be returned. The index has to be smaller than the amount getFileCount() returns.
be returned. The index must be less than the amount getFileCount() returns.
\return File name of the file. Returns 0, if an error occured. */
virtual const core::string<c16>& getFullFileName(u32 index) = 0;
virtual const core::string<c16>& getFullFileName(u32 index) const = 0;
//! Returns the size of a file in the file list, based on an index.
/** \param index is the zero based index of the file which should be returned.
The index must be less than the amount getFileCount() returns.
\return The size of the file in bytes. */
virtual u32 getFileSize(u32 index) const = 0;
//! Check if the file is a directory
/** \param index The zero based index of the file whose name shall
be returned. The index has to be smaller than the amount getFileCount() returns.
/** \param index The zero based index which will be checked. The index
must be less than the amount getFileCount() returns.
\return True if the file is a directory, else false. */
virtual bool isDirectory(u32 index) const = 0;
//! Searches for a file or folder in the list
/** Searches for a file by name
\param filename The name of the file to search for.
\param isFolder True if you are searching for a file, false if you want a dir.
\return Returns the index of the file in the file list, or -1 if
no matching name name was found. */
virtual s32 findFile(const core::string<c16>& filename, bool isFolder=false) const = 0;
//! Returns the base path of the file list
virtual const core::string<c16>& getPath() const = 0;
};
} // end namespace irr
......
......@@ -6,39 +6,22 @@
#include "IrrCompileConfig.h"
#include "irrArray.h"
#include "coreutil.h"
#include <stdlib.h>
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
#ifdef _IRR_WINDOWS_API_
#if !defined ( _WIN32_WCE )
#include <io.h>
#include <direct.h>
#endif
#endif
namespace irr
{
namespace io
{
CFileList::CFileList(const c8 * param)
static const core::string<c16> emptyFileListEntry;
CFileList::CFileList(const core::string<c16>& path, bool ignoreCase, bool ignorePaths)
: IgnorePaths(ignorePaths), IgnoreCase(ignoreCase), Path(path)
{
#ifdef _DEBUG
setDebugName("CFileList");
#endif
if ( 0 == param )
constructNative ();
Path.replace('\\', '/');
}
CFileList::~CFileList()
......@@ -46,113 +29,15 @@ CFileList::~CFileList()
Files.clear();
}
void CFileList::constructNative()
{
// --------------------------------------------
// Windows version
#ifdef _IRR_WINDOWS_API_
#if !defined ( _WIN32_WCE )
char tmp[_MAX_PATH];
_getcwd(tmp, _MAX_PATH);
Path = tmp;
struct _finddata_t c_file;
long hFile;
FileEntry entry;
if( (hFile = _findfirst( "*", &c_file )) != -1L )
{
do
{
entry.Name = c_file.name;
entry.Size = c_file.size;
entry.isDirectory = (_A_SUBDIR & c_file.attrib) != 0;
Files.push_back(entry);
}
while( _findnext( hFile, &c_file ) == 0 );
_findclose( hFile );
}
#endif
//TODO add drives
//entry.Name = "E:\\";
//entry.isDirectory = true;
//Files.push_back(entry);
#endif
// --------------------------------------------
// Linux version
#if (defined(_IRR_POSIX_API_) || defined(_IRR_OSX_PLATFORM_))
FileEntry entry;
// Add default parent - even when at /, this is available
entry.Name = "..";
entry.Size = 0;
entry.isDirectory = true;
Files.push_back(entry);
// getting the CWD is rather complex as we do not know the size
// so try it until the call was successful
// Note that neither the first nor the second parameter may be 0 according to POSIX
u32 pathSize=256;
char *tmpPath = new char[pathSize];
while ((pathSize < (1<<16)) && !(getcwd(tmpPath,pathSize)))
{
delete [] tmpPath;
pathSize *= 2;
tmpPath = new char[pathSize];
}
if (!tmpPath)
return;
// note that Path might be stringw, so use tmpPath for system call
Path = tmpPath;
// We use the POSIX compliant methods instead of scandir
DIR* dirHandle=opendir(tmpPath);
delete [] tmpPath;
if (!dirHandle)
return;
struct dirent *dirEntry;
while ((dirEntry=readdir(dirHandle)))
{
if((strcmp(dirEntry->d_name, ".")==0) ||
(strcmp(dirEntry->d_name, "..")==0))
continue;
entry.Name = dirEntry->d_name;
entry.Size = 0;
entry.isDirectory = false;
struct stat buf;
if (stat(dirEntry->d_name, &buf)==0)
{
entry.Size = buf.st_size;
entry.isDirectory = S_ISDIR(buf.st_mode);
}
#if !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__CYGWIN__)
// only available on some systems
else
{
entry.isDirectory = dirEntry->d_type == DT_DIR;
}
#endif
Files.push_back(entry);
}
closedir(dirHandle);
#endif
// sort the list on all platforms
Files.sort();
}
u32 CFileList::getFileCount() const
{
return Files.size();
}
static const core::string<c16> emptyFileListEntry;
void CFileList::sort()
{
Files.sort();
}
const core::string<c16>& CFileList::getFileName(u32 index) const
{
......@@ -164,36 +49,97 @@ const core::string<c16>& CFileList::getFileName(u32 index) const
//! Gets the full name of a file in the list, path included, based on an index.
const core::string<c16>& CFileList::getFullFileName(u32 index)
const core::string<c16>& CFileList::getFullFileName(u32 index) const
{
if (index >= Files.size())
return emptyFileListEntry;
if (Files[index].FullName.size() < Files[index].Name.size())
{
// create full name
Files[index].FullName = Path;
c16 last = lastChar ( Files[index].FullName );
if ( last != '/' && last != '\\' )
Files[index].FullName.append('/');
return Files[index].FullName;
}
Files[index].FullName.append(Files[index].Name);
//! adds a file or folder
u32 CFileList::addItem(const core::string<c16>& fullPath, u32 size, bool isDirectory, u32 id)
{
SFileListEntry entry;
entry.Size = size;
entry.ID = id;
entry.Name = fullPath;
entry.Name.replace('\\', '/');
entry.IsDirectory = isDirectory;
// remove trailing slash
if (core::lastChar(entry.Name) == '/')
{
entry.IsDirectory = true;
entry.Name[entry.Name.size()-1] = 0;
entry.Name.validate();
}
return Files[index].FullName;
}
if (IgnoreCase)
entry.Name.make_lower();
entry.FullName = entry.Name;
core::deletePathFromFilename(entry.Name);
if (IgnorePaths)
entry.FullName = entry.Name;
Files.push_back(entry);
return Files.size() - 1;
}
bool CFileList::isDirectory(u32 index) const
{
bool ret = false;
if (index < Files.size())
ret = Files[index].isDirectory;
ret = Files[index].IsDirectory;
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return ret;
}
//! Returns the size of a file
u32 CFileList::getFileSize(u32 index) const
{
return index < Files.size() ? Files[index].IsDirectory : 0;
}
//! Searches for a file or folder within the list, returns the index
s32 CFileList::findFile(const core::string<c16>& filename, bool isDirectory = false) const
{
SFileListEntry entry;
entry.FullName = filename;
entry.IsDirectory = isDirectory;
// swap
entry.FullName.replace('\\', '/');
// remove trailing slash
if (core::lastChar(entry.Name) == '/')
{
entry.IsDirectory = true;
entry.Name[ entry.Name.size()-1] = 0;
entry.Name.validate();
}
if (IgnoreCase)
entry.FullName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.FullName);
return Files.binary_search(entry);
}
//! Returns the base path of the file list
const core::string<c16>& CFileList::getPath() const
{
return Path;
}
} // end namespace irr
} // end namespace io
......@@ -15,66 +15,110 @@ namespace irr
namespace io
{
/*!
FileSystem, which manages where files are, so that modules which
use the the io do not need to know where every file is located.
local FileEntry
*/
struct FileEntry
//! An entry in a list of files, can be a folder or a file.
struct SFileListEntry
{
//! The name of the file
/** If this is a file or folder in the virtual filesystem and the archive
was created with the ignoreCase flag then the file name will be lower case. */
core::string<c16> Name;
//! The name of the file including the path
/** If this is a file or folder in the virtual filesystem and the archive was
created with the ignoreDirs flag then it will be the same as Name. */
core::string<c16> FullName;
long Size;
bool isDirectory;
bool operator <(const struct FileEntry& other) const
//! The size of the file in bytes
u32 Size;
//! The ID of the file in an archive
/** This is used to link the FileList entry to extra info held about this
file in an archive, which can hold things like data offset and CRC. */
u32 ID;
//! True if this is a folder, false if not.
bool IsDirectory;
//! The == operator is provided so that CFileList can slowly search the list!
bool operator ==(const struct SFileListEntry& other) const
{
if ( isDirectory ^ other.isDirectory )
return isDirectory;
if (IsDirectory != other.IsDirectory)
return false;
return Name.lower_ignore_case ( other.Name );
return FullName.equals_ignore_case(other.FullName);
}
//! The < operator is provided so that CFileList can sort and quickly search the list.
bool operator <(const struct SFileListEntry& other) const
{
if (IsDirectory != other.IsDirectory)
return IsDirectory;
return FullName.lower_ignore_case(other.FullName);
}
};
/*!
FileSystem, which manages where files are, so that modules which
use the the io do not need to know where every file is located.
*/
//! Implementation of a file list
class CFileList : public IFileList
{
public:
//! constructor
CFileList( const c8 *param = 0);
// CFileList methods
//! Constructor
/** \param path The path of this file archive */
CFileList(const core::string<c16>& path, bool ignoreCase, bool ignorePaths);
//! Destructor
virtual ~CFileList();
//! Add as a file or folder to the list
/** \param fullPath The file name including path, up to the root of the file list.
\param isDirectory True if this is a directory rather than a file.
\param size The size of the file in bytes.
\param id The ID of the file in the archive which owns it */
virtual u32 addItem(const core::string<c16>& fullPath, u32 size, bool isDirectory, u32 id=0);
//! Sorts the file list
void sort();
// IFileList methods
//! Returns the amount of files in the filelist.
/** \return Amount of files and directories in the file list. */
virtual u32 getFileCount() const;
//! Gets the name of a file in the list, based on an index.
/** \param index is the zero based index of the file which name should
be returned. The index has to be smaller than the amount getFileCount() returns.
\return The file name of the file. Returns 0, if an error occured. */
virtual const core::string<c16>& getFileName(u32 index) const;
//! Gets the full name of a file in the list, path included, based on an index.
virtual const core::string<c16>& getFullFileName(u32 index);
virtual const core::string<c16>& getFullFileName(u32 index) const;
//! Returns of the file is a directory
/** \param index is the zero based index of the file which name should
be returned. The index has to be smaller than the amount getFileCount() returns.
\return True if the file is a directory, else false. */
//! Returns true if the file is a directory
virtual bool isDirectory(u32 index) const;
//protected:
//! Returns the size of a file
virtual u32 getFileSize(u32 index) const;
//! Searches for a file or folder within the list, returns the index
virtual s32 findFile(const core::string<c16>& filename, bool isFolder) const;
//! Returns the base path of the file list
virtual const core::string<c16>& getPath() const;
protected:
//! Ignore paths when adding or searching for files
bool IgnorePaths;
//! Ignore case when adding or searching for files
bool IgnoreCase;
//! Path to the file list
core::string<c16> Path;
core::array< FileEntry > Files;
void constructNative ();
//! List of files
core::array<SFileListEntry> Files;
};
......
This diff is collapsed.
......@@ -46,7 +46,7 @@ public:
virtual IWriteFile* createAndWriteFile(const core::string<c16>& filename, bool append=false);
//! Adds an archive to the file system.
virtual bool addFileArchive(const core::string<c16>& filename, bool ignoreCase = true,
virtual bool addFileArchive(const core::string<c16>& filename, bool ignoreCase = true,
bool ignorePaths = true, E_FILE_ARCHIVE_TYPE archiveType = EFAT_UNKNOWN);
//! move the hirarchy of the filesystem. moves sourceIndex relative up or down
......@@ -92,7 +92,7 @@ public:
virtual EFileSystemType setFileListSystem(EFileSystemType listType);
//! Creates a list of files and directories in the current working directory
//! Creates a list of files and directories in the current working directory
//! and returns it.
virtual IFileList* createFileList();
......@@ -122,10 +122,14 @@ public:
private:
EFileSystemType FileSystemType; // Currently used FileSystemType
core::string<c16> WorkingDirectory [2]; // WorkingDirectory for Native/Virtual
core::array<IArchiveLoader*> ArchiveLoader; // currently attached ArchiveLoaders
core::array<IFileArchive*> FileArchives; // currently attached Archives
//! Currently used FileSystemType
EFileSystemType FileSystemType;
//! WorkingDirectory for Native and Virtual filesystems
core::string<c16> WorkingDirectory [2];
//! currently attached ArchiveLoaders
core::array<IArchiveLoader*> ArchiveLoader;
//! currently attached Archives
core::array<IFileArchive*> FileArchives;
};
......
......@@ -325,10 +325,13 @@ void CGUIFileOpenDialog::fillListBox()
FileList = FileSystem->createFileList();
core::stringw s;
for (u32 i=0; i<FileList->getFileCount(); ++i)
if (FileList)
{
s = FileList->getFileName(i);
FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
for (u32 i=0; i < FileList->getFileCount(); ++i)
{
s = FileList->getFileName(i);
FileBox->addItem(s.c_str(), skin->getIcon(FileList->isDirectory(i) ? EGDI_DIRECTORY : EGDI_FILE));
}
}
if (FileNameText)
......
// Copyright (C) 2002-2009 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CMountPointReader.h"
#include "CReadFile.h"
#include "os.h"
namespace irr
{
namespace io
{
//! Constructor
CArchiveLoaderMount::CArchiveLoaderMount( io::IFileSystem* fs)
: FileSystem(fs)
{
#ifdef _DEBUG
setDebugName("CArchiveLoaderMount");
#endif
}
//! destructor
CArchiveLoaderMount::~CArchiveLoaderMount()
{
}
//! returns true if the file maybe is able to be loaded by this class
bool CArchiveLoaderMount::isALoadableFileFormat(const core::string<c16>& filename) const
{
bool ret = false;
core::string<c16> fname(filename);
deletePathFromFilename(fname);
if (!fname.size())
{
ret = true;
}
return ret;
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderMount::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return fileType == EFAT_FOLDER;
}
//! Check if the file might be loaded by this class
bool CArchiveLoaderMount::isALoadableFileFormat(io::IReadFile* file) const
{
return false;
}
//! Creates an archive from the filename
IFileArchive* CArchiveLoaderMount::createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const
{
IFileArchive *archive = 0;
EFileSystemType current = FileSystem->setFileListSystem(FILESYSTEM_NATIVE);
core::string<c16> save = FileSystem->getWorkingDirectory();
core::string<c16> fullPath = FileSystem->getAbsolutePath(filename);
FileSystem->flattenFilename(fullPath);
if ( FileSystem->changeWorkingDirectoryTo ( fullPath ) )
{
archive = new CMountPointReader(FileSystem, fullPath, ignoreCase, ignorePaths);
}
FileSystem->changeWorkingDirectoryTo(save);
FileSystem->setFileListSystem(current);
return archive;
}
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
IFileArchive* CArchiveLoaderMount::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
{
return 0;
}
//! compatible Folder Archticture
//
CMountPointReader::CMountPointReader( IFileSystem * parent, const core::string<c16>& basename, bool ignoreCase, bool ignorePaths)
: CFileList(basename, ignoreCase, ignorePaths), Parent(parent)
{
//! ensure CFileList path ends in a slash
if (core::lastChar(Path) != '/' )
Path.append ('/');
core::string<c16> work = Parent->getWorkingDirectory();
Parent->changeWorkingDirectoryTo(basename);
buildDirectory();
Parent->changeWorkingDirectoryTo(work);
sort();
}
CMountPointReader::~CMountPointReader()
{
}
//! returns the list of files
const IFileList* CMountPointReader::getFileList() const
{
return this;
}
void CMountPointReader::buildDirectory()
{
IFileList * list = Parent->createFileList();
const u32 size = list->getFileCount();
for (u32 i = 0; i!= size; ++i)
{
if (!list->isDirectory(i))
{
addItem(list->getFullFileName(i), list->getFileSize(i), false, RealFileNames.size());
RealFileNames.push_back(list->getFullFileName(i));
}
else
{
const core::string<c16>& full = list->getFullFileName(i);
const core::string<c16> rel = list->getFileName(i);
core::string<c16> pwd = Parent->getWorkingDirectory() + "/";
pwd += rel;
if ( rel != "." && rel != ".." )
{
addItem(full, 0, true, 0);
Parent->changeWorkingDirectoryTo(pwd);
buildDirectory ();
Parent->changeWorkingDirectoryTo("..");
}
}
}
list->drop();
}
//! opens a file by index
IReadFile* CMountPointReader::createAndOpenFile(u32 index)
{
if (index >= Files.size())
return 0;
return createReadFile( RealFileNames[Files[index].ID] );
}
//! opens a file by file name
IReadFile* CMountPointReader::createAndOpenFile(const core::string<c16>& filename)
{
s32 index = findFile(filename, false);
if (index == -1)
return 0;
return createReadFile( RealFileNames[Files[index].ID] );
}
} // io
} // irr
// Copyright (C) 2002-2009 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_MOUNT_READER_H_INCLUDED__
#define __C_MOUNT_READER_H_INCLUDED__
#include "IFileSystem.h"
#include "CFileList.h"
namespace irr
{
namespace io
{
//! Archiveloader capable of loading MountPoint Archives
class CArchiveLoaderMount : public IArchiveLoader
{
public:
//! Constructor
CArchiveLoaderMount(io::IFileSystem* fs);
//! destructor
virtual ~CArchiveLoaderMount();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
private:
io::IFileSystem* FileSystem;
};
//! A File Archive which uses a mountpoint
class CMountPointReader : public virtual IFileArchive, virtual CFileList
{
public:
//! Constructor
CMountPointReader(IFileSystem *parent, const core::string<c16>& basename,
bool ignoreCase, bool ignorePaths);
//! Destructor
virtual ~CMountPointReader();
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const core::string<c16>& filename);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_FOLDER; }
private:
core::array<core::string<c16> > RealFileNames;
IFileSystem *Parent;
void buildDirectory();
};
} // io
} // irr
#endif
......@@ -29,6 +29,11 @@ bool CArchiveLoaderPAK::isALoadableFileFormat(const core::string<c16>& filename)
return core::hasFileExtension ( filename, "pak" );
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderPAK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return fileType == EFAT_PAK;
}
//! Creates an archive from the filename
/** \param file File handle to check.
......@@ -43,7 +48,7 @@ IFileArchive* CArchiveLoaderPAK::createArchive(const core::string<c16>& filename
archive = createArchive ( file, ignoreCase, ignorePaths );
file->drop ();
}
return archive;
}
......@@ -79,7 +84,7 @@ bool CArchiveLoaderPAK::isALoadableFileFormat(io::IReadFile* file) const
PAK Reader
*/
CPakReader::CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
: Type("pak"), File(file), IgnoreCase(ignoreCase), IgnorePaths(ignorePaths)
: CFileList(file ? file->getFileName() : "", ignoreCase, ignorePaths), File(file)
{
#ifdef _DEBUG
setDebugName("CPakReader");
......@@ -92,8 +97,7 @@ CPakReader::CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
// scan local headers
scanLocalHeader();
// prepare file index for binary search
FileList.sort();
sort();
}
}
......@@ -105,64 +109,21 @@ CPakReader::~CPakReader()
}
//! splits filename into useful filenames and paths
void CPakReader::extractFilename(SPakFileEntry* entry)
const IFileList* CPakReader::getFileList() const
{
s32 lorfn = 56; // length of real file name
if (!lorfn)
return;
if (IgnoreCase)
entry->pakFileName.make_lower();
const c16* p = entry->pakFileName.c_str() + lorfn;
// suche ein slash oder den anfang.
while (*p!='/' && p!=entry->pakFileName.c_str())
{
--p;
--lorfn;
}
bool thereIsAPath = p != entry->pakFileName.c_str();
if (thereIsAPath)
{
// there is a path
++p;
++lorfn;
}
entry->simpleFileName = p;
entry->path = "";
// pfad auch kopieren
if (thereIsAPath)
{
lorfn = (s32)(p - entry->pakFileName.c_str());
entry->path.append(entry->pakFileName, lorfn);
}
if (!IgnorePaths)
entry->simpleFileName = entry->pakFileName; // thanks to Pr3t3nd3r for this fix
return this;
}
//! scans for a local header, returns false if there is no more local file header.
bool CPakReader::scanLocalHeader()
{
c8 tmp[1024];
SPakFileEntry entry;
entry.pos = 0;
c8 tmp[1024];
core::string<c16> PakFileName;
memset(&header, 0, sizeof(SPAKFileHeader));
File->read(&header, sizeof(SPAKFileHeader));
if (header.tag[0] != 'P' && header.tag[1] != 'A')
return false; // local file headers end here.
......@@ -173,22 +134,29 @@ bool CPakReader::scanLocalHeader()
for(int i = 0; i < count; i++)
{
// read filename
entry.pakFileName.reserve(56+2);
PakFileName.reserve(56+2);
File->read(tmp, 56);
tmp[56] = 0x0;
entry.pakFileName = tmp;
PakFileName = tmp;
#ifdef _DEBUG
os::Printer::log(entry.pakFileName.c_str());
os::Printer::log(PakFileName.c_str());
#endif
extractFilename(&entry);
s32 offset;
s32 size;
File->read(&entry.pos, sizeof(u32));
File->read(&entry.length, sizeof(u32));
FileList.push_back(entry);
}
File->read(&offset, sizeof(u32));
File->read(&size, sizeof(u32));
#ifdef __BIG_ENDIAN__
os::Byteswap::byteswap(offset);
os::Byteswap::byteswap(size);
#endif
addItem(PakFileName, size, false, Offsets.size());
Offsets.push_back(offset);
}
return true;
}
......@@ -196,7 +164,7 @@ bool CPakReader::scanLocalHeader()
//! opens a file by file name
IReadFile* CPakReader::createAndOpenFile(const core::string<c16>& filename)
{
s32 index = findFile(filename);
s32 index = findFile(filename, false);
if (index != -1)
return createAndOpenFile(index);
......@@ -208,57 +176,14 @@ IReadFile* CPakReader::createAndOpenFile(const core::string<c16>& filename)
//! opens a file by index
IReadFile* CPakReader::createAndOpenFile(u32 index)
{
if (index < FileList.size())
return createLimitReadFile(FileList[index].simpleFileName, File, FileList[index].pos, FileList[index].length);
else
return 0;
}
//! returns count of files in archive
u32 CPakReader::getFileCount() const
{
return FileList.size();
}
//! returns data of file
const IFileArchiveEntry* CPakReader::getFileInfo(u32 index)
{
return &FileList[index];
}
//! returns fileindex
s32 CPakReader::findFile(const core::string<c16>& filename)
{
SPakFileEntry entry;
entry.simpleFileName = filename;
if (IgnoreCase)
entry.simpleFileName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.simpleFileName);
s32 res = FileList.binary_search(entry);
#ifdef _DEBUG
if (res == -1)
if (index < Files.size())
{
for (u32 i=0; i<FileList.size(); ++i)
if (FileList[i].simpleFileName == entry.simpleFileName)
{
os::Printer::log("File in archive but not found.", entry.simpleFileName.c_str(), ELL_ERROR);
break;
}
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
}
#endif
return res;
else
return 0;
}
} // end namespace io
} // end namespace irr
......@@ -10,6 +10,7 @@
#include "irrArray.h"
#include "irrString.h"
#include "IFileSystem.h"
#include "CFileList.h"
namespace irr
{
......@@ -22,14 +23,6 @@ namespace io
u32 length;
};
struct SPakFileEntry: public IFileArchiveEntry
{
core::string<c16> pakFileName;
u32 pos;
u32 length;
};
//! Archiveloader capable of loading PAK Archives
class CArchiveLoaderPAK : public IArchiveLoader
{
......@@ -42,17 +35,23 @@ namespace io
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
......@@ -66,57 +65,48 @@ namespace io
//! reads from pak
class CPakReader : public IFileArchive
class CPakReader : public virtual IFileArchive, virtual CFileList
{
public:
CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths);
virtual ~CPakReader();
// file archive methods
//! return the id of the file Archive
virtual const core::string<c16>& getArchiveName() const
{
return File->getFileName();
}
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const core::string<c16>& filename);
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns count of files in archive
virtual u32 getFileCount() const;
//! returns data of file
virtual const IFileArchiveEntry* getFileInfo(u32 index);
//! returns fileindex
virtual s32 findFile(const core::string<c16>& filename);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_PAK; }
//! return the id of the file Archive
virtual const core::string<c16>& getArchiveName ()
{
return File->getFileName();
}
private:
core::string<c16> Type;
//! scans for a local header, returns false if there is no more local file header.
bool scanLocalHeader();
//! splits filename from zip file into useful filenames and paths
void extractFilename(SPakFileEntry* entry);
//void extractFilename(SPakFileEntry* entry);
IReadFile* File;
SPAKFileHeader header;
core::array<SPakFileEntry> FileList;
bool IgnoreCase;
bool IgnorePaths;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
......
......@@ -32,6 +32,11 @@ bool CArchiveLoaderTAR::isALoadableFileFormat(const core::string<c16>& filename)
return core::hasFileExtension(filename, "tar");
}
//! Check to see if the loader can create archives of this type.
bool CArchiveLoaderTAR::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
{
return fileType == EFAT_TAR;
}
//! Creates an archive from the filename
/** \param file File handle to check.
......@@ -117,7 +122,7 @@ bool CArchiveLoaderTAR::isALoadableFileFormat(io::IReadFile* file) const
TAR Archive
*/
CTarReader::CTarReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
: File(file), IgnoreCase(ignoreCase), IgnorePaths(ignorePaths)
: CFileList(file ? file->getFileName() : "", ignoreCase, ignorePaths), File(file)
{
#ifdef _DEBUG
setDebugName("CTarReader");
......@@ -127,11 +132,10 @@ CTarReader::CTarReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
{
File->grab();
Base = File->getFileName();
Base.replace('\\', '/');
// fill the file list
populateFileList();
sort();
}
}
......@@ -140,14 +144,18 @@ CTarReader::~CTarReader()
{
if (File)
File->drop();
}
const IFileList* CTarReader::getFileList() const
{
return this;
}
u32 CTarReader::populateFileList()
{
STarHeader fHead;
FileList.clear();
Files.clear();
u32 pos = 0;
while ( s32(pos + sizeof(STarHeader)) < File->getSize())
......@@ -161,9 +169,7 @@ u32 CTarReader::populateFileList()
// only add standard files for now
if (fHead.Link == ETLI_REGULAR_FILE || ETLI_REGULAR_FILE_OLD)
{
STARArchiveEntry entry;
core::string<c16> fullPath = L"";
core::string<c16> fullPath = "";
fullPath.reserve(255);
// USTAR archives have a filename prefix
......@@ -171,7 +177,7 @@ u32 CTarReader::populateFileList()
if (!strcmp(fHead.Magic, "ustar"))
{
c8* np = fHead.FileNamePrefix;
while(*np && (np - fHead.FileNamePrefix) < 155)
while(*np && (np - fHead.FileNamePrefix) < 155)
fullPath.append(*np);
np++;
}
......@@ -184,26 +190,6 @@ u32 CTarReader::populateFileList()
np++;
}
fullPath.replace('\\', '/');
const s32 lastSlash = fullPath.findLast('/');
if (IgnoreCase)
fullPath.make_lower();
if (lastSlash == -1)
{
entry.path = "";
entry.simpleFileName = fullPath;
}
else
{
entry.path = fullPath.subString(0, lastSlash);
if (IgnorePaths)
entry.simpleFileName = &fullPath[lastSlash+1];
else
entry.simpleFileName = fullPath;
}
// get size
core::stringc sSize = "";
sSize.reserve(12);
......@@ -213,38 +199,38 @@ u32 CTarReader::populateFileList()
sSize.append(*np);
np++;
}
entry.size=strtoul(sSize.c_str(), NULL, 8);
if (errno==ERANGE)
u32 size = strtoul(sSize.c_str(), NULL, 8);
if (errno == ERANGE)
os::Printer::log("File too large", fullPath, ELL_WARNING);
// save start position
entry.startPos = pos + 512;
u32 offset = pos + 512;
// move to next file header block
pos = entry.startPos + (entry.size / 512) * 512 +
((entry.size % 512) ? 512 : 0);
pos = offset + (size / 512) * 512 + ((size % 512) ? 512 : 0);
// add file to list
FileList.push_back(entry);
addItem(fullPath, size, false, Offsets.size());
Offsets.push_back(offset);
}
else
{
// todo: ETLI_DIRECTORY, ETLI_LINK_TO_ARCHIVED_FILE
// move to next block
pos += 512;
}
}
FileList.sort();
return FileList.size();
return Files.size();
}
//! opens a file by file name
IReadFile* CTarReader::createAndOpenFile(const core::string<c16>& filename)
{
const s32 index = findFile(filename);
const s32 index = findFile(filename, false);
if (index != -1)
return createAndOpenFile(index);
......@@ -252,53 +238,15 @@ IReadFile* CTarReader::createAndOpenFile(const core::string<c16>& filename)
return 0;
}
//! opens a file by index
IReadFile* CTarReader::createAndOpenFile(u32 index)
{
if (index < FileList.size())
return createLimitReadFile(FileList[index].simpleFileName, File, FileList[index].startPos, FileList[index].size);
if (index < Files.size())
return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size);
else
return 0;
}
//! returns count of files in archive
u32 CTarReader::getFileCount() const
{
return FileList.size();
}
//! returns data of file
const IFileArchiveEntry* CTarReader::getFileInfo(u32 index)
{
return &FileList[index];
}
//! return the id of the file Archive
const core::string<c16>& CTarReader::getArchiveName()
{
return Base;
}
//! returns fileindex
s32 CTarReader::findFile(const core::string<c16>& simpleFilename)
{
STARArchiveEntry entry;
entry.simpleFileName = simpleFilename;
if (IgnoreCase)
entry.simpleFileName.make_lower();
if (IgnorePaths)
core::deletePathFromFilename(entry.simpleFileName);
return FileList.binary_search(entry);
}
} // end namespace io
} // end namespace irr
......@@ -10,14 +10,14 @@
#include "irrArray.h"
#include "irrString.h"
#include "IFileSystem.h"
#include "IFileList.h"
#include "CFileList.h"
namespace irr
{
namespace io
{
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
......@@ -61,7 +61,7 @@ namespace io
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
......@@ -79,35 +79,39 @@ namespace io
//! based on the file extension (e.g. ".tar")
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
//! Returns the type of archive created by this loader
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_TAR; }
private:
io::IFileSystem* FileSystem;
};
class CTarReader : public IFileArchive
class CTarReader : public virtual IFileArchive, virtual CFileList
{
public:
CTarReader(IReadFile* file, bool ignoreCase, bool ignorePaths);
virtual ~CTarReader();
//! opens a file by file name
......@@ -116,38 +120,20 @@ namespace io
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns count of files in archive
virtual u32 getFileCount() const;
//! returns data of file
virtual const IFileArchiveEntry* getFileInfo(u32 index);
//! returns fileindex
virtual s32 findFile(const core::string<c16>& filename);
//! return the id of the file Archive
virtual const core::string<c16>& getArchiveName();
//! returns the list of files
virtual const IFileList* getFileList() const;
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_TAR; }
private:
struct STARArchiveEntry : public IFileArchiveEntry
{
u32 size;
u32 startPos;
};
u32 populateFileList();
IReadFile* File;
bool IgnoreCase;
bool IgnorePaths;
core::array<STARArchiveEntry> FileList;
IReadFile* File;
core::string<c16> Base;
//! Contains offsets of the files from the start of the archive file
core::array<u32> Offsets;
};
} // end namespace io
......
This diff is collapsed.
......@@ -5,12 +5,11 @@
#ifndef __C_ZIP_READER_H_INCLUDED__
#define __C_ZIP_READER_H_INCLUDED__
#include "IReferenceCounted.h"
#include "IReadFile.h"
#include "irrArray.h"
#include "irrString.h"
#include "IFileSystem.h"
#include "IFileList.h"
#include "CFileList.h"
namespace irr
{
......@@ -22,7 +21,7 @@ namespace io
// zero in the local header
const s16 ZIP_INFO_IN_DATA_DESCRIPTOR = 0x0008;
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( push, packing )
# pragma pack( 1 )
# define PACK_STRUCT
......@@ -114,23 +113,22 @@ namespace io
} PACK_STRUCT;
// Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing )
#endif
#undef PACK_STRUCT
struct SZipFileEntry : public IFileArchiveEntry
//! Contains extended info about zip files in the archive
struct SZipFileEntry
{
SZipFileEntry () {}
//! Position of data in the archive file
s32 Offset;
core::string<c16> zipFileName;
s32 fileDataPosition; // position of compressed data in file
//! The header for this file containing compression info etc
SZIPFileHeader header;
};
//! Archiveloader capable of loading ZIP Archives
class CArchiveLoaderZIP : public IArchiveLoader
{
......@@ -143,24 +141,27 @@ namespace io
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! Check to see if the loader can create archives of this type.
/** Check based on the archive type.
\param fileType The archive type to check.
\return True if the archile loader supports this type, false if not */
virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
//! Returns the type of archive created by this loader
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_ZIP; }
private:
io::IFileSystem* FileSystem;
};
......@@ -168,7 +169,7 @@ namespace io
/*!
Zip file Reader written April 2002 by N.Gebhardt.
*/
class CZipReader : public IFileArchive
class CZipReader : public virtual IFileArchive, virtual CFileList
{
public:
......@@ -184,20 +185,11 @@ namespace io
//! opens a file by index
virtual IReadFile* createAndOpenFile(u32 index);
//! returns count of files in archive
virtual u32 getFileCount() const;
//! returns data of file
virtual const IFileArchiveEntry* getFileInfo(u32 index);
//! returns fileindex
virtual s32 findFile(const core::string<c16>& filename);
//! returns the list of files
virtual const IFileList* getFileList() const;
//! return the id of the file Archive
virtual const core::string<c16>& getArchiveName();
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_ZIP; }
//! get the archive type
virtual E_FILE_ARCHIVE_TYPE getType() const;
protected:
......@@ -209,77 +201,12 @@ namespace io
//! the same but for gzip files
bool scanGZipHeader();
//! splits filename from zip file into useful filenames and paths
void extractFilename(SZipFileEntry* entry);
bool IgnoreCase;
bool IgnorePaths;
bool IsGZip;
core::array<SZipFileEntry> FileList;
core::string<c16> Base;
// holds extended info about files
core::array<SZipFileEntry> FileInfo;
};
//! Archiveloader capable of loading MountPoint Archives
class CArchiveLoaderMount : public IArchiveLoader
{
public:
//! Constructor
CArchiveLoaderMount(io::IFileSystem* fs);
//! destructor
virtual ~CArchiveLoaderMount();
//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".zip")
virtual bool isALoadableFileFormat(const core::string<c16>& filename) const;
//! Creates an archive from the filename
/** \param file File handle to check.
\return Pointer to newly created archive, or 0 upon error. */
virtual IFileArchive* createArchive(const core::string<c16>& filename, bool ignoreCase, bool ignorePaths) const;
//! Check if the file might be loaded by this class
/** Check might look into the file.
\param file File handle to check.
\return True if file seems to be loadable. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const;
//! creates/loads an archive from the file.
//! \return Pointer to the created archive. Returns 0 if loading failed.
virtual IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
//! Returns the type of archive created by this loader
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_FOLDER; }
private:
io::IFileSystem* FileSystem;
};
//! A File Archive whichs uses a a mountpoint
class CMountPointReader : public CZipReader
{
public:
CMountPointReader(IFileSystem *parent, const core::string<c16>& basename,
bool ignoreCase, bool ignorePaths);
//! opens a file by file name
virtual IReadFile* createAndOpenFile(const core::string<c16>& filename);
//! returns fileindex
virtual s32 findFile(const core::string<c16>& filename);
//! get the class Type
virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_FOLDER; }
private:
IFileSystem *Parent;
void buildDirectory();
};
} // end namespace io
} // end namespace irr
......
This diff is collapsed.
......@@ -36,7 +36,7 @@ IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderJPG.o CIm
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o CTarReader.o irrXML.o CAttributes.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CZipReader.o CPakReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CLogger.o COSOperator.o Irrlicht.o os.o
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o
ZLIBOBJ = zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o zlib/trees.o zlib/uncompr.o zlib/zutil.o
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment