Files
2012-10-17 16:07:33 -04:00

236 lines
4.9 KiB
C++

/*
Copyright 2007 Guillaume Duhamel
Copyright 2007-2012 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ROMReader.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#ifdef HAVE_LIBZZIP
#include <zzip/zzip.h>
#endif
#ifdef WIN32
#define stat(...) _stat(__VA_ARGS__)
#define S_IFMT _S_IFMT
#define S_IFREG _S_IFREG
#endif
ROMReader_struct * ROMReaderInit(char ** filename)
{
#ifdef HAVE_LIBZ
if(!strcasecmp(".gz", *filename + (strlen(*filename) - 3)))
{
(*filename)[strlen(*filename) - 3] = '\0';
return &GZIPROMReader;
}
#endif
#ifdef HAVE_LIBZZIP
if (!strcasecmp(".zip", *filename + (strlen(*filename) - 4)))
{
(*filename)[strlen(*filename) - 4] = '\0';
return &ZIPROMReader;
}
#endif
return &STDROMReader;
}
void * STDROMReaderInit(const char * filename);
void STDROMReaderDeInit(void *);
u32 STDROMReaderSize(void *);
int STDROMReaderSeek(void *, int, int);
int STDROMReaderRead(void *, void *, u32);
ROMReader_struct STDROMReader =
{
ROMREADER_STD,
"Standard ROM Reader",
STDROMReaderInit,
STDROMReaderDeInit,
STDROMReaderSize,
STDROMReaderSeek,
STDROMReaderRead
};
void * STDROMReaderInit(const char * filename)
{
#ifdef WIN32
struct _stat sb;
#else
struct stat sb;
#endif
if (stat(filename, &sb) == -1)
return 0;
if ((sb.st_mode & S_IFMT) != S_IFREG)
return 0;
return (void *) fopen(filename, "rb");
}
void STDROMReaderDeInit(void * file)
{
if (!file) return ;
fclose((FILE*)file);
}
u32 STDROMReaderSize(void * file)
{
u32 size;
if (!file) return 0 ;
fseek((FILE*)file, 0, SEEK_END);
size = ftell((FILE*)file);
fseek((FILE*)file, 0, SEEK_SET);
return size;
}
int STDROMReaderSeek(void * file, int offset, int whence)
{
if (!file) return 0 ;
return fseek((FILE*)file, offset, whence);
}
int STDROMReaderRead(void * file, void * buffer, u32 size)
{
if (!file) return 0 ;
return fread(buffer, 1, size, (FILE*)file);
}
#ifdef HAVE_LIBZ
void * GZIPROMReaderInit(const char * filename);
void GZIPROMReaderDeInit(void *);
u32 GZIPROMReaderSize(void *);
int GZIPROMReaderSeek(void *, int, int);
int GZIPROMReaderRead(void *, void *, u32);
ROMReader_struct GZIPROMReader =
{
ROMREADER_GZIP,
"Gzip ROM Reader",
GZIPROMReaderInit,
GZIPROMReaderDeInit,
GZIPROMReaderSize,
GZIPROMReaderSeek,
GZIPROMReaderRead
};
void * GZIPROMReaderInit(const char * filename)
{
return (void*)gzopen(filename, "rb");
}
void GZIPROMReaderDeInit(void * file)
{
gzclose((gzFile)file);
}
u32 GZIPROMReaderSize(void * file)
{
char useless[1024];
u32 size = 0;
/* FIXME this function should first save the current
* position and restore it after size calculation */
gzrewind((gzFile)file);
while (gzeof ((gzFile)file) == 0)
size += gzread((gzFile)file, useless, 1024);
gzrewind((gzFile)file);
return size;
}
int GZIPROMReaderSeek(void * file, int offset, int whence)
{
return gzseek((gzFile)file, offset, whence);
}
int GZIPROMReaderRead(void * file, void * buffer, u32 size)
{
return gzread((gzFile)file, buffer, size);
}
#endif
#ifdef HAVE_LIBZZIP
void * ZIPROMReaderInit(const char * filename);
void ZIPROMReaderDeInit(void *);
u32 ZIPROMReaderSize(void *);
int ZIPROMReaderSeek(void *, int, int);
int ZIPROMReaderRead(void *, void *, u32);
ROMReader_struct ZIPROMReader =
{
ROMREADER_ZIP,
"Zip ROM Reader",
ZIPROMReaderInit,
ZIPROMReaderDeInit,
ZIPROMReaderSize,
ZIPROMReaderSeek,
ZIPROMReaderRead
};
void * ZIPROMReaderInit(const char * filename)
{
ZZIP_DIR * dir = zzip_opendir(filename);
ZZIP_DIRENT * dirent = zzip_readdir(dir);
if (dir != NULL)
{
char tmp1[1024];
char tmp2[1024];
memset(tmp1,0,sizeof(tmp1));
memset(tmp2,0,sizeof(tmp2));
strncpy(tmp1, filename, strlen(filename) - 4);
sprintf(tmp2, "%s/%s", tmp1, dirent->d_name);
return zzip_fopen(tmp2, "rb");
}
return NULL;
}
void ZIPROMReaderDeInit(void * file)
{
zzip_close((ZZIP_FILE*)file);
}
u32 ZIPROMReaderSize(void * file)
{
u32 size;
zzip_seek((ZZIP_FILE*)file, 0, SEEK_END);
size = zzip_tell((ZZIP_FILE*)file);
zzip_seek((ZZIP_FILE*)file, 0, SEEK_SET);
return size;
}
int ZIPROMReaderSeek(void * file, int offset, int whence)
{
return zzip_seek((ZZIP_FILE*)file, offset, whence);
}
int ZIPROMReaderRead(void * file, void * buffer, u32 size)
{
#ifdef ZZIP_OLD_READ
return zzip_read((ZZIP_FILE*)file, (char *) buffer, size);
#else
return zzip_read((ZZIP_FILE*)file, buffer, size);
#endif
}
#endif