//! opens a file by index IReadFile* CTarReader::createAndOpenFile(u32 index) { if (index < Files.size()) return createLimitReadFile(Files[index].FullName, File, Offsets[Files[index].ID], Files[index].Size); else return 0; }
//! opens a file by index IReadFile* CWADReader::createAndOpenFile(u32 index) { if (index >= Files.size() ) return 0; const SFileListEntry &entry = Files[index]; return createLimitReadFile( entry.FullName, File, entry.Offset, entry.Size ); }
//! opens a file by index IReadFile* CPakReader::openFile(s32 index) { File->seek(FileList[index].pos); return createLimitReadFile(FileList[index].simpleFileName.c_str(), File, FileList[index].length); }
//! opens a file by index IReadFile* CZipReader::createAndOpenFile(u32 index) { // Irrlicht supports 0, 8, 12, 14, 99 //0 - The file is stored (no compression) //1 - The file is Shrunk //2 - The file is Reduced with compression factor 1 //3 - The file is Reduced with compression factor 2 //4 - The file is Reduced with compression factor 3 //5 - The file is Reduced with compression factor 4 //6 - The file is Imploded //7 - Reserved for Tokenizing compression algorithm //8 - The file is Deflated //9 - Reserved for enhanced Deflating //10 - PKWARE Date Compression Library Imploding //12 - bzip2 - Compression Method from libbz2, WinZip 10 //14 - LZMA - Compression Method, WinZip 12 //96 - Jpeg compression - Compression Method, WinZip 12 //97 - WavPack - Compression Method, WinZip 11 //98 - PPMd - Compression Method, WinZip 10 //99 - AES encryption, WinZip 9 const SZipFileEntry &e = FileInfo[Files[index].ID]; wchar_t buf[64]; s16 actualCompressionMethod=e.header.CompressionMethod; IReadFile* decrypted=0; u8* decryptedBuf=0; u32 decryptedSize=e.header.DataDescriptor.CompressedSize; switch(actualCompressionMethod) { case 0: // no compression { if (decrypted) return decrypted; else return createLimitReadFile(Files[index].FullName, File, e.Offset, decryptedSize); } case 8: { #ifdef _IRR_COMPILE_WITH_ZLIB_ const u32 uncompressedSize = e.header.DataDescriptor.UncompressedSize; c8* pBuf = new c8[ uncompressedSize ]; if (!pBuf) { swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); os::Printer::log( buf, ELL_ERROR); if (decrypted) decrypted->drop(); return 0; } u8 *pcData = decryptedBuf; if (!pcData) { pcData = new u8[decryptedSize]; if (!pcData) { swprintf ( buf, 64, L"Not enough memory for decompressing %s", Files[index].FullName.c_str() ); os::Printer::log( buf, ELL_ERROR); delete [] pBuf; return 0; } //memset(pcData, 0, decryptedSize); File->seek(e.Offset); File->read(pcData, decryptedSize); } // Setup the inflate stream. z_stream stream; s32 err; stream.next_in = (Bytef*)pcData; stream.avail_in = (uInt)decryptedSize; stream.next_out = (Bytef*)pBuf; stream.avail_out = uncompressedSize; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; // Perform inflation. wbits < 0 indicates no zlib header inside the data. err = inflateInit2(&stream, -MAX_WBITS); if (err == Z_OK) { err = inflate(&stream, Z_FINISH); inflateEnd(&stream); if (err == Z_STREAM_END) err = Z_OK; err = Z_OK; inflateEnd(&stream); } if (decrypted) decrypted->drop(); else delete[] pcData; if (err != Z_OK) { swprintf ( buf, 64, L"Error decompressing %s", Files[index].FullName.c_str() ); os::Printer::log( buf, ELL_ERROR); delete [] pBuf; return 0; } else return io::createMemoryReadFile(pBuf, uncompressedSize, Files[index].FullName, true); #else return 0; // zlib not compiled, we cannot decompress the data. #endif } case 12: { os::Printer::log("bzip2 decompression not supported. File cannot be read.", ELL_ERROR); return 0; } case 14: { os::Printer::log("lzma decompression not supported. File cannot be read.", ELL_ERROR); return 0; } case 99: // If we come here with an encrypted file, decryption support is missing os::Printer::log("Decryption support not enabled. File cannot be read.", ELL_ERROR); return 0; default: swprintf ( buf, 64, L"file has unsupported compression method. %s", Files[index].FullName.c_str() ); os::Printer::log( buf, ELL_ERROR); return 0; }; }
//! opens a file by index IReadFile* CZipReader::openFile(s32 index) { //0 - The file is stored (no compression) //1 - The file is Shrunk //2 - The file is Reduced with compression factor 1 //3 - The file is Reduced with compression factor 2 //4 - The file is Reduced with compression factor 3 //5 - The file is Reduced with compression factor 4 //6 - The file is Imploded //7 - Reserved for Tokenizing compression algorithm //8 - The file is Deflated //9 - Reserved for enhanced Deflating //10 - PKWARE Date Compression Library Imploding switch(FileList[index].header.CompressionMethod) { case 0: // no compression { File->seek(FileList[index].fileDataPosition); return createLimitReadFile(FileList[index].simpleFileName.c_str(), File, FileList[index].header.DataDescriptor.UncompressedSize); } case 8: { #ifdef _IRR_COMPILE_WITH_ZLIB_ u32 uncompressedSize = FileList[index].header.DataDescriptor.UncompressedSize; u32 compressedSize = FileList[index].header.DataDescriptor.CompressedSize; void* pBuf = new c8[ uncompressedSize ]; if (!pBuf) { os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); return 0; } c8 *pcData = new c8[ compressedSize ]; if (!pcData) { os::Printer::log("Not enough memory for decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); return 0; } //memset(pcData, 0, compressedSize ); File->seek(FileList[index].fileDataPosition); File->read(pcData, compressedSize ); // Setup the inflate stream. z_stream stream; s32 err; stream.next_in = (Bytef*)pcData; stream.avail_in = (uInt)compressedSize; stream.next_out = (Bytef*)pBuf; stream.avail_out = uncompressedSize; stream.zalloc = (alloc_func)0; stream.zfree = (free_func)0; // Perform inflation. wbits < 0 indicates no zlib header inside the data. err = inflateInit2(&stream, -MAX_WBITS); if (err == Z_OK) { err = inflate(&stream, Z_FINISH); inflateEnd(&stream); if (err == Z_STREAM_END) err = Z_OK; err = Z_OK; inflateEnd(&stream); } delete[] pcData; if (err != Z_OK) { os::Printer::log("Error decompressing", FileList[index].simpleFileName.c_str(), ELL_ERROR); delete [] (c8*)pBuf; return 0; } else return io::createMemoryReadFile ( pBuf, uncompressedSize, FileList[index].zipFileName.c_str(), true ); #else return 0; // zlib not compiled, we cannot decompress the data. #endif } default: os::Printer::log("file has unsupported compression method.", FileList[index].simpleFileName.c_str(), ELL_ERROR); return 0; }; }