1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __C_PAK_READER_H_INCLUDED__
6 #define __C_PAK_READER_H_INCLUDED__
7 
8 #include "IrrCompileConfig.h"
9 
10 #ifdef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
11 
12 #include "IReferenceCounted.h"
13 #include "IReadFile.h"
14 #include "irrArray.h"
15 #include "irrString.h"
16 #include "IFileSystem.h"
17 #include "CFileList.h"
18 
19 namespace irr
20 {
21 namespace io
22 {
23 	//! File header containing location and size of the table of contents
24 	struct SPAKFileHeader
25 	{
26 		// Don't change the order of these fields!  They must match the order stored on disk.
27 		c8 tag[4];
28 		u32 offset;
29 		u32 length;
30 	};
31 
32 	//! An entry in the PAK file's table of contents.
33 	struct SPAKFileEntry
34 	{
35 		// Don't change the order of these fields!  They must match the order stored on disk.
36 		c8 name[56];
37 		u32 offset;
38 		u32 length;
39 	};
40 
41 	//! Archiveloader capable of loading PAK Archives
42 	class CArchiveLoaderPAK : public IArchiveLoader
43 	{
44 	public:
45 
46 		//! Constructor
47 		CArchiveLoaderPAK(io::IFileSystem* fs);
48 
49 		//! returns true if the file maybe is able to be loaded by this class
50 		//! based on the file extension (e.g. ".zip")
51 		virtual bool isALoadableFileFormat(const io::path& filename) const;
52 
53 		//! Check if the file might be loaded by this class
54 		/** Check might look into the file.
55 		\param file File handle to check.
56 		\return True if file seems to be loadable. */
57 		virtual bool isALoadableFileFormat(io::IReadFile* file) const;
58 
59 		//! Check to see if the loader can create archives of this type.
60 		/** Check based on the archive type.
61 		\param fileType The archive type to check.
62 		\return True if the archile loader supports this type, false if not */
63 		virtual bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const;
64 
65 		//! Creates an archive from the filename
66 		/** \param file File handle to check.
67 		\return Pointer to newly created archive, or 0 upon error. */
68 		virtual IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const;
69 
70 		//! creates/loads an archive from the file.
71 		//! \return Pointer to the created archive. Returns 0 if loading failed.
72 		virtual io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const;
73 
74 		//! Returns the type of archive created by this loader
getType()75 		virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_PAK; }
76 
77 	private:
78 		io::IFileSystem* FileSystem;
79 	};
80 
81 
82 	//! reads from pak
83 	class CPakReader : public virtual IFileArchive, virtual CFileList
84 	{
85 	public:
86 
87 		CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths);
88 		virtual ~CPakReader();
89 
90 		// file archive methods
91 
92 		//! return the id of the file Archive
getArchiveName()93 		virtual const io::path& getArchiveName() const
94 		{
95 			return File->getFileName();
96 		}
97 
98 		//! opens a file by file name
99 		virtual IReadFile* createAndOpenFile(const io::path& filename);
100 
101 		//! opens a file by index
102 		virtual IReadFile* createAndOpenFile(u32 index);
103 
104 		//! returns the list of files
105 		virtual const IFileList* getFileList() const;
106 
107 		//! get the class Type
getType()108 		virtual E_FILE_ARCHIVE_TYPE getType() const { return EFAT_PAK; }
109 
110 	private:
111 
112 		//! scans for a local header, returns false if the header is invalid
113 		bool scanLocalHeader();
114 
115 		IReadFile* File;
116 
117 	};
118 
119 } // end namespace io
120 } // end namespace irr
121 
122 #endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
123 
124 #endif // __C_PAK_READER_H_INCLUDED__
125 
126