1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __C_ZIP_READER_H_INCLUDED__
\r
6 #define __C_ZIP_READER_H_INCLUDED__
\r
8 #include "IrrCompileConfig.h"
\r
10 #ifdef __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_
\r
12 #include "IReadFile.h"
\r
13 #include "irrArray.h"
\r
14 #include "irrString.h"
\r
15 #include "IFileSystem.h"
\r
16 #include "CFileList.h"
\r
22 // set if the file is encrypted
\r
23 const s16 ZIP_FILE_ENCRYPTED = 0x0001;
\r
24 // the fields crc-32, compressed size and uncompressed size are set to
\r
25 // zero in the local header
\r
26 const s16 ZIP_INFO_IN_DATA_DESCRIPTOR = 0x0008;
\r
28 // byte-align structures
\r
29 #include "irrpack.h"
\r
31 struct SZIPFileDataDescriptor
\r
35 u32 UncompressedSize;
\r
38 struct SZIPFileHeader
\r
40 u32 Sig; // 'PK0304' little endian (0x04034b50)
\r
41 s16 VersionToExtract;
\r
43 s16 CompressionMethod;
\r
44 s16 LastModFileTime;
\r
45 s16 LastModFileDate;
\r
46 SZIPFileDataDescriptor DataDescriptor;
\r
48 s16 ExtraFieldLength;
\r
49 // filename (variable size)
\r
50 // extra field (variable size )
\r
53 struct SZIPFileCentralDirFileHeader
\r
55 u32 Sig; // 'PK0102' (0x02014b50)
\r
57 u16 VersionToExtract;
\r
59 u16 CompressionMethod;
\r
60 u16 LastModFileTime;
\r
61 u16 LastModFileDate;
\r
64 u32 UncompressedSize;
\r
66 u16 ExtraFieldLength;
\r
67 u16 FileCommentLength;
\r
68 u16 DiskNumberStart;
\r
69 u16 InternalFileAttributes;
\r
70 u32 ExternalFileAttributes;
\r
71 u32 RelativeOffsetOfLocalHeader;
\r
73 // filename (variable size)
\r
74 // extra field (variable size)
\r
75 // file comment (variable size)
\r
79 struct SZIPFileCentralDirEnd
\r
81 u32 Sig; // 'PK0506' end_of central dir signature // (0x06054b50)
\r
82 u16 NumberDisk; // number of this disk
\r
83 u16 NumberStart; // number of the disk with the start of the central directory
\r
84 u16 TotalDisk; // total number of entries in the central dir on this disk
\r
85 u16 TotalEntries; // total number of entries in the central dir
\r
86 u32 Size; // size of the central directory
\r
87 u32 Offset; // offset of start of centraldirectory with respect to the starting disk number
\r
88 u16 CommentLength; // zipfile comment length
\r
89 // zipfile comment (variable size)
\r
92 struct SZipFileExtraHeader
\r
98 struct SZipFileAESExtraData
\r
102 u8 EncryptionStrength;
\r
103 s16 CompressionMode;
\r
110 EGZF_EXTRA_FIELDS = 4,
\r
111 EGZF_FILE_NAME = 8,
\r
115 struct SGZIPMemberHeader
\r
118 u8 compressionMethod; // 8 = deflate
\r
121 u8 extraFlags; // slow compress = 2, fast compress = 4
\r
122 u8 operatingSystem;
\r
125 // Default alignment
\r
126 #include "irrunpack.h"
\r
128 //! Contains extended info about zip files in the archive
\r
129 struct SZipFileEntry
\r
131 //! Position of data in the archive file
\r
134 //! The header for this file containing compression info etc
\r
135 SZIPFileHeader header;
\r
138 //! Archiveloader capable of loading ZIP Archives
\r
139 class CArchiveLoaderZIP : public IArchiveLoader
\r
144 CArchiveLoaderZIP(io::IFileSystem* fs);
\r
146 //! returns true if the file maybe is able to be loaded by this class
\r
147 //! based on the file extension (e.g. ".zip")
\r
148 bool isALoadableFileFormat(const io::path& filename) const override;
\r
150 //! Check if the file might be loaded by this class
\r
151 /** Check might look into the file.
\r
152 \param file File handle to check.
\r
153 \return True if file seems to be loadable. */
\r
154 bool isALoadableFileFormat(io::IReadFile* file) const override;
\r
156 //! Check to see if the loader can create archives of this type.
\r
157 /** Check based on the archive type.
\r
158 \param fileType The archive type to check.
\r
159 \return True if the archile loader supports this type, false if not */
\r
160 bool isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const override;
\r
162 //! Creates an archive from the filename
\r
163 /** \param file File handle to check.
\r
164 \return Pointer to newly created archive, or 0 upon error. */
\r
165 IFileArchive* createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const override;
\r
167 //! creates/loads an archive from the file.
\r
168 //! \return Pointer to the created archive. Returns 0 if loading failed.
\r
169 io::IFileArchive* createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const override;
\r
172 io::IFileSystem* FileSystem;
\r
176 Zip file Reader written April 2002 by N.Gebhardt.
\r
178 class CZipReader : public virtual IFileArchive, virtual CFileList
\r
183 CZipReader(IFileSystem* fs, IReadFile* file, bool ignoreCase, bool ignorePaths, bool isGZip=false);
\r
186 virtual ~CZipReader();
\r
188 //! opens a file by file name
\r
189 IReadFile* createAndOpenFile(const io::path& filename) override;
\r
191 //! opens a file by index
\r
192 IReadFile* createAndOpenFile(u32 index) override;
\r
194 //! returns the list of files
\r
195 const IFileList* getFileList() const override;
\r
197 //! get the archive type
\r
198 E_FILE_ARCHIVE_TYPE getType() const override;
\r
200 //! return the id of the file Archive
\r
201 const io::path& getArchiveName() const override {return Path;}
\r
205 //! reads the next file header from a ZIP file, returns false if there are no more headers.
\r
206 /* if ignoreGPBits is set, the item will be read despite missing
\r
207 file information. This is used when reading items from the central
\r
209 bool scanZipHeader(bool ignoreGPBits=false);
\r
211 //! the same but for gzip files
\r
212 bool scanGZipHeader();
\r
214 bool scanCentralDirectoryHeader();
\r
216 io::IFileSystem* FileSystem;
\r
219 // holds extended info about files
\r
220 core::array<SZipFileEntry> FileInfo;
\r
226 } // end namespace io
\r
227 } // end namespace irr
\r
229 #endif // __IRR_COMPILE_WITH_ZIP_ARCHIVE_LOADER_
\r
230 #endif // __C_ZIP_READER_H_INCLUDED__
\r