generalize zip reading
This commit is contained in:
@@ -55,8 +55,26 @@ RageFileDriverZip::RageFileDriverZip( CString path ):
|
|||||||
RageFileDriver( new NullFilenameDB ),
|
RageFileDriver( new NullFilenameDB ),
|
||||||
m_Mutex( ssprintf("RageFileDriverZip(%s)", path.c_str()) )
|
m_Mutex( ssprintf("RageFileDriverZip(%s)", path.c_str()) )
|
||||||
{
|
{
|
||||||
if( !zip.Open(path) )
|
m_bFileOwned = true;
|
||||||
RageException::Throw( "Couldn't open %s: %s", path.c_str(), zip.GetError().c_str() );
|
m_sPath = path;
|
||||||
|
|
||||||
|
RageFile *pFile = new RageFile;
|
||||||
|
m_pZip = pFile;
|
||||||
|
|
||||||
|
if( !pFile->Open(path) )
|
||||||
|
RageException::Throw( "Couldn't open %s: %s", path.c_str(), pFile->GetError().c_str() );
|
||||||
|
|
||||||
|
ParseZipfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
RageFileDriverZip::RageFileDriverZip( RageFileBasic *pFile ):
|
||||||
|
RageFileDriver( new NullFilenameDB ),
|
||||||
|
m_Mutex( ssprintf("RageFileDriverZip(%p)", pFile) )
|
||||||
|
{
|
||||||
|
m_sPath = ssprintf("%p", pFile);
|
||||||
|
|
||||||
|
m_bFileOwned = false;
|
||||||
|
m_pZip = pFile;
|
||||||
|
|
||||||
ParseZipfile();
|
ParseZipfile();
|
||||||
}
|
}
|
||||||
@@ -83,9 +101,9 @@ static unsigned long makelong(const unsigned char *sig)
|
|||||||
+ ((unsigned long)sig[0]);
|
+ ((unsigned long)sig[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageFileDriverZip::ReadEndCentralRecord( RageFile &zip, end_central_dir_record &ec )
|
void RageFileDriverZip::ReadEndCentralRecord( end_central_dir_record &ec )
|
||||||
{
|
{
|
||||||
const int OrigPos = zip.Tell();
|
const int OrigPos = m_pZip->Tell();
|
||||||
typedef unsigned char ec_byte_rec[ ECREC_SIZE+4 ];
|
typedef unsigned char ec_byte_rec[ ECREC_SIZE+4 ];
|
||||||
#define NUMBER_THIS_DISK 4
|
#define NUMBER_THIS_DISK 4
|
||||||
#define NUM_DISK_WITH_START_CENTRAL_DIR 6
|
#define NUM_DISK_WITH_START_CENTRAL_DIR 6
|
||||||
@@ -96,11 +114,11 @@ void RageFileDriverZip::ReadEndCentralRecord( RageFile &zip, end_central_dir_rec
|
|||||||
#define ZIPFILE_COMMENT_LENGTH 20
|
#define ZIPFILE_COMMENT_LENGTH 20
|
||||||
|
|
||||||
ec_byte_rec byterec;
|
ec_byte_rec byterec;
|
||||||
const int got = zip.Read( byterec, ECREC_SIZE+4 );
|
const int got = m_pZip->Read( byterec, ECREC_SIZE+4 );
|
||||||
if( got == -1 )
|
if( got == -1 )
|
||||||
RageException::Throw( "Couldn't open %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Couldn't open %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if ( got != ECREC_SIZE+4 )
|
if ( got != ECREC_SIZE+4 )
|
||||||
RageException::Throw( "%s: unexpected EOF", zip.GetPath().c_str() );
|
RageException::Throw( "%s: unexpected EOF", m_sPath.c_str() );
|
||||||
|
|
||||||
ec.number_this_disk = makeword(&byterec[NUMBER_THIS_DISK]);
|
ec.number_this_disk = makeword(&byterec[NUMBER_THIS_DISK]);
|
||||||
ec.num_disk_start_cdir = makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
|
ec.num_disk_start_cdir = makeword(&byterec[NUM_DISK_WITH_START_CENTRAL_DIR]);
|
||||||
@@ -112,19 +130,19 @@ void RageFileDriverZip::ReadEndCentralRecord( RageFile &zip, end_central_dir_rec
|
|||||||
|
|
||||||
const int expect_ecrec_offset = ec.offset_start_central_directory + ec.size_central_directory;
|
const int expect_ecrec_offset = ec.offset_start_central_directory + ec.size_central_directory;
|
||||||
if( expect_ecrec_offset > OrigPos )
|
if( expect_ecrec_offset > OrigPos )
|
||||||
RageException::Throw( "Couldn't open %s: missing %ld bytes in zipfile", zip.GetPath().c_str(),
|
RageException::Throw( "Couldn't open %s: missing %ld bytes in zipfile", m_sPath.c_str(),
|
||||||
expect_ecrec_offset - OrigPos );
|
expect_ecrec_offset - OrigPos );
|
||||||
}
|
}
|
||||||
|
|
||||||
void RageFileDriverZip::ParseZipfile()
|
void RageFileDriverZip::ParseZipfile()
|
||||||
{
|
{
|
||||||
/* Look for the end-central record. */
|
/* Look for the end-central record. */
|
||||||
const int searchlen = min( zip.GetFileSize(), 66000 );
|
const int searchlen = min( m_pZip->GetFileSize(), 66000 );
|
||||||
const int Size = zip.GetFileSize();
|
const int Size = m_pZip->GetFileSize();
|
||||||
int realpos = Size;
|
int realpos = Size;
|
||||||
|
|
||||||
/* Loop through blocks of data, starting at the end. In general, need not
|
/* Loop through blocks of data, starting at the end. In general, need not
|
||||||
* check whole zipfile for signature, but may want to do so if testing. */
|
* check whole zim_pZip for signature, but may want to do so if testing. */
|
||||||
|
|
||||||
int real_ecrec_offset = -1;
|
int real_ecrec_offset = -1;
|
||||||
|
|
||||||
@@ -134,15 +152,15 @@ void RageFileDriverZip::ParseZipfile()
|
|||||||
{
|
{
|
||||||
realpos -= INBUFSIZE;
|
realpos -= INBUFSIZE;
|
||||||
realpos = max( 0, realpos );
|
realpos = max( 0, realpos );
|
||||||
zip.Seek( realpos );
|
m_pZip->Seek( realpos );
|
||||||
int got = zip.Read( tmp+tmp_used, sizeof(tmp)-tmp_used );
|
int got = m_pZip->Read( tmp+tmp_used, sizeof(tmp)-tmp_used );
|
||||||
if( got == -1 )
|
if( got == -1 )
|
||||||
RageException::Throw( "Couldn't open %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Couldn't open %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if( got == 0 )
|
if( got == 0 )
|
||||||
break; /* fall through and fail */
|
break; /* fall through and fail */
|
||||||
got += tmp_used;
|
got += tmp_used;
|
||||||
|
|
||||||
/* 'P' must be at least (ECREC_SIZE+4) bytes from end of zipfile */
|
/* 'P' must be at least (ECREC_SIZE+4) bytes from end of zim_pZip */
|
||||||
for( int pos = got-(ECREC_SIZE+4); real_ecrec_offset == -1 && pos >= 0; --pos )
|
for( int pos = got-(ECREC_SIZE+4); real_ecrec_offset == -1 && pos >= 0; --pos )
|
||||||
{
|
{
|
||||||
const char *p = tmp+pos;
|
const char *p = tmp+pos;
|
||||||
@@ -160,34 +178,34 @@ void RageFileDriverZip::ParseZipfile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( real_ecrec_offset == -1 )
|
if( real_ecrec_offset == -1 )
|
||||||
RageException::Throw( "Couldn't open %s: End-of-central-directory signature not found", zip.GetPath().c_str() );
|
RageException::Throw( "Couldn't open %s: End-of-central-directory signature not found", m_sPath.c_str() );
|
||||||
|
|
||||||
zip.Seek( real_ecrec_offset );
|
m_pZip->Seek( real_ecrec_offset );
|
||||||
|
|
||||||
/* Get the end-central data. */
|
/* Get the end-central data. */
|
||||||
end_central_dir_record ec;
|
end_central_dir_record ec;
|
||||||
ReadEndCentralRecord( zip, ec );
|
ReadEndCentralRecord( ec );
|
||||||
|
|
||||||
bool something = ec.number_this_disk == 1 && ec.num_disk_start_cdir == 1;
|
bool something = ec.number_this_disk == 1 && ec.num_disk_start_cdir == 1;
|
||||||
if (!something && ec.number_this_disk != 0)
|
if (!something && ec.number_this_disk != 0)
|
||||||
RageException::Throw( "Couldn't open %s: zipfile is part of multi-disk archive", zip.GetPath().c_str() );
|
RageException::Throw( "Couldn't open %s: zipfile is part of multi-disk archive", m_sPath.c_str() );
|
||||||
|
|
||||||
/* Seek to where the start of central directory should be, and make
|
/* Seek to where the start of central directory should be, and make
|
||||||
* sure it's there. */
|
* sure it's there. */
|
||||||
zip.Seek( ec.offset_start_central_directory );
|
m_pZip->Seek( ec.offset_start_central_directory );
|
||||||
|
|
||||||
CString sig;
|
CString sig;
|
||||||
int got = zip.Read( sig, 4 );
|
int got = m_pZip->Read( sig, 4 );
|
||||||
if( got != 4 || sig != central_hdr_sig )
|
if( got != 4 || sig != central_hdr_sig )
|
||||||
RageException::Throw( "Couldn't open %s: start of central directory not found; zipfile corrupt", zip.GetPath().c_str() );
|
RageException::Throw( "Couldn't open %s: start of central directory not found; zipfile corrupt", m_sPath.c_str() );
|
||||||
|
|
||||||
zip.Seek( ec.offset_start_central_directory );
|
m_pZip->Seek( ec.offset_start_central_directory );
|
||||||
|
|
||||||
/* Loop through files in central directory. */
|
/* Loop through files in central directory. */
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
CString sig;
|
CString sig;
|
||||||
if ( zip.Read( sig, 4 ) != 4 )
|
if ( m_pZip->Read( sig, 4 ) != 4 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Is it a new entry? */
|
/* Is it a new entry? */
|
||||||
@@ -199,22 +217,22 @@ void RageFileDriverZip::ParseZipfile()
|
|||||||
{
|
{
|
||||||
/* Are we at the end_central record? */
|
/* Are we at the end_central record? */
|
||||||
if( sig != end_central_sig )
|
if( sig != end_central_sig )
|
||||||
LOG->Warn( "%s: expected end central file header signature not found", zip.GetPath().c_str() );
|
LOG->Warn( "%s: expected end central file header signature not found", m_sPath.c_str() );
|
||||||
} else {
|
} else {
|
||||||
LOG->Warn( "%s: expected central file header signature not found", zip.GetPath().c_str() );
|
LOG->Warn( "%s: expected central file header signature not found", m_sPath.c_str() );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo info;
|
FileInfo info;
|
||||||
info.data_offset = -1;
|
info.data_offset = -1;
|
||||||
int got = ProcessCdirFileHdr(zip, info);
|
int got = ProcessCdirFileHdr( info );
|
||||||
if( got == -1 ) /* error */
|
if( got == -1 ) /* error */
|
||||||
break;
|
break;
|
||||||
if( got == 0 ) /* skip */
|
if( got == 0 ) /* skip */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
zip.Seek( zip.Tell() + info.extra_field_length );
|
m_pZip->Seek( m_pZip->Tell() + info.extra_field_length );
|
||||||
|
|
||||||
FileInfo *pInfo = new FileInfo(info);
|
FileInfo *pInfo = new FileInfo(info);
|
||||||
Files.push_back( pInfo );
|
Files.push_back( pInfo );
|
||||||
@@ -241,19 +259,19 @@ typedef unsigned char cdir_byte_hdr[ CREC_SIZE ];
|
|||||||
#define C_INTERNAL_FILE_ATTRIBUTES 32
|
#define C_INTERNAL_FILE_ATTRIBUTES 32
|
||||||
#define C_EXTERNAL_FILE_ATTRIBUTES 34
|
#define C_EXTERNAL_FILE_ATTRIBUTES 34
|
||||||
#define C_RELATIVE_OFFSET_LOCAL_HEADER 38
|
#define C_RELATIVE_OFFSET_LOCAL_HEADER 38
|
||||||
int RageFileDriverZip::ProcessCdirFileHdr( RageFile &zip, FileInfo &info )
|
int RageFileDriverZip::ProcessCdirFileHdr( FileInfo &info )
|
||||||
{
|
{
|
||||||
/* Read the next central directory entry and do any necessary machine-type
|
/* Read the next central directory entry and do any necessary machine-type
|
||||||
* conversions (byte ordering, structure padding compensation--do so by
|
* conversions (byte ordering, structure padding compensation--do so by
|
||||||
* copying the data from the array into which it was read (byterec) to the
|
* copying the data from the array into which it was read (byterec) to the
|
||||||
* usable struct. */
|
* usable struct. */
|
||||||
cdir_byte_hdr byterec;
|
cdir_byte_hdr byterec;
|
||||||
int got = zip.Read( (char *)byterec, CREC_SIZE );
|
int got = m_pZip->Read( (char *)byterec, CREC_SIZE );
|
||||||
if ( got == -1 )
|
if ( got == -1 )
|
||||||
RageException::Throw( "Couldn't open %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Couldn't open %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if ( got != CREC_SIZE )
|
if ( got != CREC_SIZE )
|
||||||
{
|
{
|
||||||
LOG->Warn( "%s: unexpected EOF", zip.GetPath().c_str() );
|
LOG->Warn( "%s: unexpected EOF", m_sPath.c_str() );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +281,7 @@ int RageFileDriverZip::ProcessCdirFileHdr( RageFile &zip, FileInfo &info )
|
|||||||
if( version_needed_to_extract > 20 ) /* compatible with PKUNZIP 2.0 */
|
if( version_needed_to_extract > 20 ) /* compatible with PKUNZIP 2.0 */
|
||||||
{
|
{
|
||||||
LOG->Warn( "File \"%s\" in \"%s\" uses unsupported ZIP version %i.%i",
|
LOG->Warn( "File \"%s\" in \"%s\" uses unsupported ZIP version %i.%i",
|
||||||
info.fn.c_str(), zip.GetRealPath().c_str(),
|
info.fn.c_str(), m_sPath.c_str(),
|
||||||
version_needed_to_extract / 10, version_needed_to_extract % 10 );
|
version_needed_to_extract / 10, version_needed_to_extract % 10 );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -271,8 +289,7 @@ int RageFileDriverZip::ProcessCdirFileHdr( RageFile &zip, FileInfo &info )
|
|||||||
const int general_purpose_bit_flag = makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
|
const int general_purpose_bit_flag = makeword(&byterec[C_GENERAL_PURPOSE_BIT_FLAG]);
|
||||||
if( general_purpose_bit_flag & 1 )
|
if( general_purpose_bit_flag & 1 )
|
||||||
{
|
{
|
||||||
LOG->Warn( "Skipped encrypted \"%s\" in \"%s\"",
|
LOG->Warn( "Skipped encrypted \"%s\" in \"%s\"", info.fn.c_str(), m_sPath.c_str() );
|
||||||
info.fn.c_str(), zip.GetRealPath().c_str() );
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,19 +310,19 @@ int RageFileDriverZip::ProcessCdirFileHdr( RageFile &zip, FileInfo &info )
|
|||||||
if( external_file_attributes & 0x08 )
|
if( external_file_attributes & 0x08 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
got = zip.Read( info.fn, info.filename_length );
|
got = m_pZip->Read( info.fn, info.filename_length );
|
||||||
if( got == -1 )
|
if( got == -1 )
|
||||||
RageException::Throw( "Couldn't open %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Couldn't open %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if( got != info.filename_length )
|
if( got != info.filename_length )
|
||||||
{
|
{
|
||||||
LOG->Warn( "%s: bad filename length %li", zip.GetPath().c_str(), info.filename_length );
|
LOG->Warn( "%s: bad filename length %li", m_sPath.c_str(), info.filename_length );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( info.compression_method != STORED && info.compression_method != DEFLATED )
|
if( info.compression_method != STORED && info.compression_method != DEFLATED )
|
||||||
{
|
{
|
||||||
LOG->Warn( "File \"%s\" in \"%s\" uses unsupported compression method %i",
|
LOG->Warn( "File \"%s\" in \"%s\" uses unsupported compression method %i",
|
||||||
info.fn.c_str(), zip.GetRealPath().c_str(), info.compression_method );
|
info.fn.c_str(), m_sPath.c_str(), info.compression_method );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -317,6 +334,9 @@ RageFileDriverZip::~RageFileDriverZip()
|
|||||||
{
|
{
|
||||||
for( unsigned i = 0; i < Files.size(); ++i )
|
for( unsigned i = 0; i < Files.size(); ++i )
|
||||||
delete Files[i];
|
delete Files[i];
|
||||||
|
|
||||||
|
if( m_bFileOwned )
|
||||||
|
delete m_pZip;
|
||||||
}
|
}
|
||||||
|
|
||||||
RageFileBasic *RageFileDriverZip::Open( const CString &path, int mode, int &err )
|
RageFileBasic *RageFileDriverZip::Open( const CString &path, int mode, int &err )
|
||||||
@@ -339,48 +359,48 @@ RageFileBasic *RageFileDriverZip::Open( const CString &path, int mode, int &err
|
|||||||
/* If we havn't figured out the offset to the real data yet, do so now. */
|
/* If we havn't figured out the offset to the real data yet, do so now. */
|
||||||
if( info->data_offset == -1 )
|
if( info->data_offset == -1 )
|
||||||
{
|
{
|
||||||
zip.Seek( info->offset );
|
m_pZip->Seek( info->offset );
|
||||||
|
|
||||||
/* Should be in proper position now, so check for sig. */
|
/* Should be in proper position now, so check for sig. */
|
||||||
CString sig;
|
CString sig;
|
||||||
int got = zip.Read( sig, 4 );
|
int got = m_pZip->Read( sig, 4 );
|
||||||
if( got == -1 )
|
if( got == -1 )
|
||||||
RageException::Throw( "Read error in %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Read error in %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if( got != 4 )
|
if( got != 4 )
|
||||||
RageException::Throw( "%s: unexpected EOF", zip.GetPath().c_str() );
|
RageException::Throw( "%s: unexpected EOF", m_sPath.c_str() );
|
||||||
|
|
||||||
if( sig != local_hdr_sig )
|
if( sig != local_hdr_sig )
|
||||||
RageException::Throw( "%s: bad zipfile offset", zip.GetPath().c_str() );
|
RageException::Throw( "%s: bad zipfile offset", m_sPath.c_str() );
|
||||||
|
|
||||||
#define LREC_SIZE 26 /* lengths of local file headers, central */
|
#define LREC_SIZE 26 /* lengths of local file headers, central */
|
||||||
#define L_FILENAME_LENGTH 22
|
#define L_FILENAME_LENGTH 22
|
||||||
#define L_EXTRA_FIELD_LENGTH 24
|
#define L_EXTRA_FIELD_LENGTH 24
|
||||||
unsigned char byterec[LREC_SIZE];
|
unsigned char byterec[LREC_SIZE];
|
||||||
got = zip.Read( (char *)byterec, LREC_SIZE );
|
got = m_pZip->Read( (char *)byterec, LREC_SIZE );
|
||||||
if( got == -1 )
|
if( got == -1 )
|
||||||
RageException::Throw( "Read error in %s: %s", zip.GetPath().c_str(), zip.GetError().c_str() );
|
RageException::Throw( "Read error in %s: %s", m_sPath.c_str(), m_pZip->GetError().c_str() );
|
||||||
if( got != LREC_SIZE )
|
if( got != LREC_SIZE )
|
||||||
RageException::Throw( "%s: unexpected EOF", zip.GetPath().c_str() );
|
RageException::Throw( "%s: unexpected EOF", m_sPath.c_str() );
|
||||||
|
|
||||||
const int filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
|
const int filename_length = makeword(&byterec[L_FILENAME_LENGTH]);
|
||||||
const int extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
|
const int extra_field_length = makeword(&byterec[L_EXTRA_FIELD_LENGTH]);
|
||||||
info->data_offset = zip.Tell() + filename_length + extra_field_length;
|
info->data_offset = m_pZip->Tell() + filename_length + extra_field_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We won't do any further access to zip, except to copy it (which is
|
/* We won't do any further access to zip, except to copy it (which is
|
||||||
* threadsafe), so we can unlock now. */
|
* threadsafe), so we can unlock now. */
|
||||||
m_Mutex.Unlock();
|
m_Mutex.Unlock();
|
||||||
|
|
||||||
RageFileDriverSlice *pFile = new RageFileDriverSlice( zip.Copy(), info->data_offset, info->compr_size );
|
RageFileDriverSlice *pSlice = new RageFileDriverSlice( m_pZip->Copy(), info->data_offset, info->compr_size );
|
||||||
pFile->DeleteFileWhenFinished();
|
pSlice->DeleteFileWhenFinished();
|
||||||
|
|
||||||
switch( info->compression_method )
|
switch( info->compression_method )
|
||||||
{
|
{
|
||||||
case STORED:
|
case STORED:
|
||||||
return pFile;
|
return pSlice;
|
||||||
case DEFLATED:
|
case DEFLATED:
|
||||||
{
|
{
|
||||||
RageFileObjInflate *pInflate = new RageFileObjInflate( pFile, info->uncompr_size );
|
RageFileObjInflate *pInflate = new RageFileObjInflate( pSlice, info->uncompr_size );
|
||||||
pInflate->DeleteFileWhenFinished();
|
pInflate->DeleteFileWhenFinished();
|
||||||
return pInflate;
|
return pInflate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,22 +12,29 @@ class RageFileDriverZip: public RageFileDriver
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RageFileDriverZip( CString path );
|
RageFileDriverZip( CString path );
|
||||||
|
RageFileDriverZip( RageFileBasic *pFile );
|
||||||
virtual ~RageFileDriverZip();
|
virtual ~RageFileDriverZip();
|
||||||
|
|
||||||
RageFileBasic *Open( const CString &path, int mode, int &err );
|
RageFileBasic *Open( const CString &path, int mode, int &err );
|
||||||
void FlushDirCache( const CString &sPath );
|
void FlushDirCache( const CString &sPath );
|
||||||
|
|
||||||
|
void DeleteFileWhenFinished() { m_bFileOwned = true; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RageFile zip;
|
bool m_bFileOwned;
|
||||||
|
|
||||||
|
RageFileBasic *m_pZip;
|
||||||
vector<FileInfo *> Files;
|
vector<FileInfo *> Files;
|
||||||
|
|
||||||
|
CString m_sPath;
|
||||||
|
|
||||||
/* Open() must be threadsafe. Mutex access to "zip", since we seek
|
/* Open() must be threadsafe. Mutex access to "zip", since we seek
|
||||||
* around in it when reading files. */
|
* around in it when reading files. */
|
||||||
RageMutex m_Mutex;
|
RageMutex m_Mutex;
|
||||||
|
|
||||||
void ParseZipfile();
|
void ParseZipfile();
|
||||||
static void ReadEndCentralRecord( RageFile &zip, end_central_dir_record &ec );
|
void ReadEndCentralRecord( end_central_dir_record &ec );
|
||||||
static int ProcessCdirFileHdr( RageFile &zip, FileInfo &info );
|
int ProcessCdirFileHdr( FileInfo &info );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user