From b8ab0fc587587aea9b88cce20e015bb515f28a84 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 8 Dec 2003 00:08:20 +0000 Subject: [PATCH] add RageFileDriverZip --- stepmania/src/RageFileDriverZip.cpp | 156 ++++++++++++++++++++++++++++ stepmania/src/RageFileDriverZip.h | 27 +++++ 2 files changed, 183 insertions(+) create mode 100644 stepmania/src/RageFileDriverZip.cpp create mode 100644 stepmania/src/RageFileDriverZip.h diff --git a/stepmania/src/RageFileDriverZip.cpp b/stepmania/src/RageFileDriverZip.cpp new file mode 100644 index 0000000000..65f132ea1a --- /dev/null +++ b/stepmania/src/RageFileDriverZip.cpp @@ -0,0 +1,156 @@ +#include "global.h" +#include "RageFileDriverZip.h" +#include "RageUtil.h" +#include "RageUtil_FileDB.h" +#include +#include + +#if defined(_WINDOWS) + #ifdef DEBUG + #pragma comment(lib, "zzip/zziplibd.lib") + #else + #pragma comment(lib, "zzip/zziplib.lib") + #endif +#endif +#pragma comment(lib, "zzip/zlib.lib") + +class RageFileObjZip: public RageFileObj +{ +private: + ZZIP_FILE *fp; + RageFileDriverZip *dir; /* hack: for errors */ + +public: + RageFileObjZip( ZZIP_FILE *fp, RageFileDriverZip *dir, RageFile &p ); + virtual ~RageFileObjZip(); + virtual int Read(void *buffer, size_t bytes); + virtual int Write(const void *buffer, size_t bytes); + virtual void Rewind(); + virtual int Seek( int offset ); + virtual int SeekCur( int offset ); + virtual int GetFileSize(); +}; + +class ZipFilenameDB: public FilenameDB +{ +protected: + void PopulateFileSet( FileSet &fs, const CString &sPath ) { } +public: + ZipFilenameDB() { ExpireSeconds = -1; } +}; + + +RageFileDriverZip::RageFileDriverZip( CString path ): + RageFileDriver( new ZipFilenameDB ) +{ + zzip_error_t err; + dir = zzip_dir_open( path, &err ); + if( dir == NULL ) + RageException::Throw( "Couldn't open %s: %s", path.c_str(), zzip_strerror(err) ); + + while( ZZIP_DIRENT *ent = zzip_readdir(dir) ) + FDB->AddFile( ent->d_name, ent->st_size, 0 ); + + zzip_rewinddir( dir ); +} + +RageFileDriverZip::~RageFileDriverZip() +{ + zzip_dir_close( dir ); +} + +RageFileObj *RageFileDriverZip::Open( const CString &path, RageFile::OpenMode mode, RageFile &p, int &err ) +{ + if( mode == RageFile::WRITE ) + { + err = EINVAL; + return NULL; + } + + LockMut( lock ); + + ZZIP_FILE *fp = zzip_file_open( dir, path, ZZIP_CASELESS|ZZIP_ONLYZIP ); + + if( !fp ) + { + err = zzip_errno( zzip_error(dir) ); + return NULL; + } + + return new RageFileObjZip( fp, this, p ); +} + +int RageFileDriverZip::GetFileModTime( const CString &sPath ) +{ + /* XXX: we can use CRC instead */ + /* Don't spend time looking up the real mod time; use the mtime of the ZIP itself. */ + return FDB->GetFileModTime( sPath ); +} + +/* NOP for now. This could check to see if the ZIP's mtime has changed, and reload. */ +void RageFileDriverZip::FlushDirCache( const CString &sPath ) +{ + +} + +RageFileObjZip::RageFileObjZip( ZZIP_FILE *fp_, RageFileDriverZip *dir_, RageFile &p ): + RageFileObj( p ) +{ + fp=fp_; + dir=dir_; +} + +RageFileObjZip::~RageFileObjZip() +{ + LockMut( dir->lock ); + zzip_file_close( fp ); +} + +int RageFileObjZip::Read( void *buf, size_t bytes ) +{ + LockMut( dir->lock ); + + const int ret = zzip_file_read( fp, (char *) buf, bytes ); + if( ret == -1 ) + { + SetError( zzip_strerror_of(dir->dir) ); + return -1; + } + + return ret; +} + +int RageFileObjZip::Write(const void *buffer, size_t bytes) +{ + SetError( "Not implemented" ); + return -1; +} + +void RageFileObjZip::Rewind() +{ + LockMut( dir->lock ); + zzip_rewind( fp ); +} + +int RageFileObjZip::Seek( int offset ) +{ + LockMut( dir->lock ); + return zzip_seek( fp, offset, SEEK_SET ); +} + +int RageFileObjZip::SeekCur( int offset ) +{ + LockMut( dir->lock ); + return zzip_seek( fp, offset, SEEK_CUR ); +} + +int RageFileObjZip::GetFileSize() +{ + LockMut( dir->lock ); + + /* XXX very slow */ + const int OldPos = zzip_tell( fp ); + int ret = zzip_seek( fp, 0, SEEK_END ); + zzip_seek( fp, OldPos, SEEK_SET ); + return ret; +} diff --git a/stepmania/src/RageFileDriverZip.h b/stepmania/src/RageFileDriverZip.h new file mode 100644 index 0000000000..9323fd302d --- /dev/null +++ b/stepmania/src/RageFileDriverZip.h @@ -0,0 +1,27 @@ +#ifndef RAGE_FILE_DRIVER_ZIP_H +#define RAGE_FILE_DRIVER_ZIP_H + +#include "RageFileDriver.h" +#include "RageThreads.h" + +typedef struct zzip_dir ZZIP_DIR; + +class RageFileObjZip; + +class RageFileDriverZip: public RageFileDriver +{ + friend class RageFileObjZip; +public: + RageFileDriverZip( CString path ); + virtual ~RageFileDriverZip(); + + RageFileObj *Open( const CString &path, RageFile::OpenMode mode, RageFile &p, int &err ); + int GetFileModTime( const CString &sPath ); + void FlushDirCache( const CString &sPath ); + +private: + ZZIP_DIR *dir; + RageMutex lock; +}; + +#endif