aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp')
-rw-r--r--src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp
new file mode 100644
index 0000000..7b96842
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/source/Irrlicht/CPakReader.cpp
@@ -0,0 +1,196 @@
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// Code contributed by skreamz
5
6#include "CPakReader.h"
7
8#ifdef __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
9
10#include "os.h"
11#include "coreutil.h"
12
13namespace irr
14{
15namespace io
16{
17
18namespace
19{
20
21inline bool isHeaderValid(const SPAKFileHeader& header)
22{
23 const c8* tag = header.tag;
24 return tag[0] == 'P' &&
25 tag[1] == 'A' &&
26 tag[2] == 'C' &&
27 tag[3] == 'K';
28}
29
30} // end namespace
31
32//! Constructor
33CArchiveLoaderPAK::CArchiveLoaderPAK( io::IFileSystem* fs)
34: FileSystem(fs)
35{
36#ifdef _DEBUG
37 setDebugName("CArchiveLoaderPAK");
38#endif
39}
40
41
42//! returns true if the file maybe is able to be loaded by this class
43bool CArchiveLoaderPAK::isALoadableFileFormat(const io::path& filename) const
44{
45 return core::hasFileExtension(filename, "pak");
46}
47
48//! Check to see if the loader can create archives of this type.
49bool CArchiveLoaderPAK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
50{
51 return fileType == EFAT_PAK;
52}
53
54//! Creates an archive from the filename
55/** \param file File handle to check.
56\return Pointer to newly created archive, or 0 upon error. */
57IFileArchive* CArchiveLoaderPAK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const
58{
59 IFileArchive *archive = 0;
60 io::IReadFile* file = FileSystem->createAndOpenFile(filename);
61
62 if (file)
63 {
64 archive = createArchive(file, ignoreCase, ignorePaths);
65 file->drop ();
66 }
67
68 return archive;
69}
70
71//! creates/loads an archive from the file.
72//! \return Pointer to the created archive. Returns 0 if loading failed.
73IFileArchive* CArchiveLoaderPAK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
74{
75 IFileArchive *archive = 0;
76 if ( file )
77 {
78 file->seek ( 0 );
79 archive = new CPakReader(file, ignoreCase, ignorePaths);
80 }
81 return archive;
82}
83
84
85//! Check if the file might be loaded by this class
86/** Check might look into the file.
87\param file File handle to check.
88\return True if file seems to be loadable. */
89bool CArchiveLoaderPAK::isALoadableFileFormat(io::IReadFile* file) const
90{
91 SPAKFileHeader header;
92
93 file->read(&header, sizeof(header));
94
95 return isHeaderValid(header);
96}
97
98
99/*!
100 PAK Reader
101*/
102CPakReader::CPakReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
103: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file)
104{
105#ifdef _DEBUG
106 setDebugName("CPakReader");
107#endif
108
109 if (File)
110 {
111 File->grab();
112 scanLocalHeader();
113 sort();
114 }
115}
116
117
118CPakReader::~CPakReader()
119{
120 if (File)
121 File->drop();
122}
123
124
125const IFileList* CPakReader::getFileList() const
126{
127 return this;
128}
129
130bool CPakReader::scanLocalHeader()
131{
132 SPAKFileHeader header;
133
134 // Read and validate the header
135 File->read(&header, sizeof(header));
136 if (!isHeaderValid(header))
137 return false;
138
139 // Seek to the table of contents
140#ifdef __BIG_ENDIAN__
141 header.offset = os::Byteswap::byteswap(header.offset);
142 header.length = os::Byteswap::byteswap(header.length);
143#endif
144 File->seek(header.offset);
145
146 const int numberOfFiles = header.length / sizeof(SPAKFileEntry);
147
148 // Loop through each entry in the table of contents
149 for(int i = 0; i < numberOfFiles; i++)
150 {
151 // read an entry
152 SPAKFileEntry entry;
153 File->read(&entry, sizeof(entry));
154
155#ifdef _DEBUG
156 os::Printer::log(entry.name);
157#endif
158
159#ifdef __BIG_ENDIAN__
160 entry.offset = os::Byteswap::byteswap(entry.offset);
161 entry.length = os::Byteswap::byteswap(entry.length);
162#endif
163
164 addItem(io::path(entry.name), entry.offset, entry.length, false );
165 }
166 return true;
167}
168
169
170//! opens a file by file name
171IReadFile* CPakReader::createAndOpenFile(const io::path& filename)
172{
173 s32 index = findFile(filename, false);
174
175 if (index != -1)
176 return createAndOpenFile(index);
177
178 return 0;
179}
180
181
182//! opens a file by index
183IReadFile* CPakReader::createAndOpenFile(u32 index)
184{
185 if (index >= Files.size() )
186 return 0;
187
188 const SFileListEntry &entry = Files[index];
189 return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
190}
191
192} // end namespace io
193} // end namespace irr
194
195#endif // __IRR_COMPILE_WITH_PAK_ARCHIVE_LOADER_
196