Make ZipHandler 64-bit throughout.

- although we will probably never deal with 4GB+ files, the underlying stream-reading code is 64-bit anyway
- fixes warnings in 32 <-> 64 bit conversions in OSX.
This commit is contained in:
Stephen Anthony 2018-09-05 11:14:28 -02:30
parent d04dc49c3d
commit cacb1e3341
3 changed files with 28 additions and 28 deletions

View File

@ -193,7 +193,7 @@ uInt32 FilesystemNodeZIP::read(BytePtr& image) const
while(myZipHandler->hasNext() && !found) while(myZipHandler->hasNext() && !found)
found = myZipHandler->next() == _virtualPath; found = myZipHandler->next() == _virtualPath;
return found ? myZipHandler->decompress(image) : 0; return found ? uInt32(myZipHandler->decompress(image)) : 0; // TODO: 64bit
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -103,11 +103,11 @@ const string& ZipHandler::next()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 ZipHandler::decompress(BytePtr& image) uInt64 ZipHandler::decompress(BytePtr& image)
{ {
if(myZip && myZip->myHeader.uncompressedLength > 0) if(myZip && myZip->myHeader.uncompressedLength > 0)
{ {
uInt32 length = myZip->myHeader.uncompressedLength; uInt64 length = myZip->myHeader.uncompressedLength;
image = make_unique<uInt8[]>(length); image = make_unique<uInt8[]>(length);
if(image == nullptr) if(image == nullptr)
throw runtime_error(errorMessage(ZipError::OUT_OF_MEMORY)); throw runtime_error(errorMessage(ZipError::OUT_OF_MEMORY));
@ -243,7 +243,7 @@ void ZipHandler::ZipFile::initialize()
throw ZipError::OUT_OF_MEMORY; throw ZipError::OUT_OF_MEMORY;
// Read the central directory // Read the central directory
uInt32 read_length = 0; uInt64 read_length = 0;
bool success = readStream(myCd, myEcd.cdStartDiskOffset, myEcd.cdSize, read_length); bool success = readStream(myCd, myEcd.cdStartDiskOffset, myEcd.cdSize, read_length);
if(!success) if(!success)
throw ZipError::FILE_ERROR; throw ZipError::FILE_ERROR;
@ -266,13 +266,13 @@ void ZipHandler::ZipFile::close()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ZipHandler::ZipFile::readEcd() void ZipHandler::ZipFile::readEcd()
{ {
uInt32 buflen = 1024; uInt64 buflen = 1024;
BytePtr buffer; BytePtr buffer;
// We may need multiple tries // We may need multiple tries
while(buflen < 65536) while(buflen < 65536)
{ {
uInt32 read_length; uInt64 read_length;
// Max out the buf length at the size of the file // Max out the buf length at the size of the file
if(buflen > myLength) if(buflen > myLength)
@ -321,15 +321,15 @@ void ZipHandler::ZipFile::readEcd()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ZipHandler::ZipFile::readStream(BytePtr& out, uInt32 offset, bool ZipHandler::ZipFile::readStream(BytePtr& out, uInt64 offset,
uInt32 length, uInt32& actual) uInt64 length, uInt64& actual)
{ {
try try
{ {
myStream.seekg(offset); myStream.seekg(offset);
myStream.read(reinterpret_cast<char*>(out.get()), length); myStream.read(reinterpret_cast<char*>(out.get()), length);
actual = uInt32(myStream.gcount()); actual = myStream.gcount();
return true; return true;
} }
catch(...) catch(...)
@ -365,7 +365,7 @@ const ZipHandler::ZipHeader* const ZipHandler::ZipFile::nextFile()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ZipHandler::ZipFile::decompress(BytePtr& out, uInt32 length) void ZipHandler::ZipFile::decompress(BytePtr& out, uInt64 length)
{ {
// If we don't have enough buffer, error // If we don't have enough buffer, error
if(length < myHeader.uncompressedLength) if(length < myHeader.uncompressedLength)
@ -378,7 +378,7 @@ void ZipHandler::ZipFile::decompress(BytePtr& out, uInt32 length)
try try
{ {
// Get the compressed data offset // Get the compressed data offset
uInt32 offset = getCompressedDataOffset(); uInt64 offset = getCompressedDataOffset();
// Handle compression types // Handle compression types
switch(myHeader.compression) switch(myHeader.compression)
@ -402,10 +402,10 @@ void ZipHandler::ZipFile::decompress(BytePtr& out, uInt32 length)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 ZipHandler::ZipFile::getCompressedDataOffset() uInt64 ZipHandler::ZipFile::getCompressedDataOffset()
{ {
// Read the fixed-sized part of the local file header // Read the fixed-sized part of the local file header
uInt32 read_length = 0; uInt64 read_length = 0;
bool success = readStream(myBuffer, myHeader.localHeaderOffset, 0x1e, read_length); bool success = readStream(myBuffer, myHeader.localHeaderOffset, 0x1e, read_length);
if(!success) if(!success)
throw ZipError::FILE_ERROR; throw ZipError::FILE_ERROR;
@ -420,10 +420,10 @@ uInt32 ZipHandler::ZipFile::getCompressedDataOffset()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ZipHandler::ZipFile::decompressDataType0( void ZipHandler::ZipFile::decompressDataType0(
uInt32 offset, BytePtr& out, uInt32 length) uInt64 offset, BytePtr& out, uInt64 length)
{ {
// The data is uncompressed; just read it // The data is uncompressed; just read it
uInt32 read_length = 0; uInt64 read_length = 0;
bool success = readStream(out, offset, myHeader.compressedLength, read_length); bool success = readStream(out, offset, myHeader.compressedLength, read_length);
if(!success) if(!success)
throw ZipError::FILE_ERROR; throw ZipError::FILE_ERROR;
@ -433,9 +433,9 @@ void ZipHandler::ZipFile::decompressDataType0(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ZipHandler::ZipFile::decompressDataType8( void ZipHandler::ZipFile::decompressDataType8(
uInt32 offset, BytePtr& out, uInt32 length) uInt64 offset, BytePtr& out, uInt64 length)
{ {
uInt32 input_remaining = myHeader.compressedLength; uInt64 input_remaining = myHeader.compressedLength;
// Reset the stream // Reset the stream
z_stream stream; z_stream stream;
@ -444,7 +444,7 @@ void ZipHandler::ZipFile::decompressDataType8(
stream.opaque = Z_NULL; stream.opaque = Z_NULL;
stream.avail_in = 0; stream.avail_in = 0;
stream.next_out = reinterpret_cast<Bytef *>(out.get()); stream.next_out = reinterpret_cast<Bytef *>(out.get());
stream.avail_out = length; stream.avail_out = uInt32(length); // TODO - use zip64
// Initialize the decompressor // Initialize the decompressor
int zerr = inflateInit2(&stream, -MAX_WBITS); int zerr = inflateInit2(&stream, -MAX_WBITS);
@ -455,9 +455,9 @@ void ZipHandler::ZipFile::decompressDataType8(
for(;;) for(;;)
{ {
// Read in the next chunk of data // Read in the next chunk of data
uInt32 read_length = 0; uInt64 read_length = 0;
bool success = readStream(myBuffer, offset, bool success = readStream(myBuffer, offset,
std::min(input_remaining, uInt32(sizeof(myBuffer.get()))), read_length); std::min(input_remaining, uInt64(sizeof(myBuffer.get()))), read_length);
if(!success) if(!success)
{ {
inflateEnd(&stream); inflateEnd(&stream);
@ -474,7 +474,7 @@ void ZipHandler::ZipFile::decompressDataType8(
// Fill out the input data // Fill out the input data
stream.next_in = myBuffer.get(); stream.next_in = myBuffer.get();
stream.avail_in = read_length; stream.avail_in = uInt32(read_length); // TODO - use zip64
input_remaining -= read_length; input_remaining -= read_length;
// Add a dummy byte at end of compressed data // Add a dummy byte at end of compressed data

View File

@ -45,7 +45,7 @@ class ZipHandler
// Decompress the currently selected file and return its length // Decompress the currently selected file and return its length
// An exception will be thrown on any errors // An exception will be thrown on any errors
uInt32 decompress(BytePtr& image); uInt64 decompress(BytePtr& image);
// Answer the number of ROM files (with a valid extension) found // Answer the number of ROM files (with a valid extension) found
uInt16 romFiles() const { return myZip ? myZip->myRomfiles : 0; } uInt16 romFiles() const { return myZip ? myZip->myRomfiles : 0; }
@ -105,7 +105,7 @@ class ZipHandler
{ {
string myFilename; // copy of ZIP filename (for caching) string myFilename; // copy of ZIP filename (for caching)
fstream myStream; // C++ fstream file handle fstream myStream; // C++ fstream file handle
uInt32 myLength; // length of zip file uInt64 myLength; // length of zip file
uInt16 myRomfiles; // number of ROM files in central directory uInt16 myRomfiles; // number of ROM files in central directory
ZipEcd myEcd; // end of central directory ZipEcd myEcd; // end of central directory
@ -132,22 +132,22 @@ class ZipHandler
void readEcd(); void readEcd();
/** Read data from stream */ /** Read data from stream */
bool readStream(BytePtr& out, uInt32 offset, uInt32 length, uInt32& actual); bool readStream(BytePtr& out, uInt64 offset, uInt64 length, uInt64& actual);
/** Return the next entry in the ZIP file */ /** Return the next entry in the ZIP file */
const ZipHeader* const nextFile(); const ZipHeader* const nextFile();
/** Decompress the most recently found file in the ZIP into target buffer */ /** Decompress the most recently found file in the ZIP into target buffer */
void decompress(BytePtr& out, uInt32 length); void decompress(BytePtr& out, uInt64 length);
/** Return the offset of the compressed data */ /** Return the offset of the compressed data */
uInt32 getCompressedDataOffset(); uInt64 getCompressedDataOffset();
/** Decompress type 0 data (which is uncompressed) */ /** Decompress type 0 data (which is uncompressed) */
void decompressDataType0(uInt32 offset, BytePtr& out, uInt32 length); void decompressDataType0(uInt64 offset, BytePtr& out, uInt64 length);
/** Decompress type 8 data (which is deflated) */ /** Decompress type 8 data (which is deflated) */
void decompressDataType8(uInt32 offset, BytePtr& out, uInt32 length); void decompressDataType8(uInt64 offset, BytePtr& out, uInt64 length);
}; };
using ZipFilePtr = unique_ptr<ZipFile>; using ZipFilePtr = unique_ptr<ZipFile>;