aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp554
1 files changed, 277 insertions, 277 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp
index fc02786..ce1e39d 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CNPKReader.cpp
@@ -1,277 +1,277 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt 1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// Copyright (C) 2009-2012 Christian Stehno 2// Copyright (C) 2009-2012 Christian Stehno
3// This file is part of the "Irrlicht Engine". 3// This file is part of the "Irrlicht Engine".
4// For conditions of distribution and use, see copyright notice in irrlicht.h 4// For conditions of distribution and use, see copyright notice in irrlicht.h
5// Based on the NPK reader from Irrlicht 5// Based on the NPK reader from Irrlicht
6 6
7#include "CNPKReader.h" 7#include "CNPKReader.h"
8 8
9#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ 9#ifdef __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
10 10
11#include "os.h" 11#include "os.h"
12#include "coreutil.h" 12#include "coreutil.h"
13 13
14#ifdef _DEBUG 14#ifdef _DEBUG
15#define IRR_DEBUG_NPK_READER 15#define IRR_DEBUG_NPK_READER
16#endif 16#endif
17 17
18namespace irr 18namespace irr
19{ 19{
20namespace io 20namespace io
21{ 21{
22 22
23namespace 23namespace
24{ 24{
25 bool isHeaderValid(const SNPKHeader& header) 25 bool isHeaderValid(const SNPKHeader& header)
26 { 26 {
27 const c8* const tag = header.Tag; 27 const c8* const tag = header.Tag;
28 return tag[0] == '0' && 28 return tag[0] == '0' &&
29 tag[1] == 'K' && 29 tag[1] == 'K' &&
30 tag[2] == 'P' && 30 tag[2] == 'P' &&
31 tag[3] == 'N'; 31 tag[3] == 'N';
32 } 32 }
33} // end namespace 33} // end namespace
34 34
35 35
36//! Constructor 36//! Constructor
37CArchiveLoaderNPK::CArchiveLoaderNPK( io::IFileSystem* fs) 37CArchiveLoaderNPK::CArchiveLoaderNPK( io::IFileSystem* fs)
38: FileSystem(fs) 38: FileSystem(fs)
39{ 39{
40#ifdef _DEBUG 40#ifdef _DEBUG
41 setDebugName("CArchiveLoaderNPK"); 41 setDebugName("CArchiveLoaderNPK");
42#endif 42#endif
43} 43}
44 44
45 45
46//! returns true if the file maybe is able to be loaded by this class 46//! returns true if the file maybe is able to be loaded by this class
47bool CArchiveLoaderNPK::isALoadableFileFormat(const io::path& filename) const 47bool CArchiveLoaderNPK::isALoadableFileFormat(const io::path& filename) const
48{ 48{
49 return core::hasFileExtension(filename, "npk"); 49 return core::hasFileExtension(filename, "npk");
50} 50}
51 51
52//! Check to see if the loader can create archives of this type. 52//! Check to see if the loader can create archives of this type.
53bool CArchiveLoaderNPK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const 53bool CArchiveLoaderNPK::isALoadableFileFormat(E_FILE_ARCHIVE_TYPE fileType) const
54{ 54{
55 return fileType == EFAT_NPK; 55 return fileType == EFAT_NPK;
56} 56}
57 57
58//! Creates an archive from the filename 58//! Creates an archive from the filename
59/** \param file File handle to check. 59/** \param file File handle to check.
60\return Pointer to newly created archive, or 0 upon error. */ 60\return Pointer to newly created archive, or 0 upon error. */
61IFileArchive* CArchiveLoaderNPK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const 61IFileArchive* CArchiveLoaderNPK::createArchive(const io::path& filename, bool ignoreCase, bool ignorePaths) const
62{ 62{
63 IFileArchive *archive = 0; 63 IFileArchive *archive = 0;
64 io::IReadFile* file = FileSystem->createAndOpenFile(filename); 64 io::IReadFile* file = FileSystem->createAndOpenFile(filename);
65 65
66 if (file) 66 if (file)
67 { 67 {
68 archive = createArchive(file, ignoreCase, ignorePaths); 68 archive = createArchive(file, ignoreCase, ignorePaths);
69 file->drop (); 69 file->drop ();
70 } 70 }
71 71
72 return archive; 72 return archive;
73} 73}
74 74
75//! creates/loads an archive from the file. 75//! creates/loads an archive from the file.
76//! \return Pointer to the created archive. Returns 0 if loading failed. 76//! \return Pointer to the created archive. Returns 0 if loading failed.
77IFileArchive* CArchiveLoaderNPK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const 77IFileArchive* CArchiveLoaderNPK::createArchive(io::IReadFile* file, bool ignoreCase, bool ignorePaths) const
78{ 78{
79 IFileArchive *archive = 0; 79 IFileArchive *archive = 0;
80 if ( file ) 80 if ( file )
81 { 81 {
82 file->seek ( 0 ); 82 file->seek ( 0 );
83 archive = new CNPKReader(file, ignoreCase, ignorePaths); 83 archive = new CNPKReader(file, ignoreCase, ignorePaths);
84 } 84 }
85 return archive; 85 return archive;
86} 86}
87 87
88 88
89//! Check if the file might be loaded by this class 89//! Check if the file might be loaded by this class
90/** Check might look into the file. 90/** Check might look into the file.
91\param file File handle to check. 91\param file File handle to check.
92\return True if file seems to be loadable. */ 92\return True if file seems to be loadable. */
93bool CArchiveLoaderNPK::isALoadableFileFormat(io::IReadFile* file) const 93bool CArchiveLoaderNPK::isALoadableFileFormat(io::IReadFile* file) const
94{ 94{
95 SNPKHeader header; 95 SNPKHeader header;
96 96
97 file->read(&header, sizeof(header)); 97 file->read(&header, sizeof(header));
98 98
99 return isHeaderValid(header); 99 return isHeaderValid(header);
100} 100}
101 101
102 102
103/*! 103/*!
104 NPK Reader 104 NPK Reader
105*/ 105*/
106CNPKReader::CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths) 106CNPKReader::CNPKReader(IReadFile* file, bool ignoreCase, bool ignorePaths)
107: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file) 107: CFileList((file ? file->getFileName() : io::path("")), ignoreCase, ignorePaths), File(file)
108{ 108{
109#ifdef _DEBUG 109#ifdef _DEBUG
110 setDebugName("CNPKReader"); 110 setDebugName("CNPKReader");
111#endif 111#endif
112 112
113 if (File) 113 if (File)
114 { 114 {
115 File->grab(); 115 File->grab();
116 if (scanLocalHeader()) 116 if (scanLocalHeader())
117 sort(); 117 sort();
118 else 118 else
119 os::Printer::log("Failed to load NPK archive."); 119 os::Printer::log("Failed to load NPK archive.");
120 } 120 }
121} 121}
122 122
123 123
124CNPKReader::~CNPKReader() 124CNPKReader::~CNPKReader()
125{ 125{
126 if (File) 126 if (File)
127 File->drop(); 127 File->drop();
128} 128}
129 129
130 130
131const IFileList* CNPKReader::getFileList() const 131const IFileList* CNPKReader::getFileList() const
132{ 132{
133 return this; 133 return this;
134} 134}
135 135
136 136
137bool CNPKReader::scanLocalHeader() 137bool CNPKReader::scanLocalHeader()
138{ 138{
139 SNPKHeader header; 139 SNPKHeader header;
140 140
141 // Read and validate the header 141 // Read and validate the header
142 File->read(&header, sizeof(header)); 142 File->read(&header, sizeof(header));
143 if (!isHeaderValid(header)) 143 if (!isHeaderValid(header))
144 return false; 144 return false;
145 145
146 // Seek to the table of contents 146 // Seek to the table of contents
147#ifdef __BIG_ENDIAN__ 147#ifdef __BIG_ENDIAN__
148 header.Offset = os::Byteswap::byteswap(header.Offset); 148 header.Offset = os::Byteswap::byteswap(header.Offset);
149 header.Length = os::Byteswap::byteswap(header.Length); 149 header.Length = os::Byteswap::byteswap(header.Length);
150#endif 150#endif
151 header.Offset += 8; 151 header.Offset += 8;
152 core::stringc dirName; 152 core::stringc dirName;
153 bool inTOC=true; 153 bool inTOC=true;
154 // Loop through each entry in the table of contents 154 // Loop through each entry in the table of contents
155 while (inTOC && (File->getPos() < File->getSize())) 155 while (inTOC && (File->getPos() < File->getSize()))
156 { 156 {
157 // read an entry 157 // read an entry
158 char tag[4]={0}; 158 char tag[4]={0};
159 SNPKFileEntry entry; 159 SNPKFileEntry entry;
160 File->read(tag, 4); 160 File->read(tag, 4);
161 const int numTag = MAKE_IRR_ID(tag[3],tag[2],tag[1],tag[0]); 161 const int numTag = MAKE_IRR_ID(tag[3],tag[2],tag[1],tag[0]);
162 int size; 162 int size;
163 163
164 bool isDir=true; 164 bool isDir=true;
165 165
166 switch (numTag) 166 switch (numTag)
167 { 167 {
168 case MAKE_IRR_ID('D','I','R','_'): 168 case MAKE_IRR_ID('D','I','R','_'):
169 { 169 {
170 File->read(&size, 4); 170 File->read(&size, 4);
171 readString(entry.Name); 171 readString(entry.Name);
172 entry.Length=0; 172 entry.Length=0;
173 entry.Offset=0; 173 entry.Offset=0;
174#ifdef IRR_DEBUG_NPK_READER 174#ifdef IRR_DEBUG_NPK_READER
175 os::Printer::log("Dir", entry.Name); 175 os::Printer::log("Dir", entry.Name);
176#endif 176#endif
177 } 177 }
178 break; 178 break;
179 case MAKE_IRR_ID('F','I','L','E'): 179 case MAKE_IRR_ID('F','I','L','E'):
180 { 180 {
181 File->read(&size, 4); 181 File->read(&size, 4);
182 File->read(&entry.Offset, 4); 182 File->read(&entry.Offset, 4);
183 File->read(&entry.Length, 4); 183 File->read(&entry.Length, 4);
184 readString(entry.Name); 184 readString(entry.Name);
185 isDir=false; 185 isDir=false;
186#ifdef IRR_DEBUG_NPK_READER 186#ifdef IRR_DEBUG_NPK_READER
187 os::Printer::log("File", entry.Name); 187 os::Printer::log("File", entry.Name);
188#endif 188#endif
189#ifdef __BIG_ENDIAN__ 189#ifdef __BIG_ENDIAN__
190 entry.Offset = os::Byteswap::byteswap(entry.Offset); 190 entry.Offset = os::Byteswap::byteswap(entry.Offset);
191 entry.Length = os::Byteswap::byteswap(entry.Length); 191 entry.Length = os::Byteswap::byteswap(entry.Length);
192#endif 192#endif
193 } 193 }
194 break; 194 break;
195 case MAKE_IRR_ID('D','E','N','D'): 195 case MAKE_IRR_ID('D','E','N','D'):
196 { 196 {
197 File->read(&size, 4); 197 File->read(&size, 4);
198 entry.Name=""; 198 entry.Name="";
199 entry.Length=0; 199 entry.Length=0;
200 entry.Offset=0; 200 entry.Offset=0;
201 const s32 pos = dirName.findLast('/', dirName.size()-2); 201 const s32 pos = dirName.findLast('/', dirName.size()-2);
202 if (pos==-1) 202 if (pos==-1)
203 dirName=""; 203 dirName="";
204 else 204 else
205 dirName=dirName.subString(0, pos); 205 dirName=dirName.subString(0, pos);
206#ifdef IRR_DEBUG_NPK_READER 206#ifdef IRR_DEBUG_NPK_READER
207 os::Printer::log("Dirend", dirName); 207 os::Printer::log("Dirend", dirName);
208#endif 208#endif
209 } 209 }
210 break; 210 break;
211 default: 211 default:
212 inTOC=false; 212 inTOC=false;
213 } 213 }
214 // skip root dir 214 // skip root dir
215 if (isDir) 215 if (isDir)
216 { 216 {
217 if (!entry.Name.size() || (entry.Name==".") || (entry.Name=="<noname>")) 217 if (!entry.Name.size() || (entry.Name==".") || (entry.Name=="<noname>"))
218 continue; 218 continue;
219 dirName += entry.Name; 219 dirName += entry.Name;
220 dirName += "/"; 220 dirName += "/";
221 } 221 }
222#ifdef IRR_DEBUG_NPK_READER 222#ifdef IRR_DEBUG_NPK_READER
223 os::Printer::log("Name", entry.Name); 223 os::Printer::log("Name", entry.Name);
224#endif 224#endif
225 addItem((isDir?dirName:dirName+entry.Name), entry.Offset+header.Offset, entry.Length, isDir); 225 addItem((isDir?dirName:dirName+entry.Name), entry.Offset+header.Offset, entry.Length, isDir);
226 } 226 }
227 return true; 227 return true;
228} 228}
229 229
230 230
231//! opens a file by file name 231//! opens a file by file name
232IReadFile* CNPKReader::createAndOpenFile(const io::path& filename) 232IReadFile* CNPKReader::createAndOpenFile(const io::path& filename)
233{ 233{
234 s32 index = findFile(filename, false); 234 s32 index = findFile(filename, false);
235 235
236 if (index != -1) 236 if (index != -1)
237 return createAndOpenFile(index); 237 return createAndOpenFile(index);
238 238
239 return 0; 239 return 0;
240} 240}
241 241
242 242
243//! opens a file by index 243//! opens a file by index
244IReadFile* CNPKReader::createAndOpenFile(u32 index) 244IReadFile* CNPKReader::createAndOpenFile(u32 index)
245{ 245{
246 if (index >= Files.size() ) 246 if (index >= Files.size() )
247 return 0; 247 return 0;
248 248
249 const SFileListEntry &entry = Files[index]; 249 const SFileListEntry &entry = Files[index];
250 return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); 250 return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size );
251} 251}
252 252
253void CNPKReader::readString(core::stringc& name) 253void CNPKReader::readString(core::stringc& name)
254{ 254{
255 short stringSize; 255 short stringSize;
256 char buf[256]; 256 char buf[256];
257 File->read(&stringSize, 2); 257 File->read(&stringSize, 2);
258#ifdef __BIG_ENDIAN__ 258#ifdef __BIG_ENDIAN__
259 stringSize = os::Byteswap::byteswap(stringSize); 259 stringSize = os::Byteswap::byteswap(stringSize);
260#endif 260#endif
261 name.reserve(stringSize); 261 name.reserve(stringSize);
262 while(stringSize) 262 while(stringSize)
263 { 263 {
264 const short next = core::min_(stringSize, (short)255); 264 const short next = core::min_(stringSize, (short)255);
265 File->read(buf,next); 265 File->read(buf,next);
266 buf[next]=0; 266 buf[next]=0;
267 name.append(buf); 267 name.append(buf);
268 stringSize -= next; 268 stringSize -= next;
269 } 269 }
270} 270}
271 271
272 272
273} // end namespace io 273} // end namespace io
274} // end namespace irr 274} // end namespace irr
275 275
276#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_ 276#endif // __IRR_COMPILE_WITH_NPK_ARCHIVE_LOADER_
277 277