mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
152 lines
3.3 KiB
C
152 lines
3.3 KiB
C
|
#include "shared.h"
|
||
|
|
||
|
/*
|
||
|
Load a normal file, or ZIP/GZ archive.
|
||
|
Returns NULL if an error occured.
|
||
|
*/
|
||
|
uint8 *load_archive(char *filename, int *file_size)
|
||
|
{
|
||
|
int size = 0;
|
||
|
uint8 *buf = NULL;
|
||
|
|
||
|
if(check_zip(filename))
|
||
|
{
|
||
|
unzFile *fd = NULL;
|
||
|
unz_file_info info;
|
||
|
int ret = 0;
|
||
|
|
||
|
/* Attempt to open the archive */
|
||
|
fd = unzOpen(filename);
|
||
|
if(!fd) return (NULL);
|
||
|
|
||
|
/* Go to first file in archive */
|
||
|
ret = unzGoToFirstFile(fd);
|
||
|
if(ret != UNZ_OK)
|
||
|
{
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
ret = unzGetCurrentFileInfo(fd, &info, NULL, 0, NULL, 0, NULL, 0);
|
||
|
if(ret != UNZ_OK)
|
||
|
{
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Open the file for reading */
|
||
|
ret = unzOpenCurrentFile(fd);
|
||
|
if(ret != UNZ_OK)
|
||
|
{
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Allocate file data buffer */
|
||
|
size = info.uncompressed_size;
|
||
|
buf = malloc(size);
|
||
|
if(!buf)
|
||
|
{
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Read (decompress) the file */
|
||
|
ret = unzReadCurrentFile(fd, buf, info.uncompressed_size);
|
||
|
if(ret != info.uncompressed_size)
|
||
|
{
|
||
|
free(buf);
|
||
|
unzCloseCurrentFile(fd);
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Close the current file */
|
||
|
ret = unzCloseCurrentFile(fd);
|
||
|
if(ret != UNZ_OK)
|
||
|
{
|
||
|
free(buf);
|
||
|
unzClose(fd);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Close the archive */
|
||
|
ret = unzClose(fd);
|
||
|
if(ret != UNZ_OK)
|
||
|
{
|
||
|
free(buf);
|
||
|
return (NULL);
|
||
|
}
|
||
|
|
||
|
/* Update file size and return pointer to file data */
|
||
|
*file_size = size;
|
||
|
return (buf);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
gzFile *gd = NULL;
|
||
|
|
||
|
/* Open file */
|
||
|
gd = gzopen(filename, "rb");
|
||
|
if(!gd) return (0);
|
||
|
|
||
|
/* Get file size */
|
||
|
size = gzsize(gd);
|
||
|
|
||
|
/* Allocate file data buffer */
|
||
|
buf = malloc(size);
|
||
|
if(!buf)
|
||
|
{
|
||
|
gzclose(gd);
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* Read file data */
|
||
|
gzread(gd, buf, size);
|
||
|
|
||
|
/* Close file */
|
||
|
gzclose(gd);
|
||
|
|
||
|
/* Update file size and return pointer to file data */
|
||
|
*file_size = size;
|
||
|
return (buf);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
Verifies if a file is a ZIP archive or not.
|
||
|
Returns: 1= ZIP archive, 0= not a ZIP archive
|
||
|
*/
|
||
|
int check_zip(char *filename)
|
||
|
{
|
||
|
uint8 buf[2];
|
||
|
FILE *fd = NULL;
|
||
|
fd = fopen(filename, "rb");
|
||
|
if(!fd) return (0);
|
||
|
fread(buf, 2, 1, fd);
|
||
|
fclose(fd);
|
||
|
if(memcmp(buf, "PK", 2) == 0) return (1);
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
Returns the size of a GZ compressed file.
|
||
|
*/
|
||
|
int gzsize(gzFile *gd)
|
||
|
{
|
||
|
#define CHUNKSIZE (0x10000)
|
||
|
int size = 0, length = 0;
|
||
|
unsigned char buffer[CHUNKSIZE];
|
||
|
gzrewind(gd);
|
||
|
do {
|
||
|
size = gzread(gd, buffer, CHUNKSIZE);
|
||
|
if(size <= 0) break;
|
||
|
length += size;
|
||
|
} while (!gzeof(gd));
|
||
|
gzrewind(gd);
|
||
|
return (length);
|
||
|
#undef CHUNKSIZE
|
||
|
}
|