The problem...
While i was busy writing a class to write Zip archives for irrlicht, i noticed that although 7-zip could open the zip file, irrlicht gave a ireadfile* object that had an infinately large buffer size...
hmm... changing my zip file a bit to seek back to the local header, i wrote the datadescriptor there and bam... irrlicht could open that...
however, depending on the type of iwritefile*, if it doesn't support seeking that would be a problem... plus, why wouldn't irrlicht load the extended local header to provide compatibility with all zip files...
Summary:
Irrlicht doesn't support extended datadescriptors properly, yet..
Solution...
I looked through the CZipReader and easily enough i see that irrlicht expects the datadescriptor to be straight after the local header...
but in fact it is after the compressed data...
so all you have to do is read ahead till you get to the extended headers signature, then seek back (all ireadfile* objects should supply seek functionality) then read the datadescriptor
easy enough...
heres the patch... in CZipReader::scanLocalHeader() just after you skip the extra information add:
Code: Select all
// this is the data block
entry.fileDataPosition = File->getPos();
// if bit 3 was set, read DataDescriptor, following after the compressed data
if (entry.header.GeneralBitFlag & ZIP_INFO_IN_DATA_DESCRITOR)
{
s32 pos = File->getPos();
c8 _char = 0;
bool found_ext = false;
while(!found_ext && File->getPos() != File->getSize())
{
c8 oldchar = _char;
File->read(&_char, 1);
if(oldchar == 0x50 && _char == 0x4B)
{
found_ext = true;
File->read(&_char, 1);
File->read(&_char, 1);
}
}
if(found_ext)
{
// read data descriptor
File->read(&entry.header.DataDescriptor, sizeof(entry.header.DataDescriptor));
#ifdef __BIG_ENDIAN__
entry.header.DataDescriptor.CRC32 = os::Byteswap::byteswap(entry.header.DataDescriptor.CRC32);
entry.header.DataDescriptor.CompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.CompressedSize);
entry.header.DataDescriptor.UncompressedSize = os::Byteswap::byteswap(entry.header.DataDescriptor.UncompressedSize);
#endif
}
else
{
os::Printer::log("Zip file data descriptor not found", entry.simpleFileName.c_str(), ELL_ERROR);
return 0;
}
}
else
// we have the info, so move forward length of data
File->seek(entry.header.DataDescriptor.CompressedSize, true);
hopefully niko will edit the code in future versions of irrlicht so i won't have to keep patching it