mirror of
https://github.com/vivier/EMILE.git
synced 2025-02-22 20:29:04 +00:00
move volume and file to stream, add fs.mount, fs.open
This commit is contained in:
parent
d90125f60c
commit
5caae75dc2
@ -6,7 +6,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* @(#) $Id: gzio.c,v 1.2 2005/11/26 08:51:55 lvivier Exp $ */
|
||||
/* @(#) $Id: gzio.c,v 1.3 2008/04/20 16:07:24 lvivier Exp $ */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -59,7 +59,8 @@ typedef struct gz_stream {
|
||||
int back; /* one character push-back */
|
||||
int last; /* true if push-back is last character */
|
||||
|
||||
filesystem_io_t fs;
|
||||
stream_FILE *file;
|
||||
filesystem_io_t *fs;
|
||||
} gz_stream;
|
||||
|
||||
|
||||
@ -77,8 +78,8 @@ local uLong getLong OF((gz_stream *s));
|
||||
can be checked to distinguish the two cases (if errno is zero, the
|
||||
zlib error is Z_MEM_ERROR).
|
||||
*/
|
||||
gzFile gzopen (fs)
|
||||
filesystem_io_t *fs;
|
||||
gzFile gzopen (stream)
|
||||
stream_t *stream;
|
||||
{
|
||||
int err;
|
||||
gz_stream *s;
|
||||
@ -100,7 +101,8 @@ gzFile gzopen (fs)
|
||||
s->crc = crc32(0L, Z_NULL, 0);
|
||||
s->transparent = 0;
|
||||
|
||||
s->fs = *fs;
|
||||
s->file = stream->file;
|
||||
s->fs = &stream->fs;
|
||||
|
||||
s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
|
||||
|
||||
@ -118,7 +120,7 @@ gzFile gzopen (fs)
|
||||
s->stream.avail_out = Z_BUFSIZE;
|
||||
|
||||
check_header(s); /* skip the .gz header */
|
||||
s->start = s->fs.lseek(s->fs.file, 0, SEEK_CUR) - s->stream.avail_in;
|
||||
s->start = s->fs->lseek(s->file, 0, SEEK_CUR) - s->stream.avail_in;
|
||||
|
||||
return (gzFile)s;
|
||||
}
|
||||
@ -133,7 +135,7 @@ local int get_byte(s)
|
||||
{
|
||||
if (s->z_eof) return EOF;
|
||||
if (s->stream.avail_in == 0) {
|
||||
s->stream.avail_in = (uInt)s->fs.read(s->fs.file, s->inbuf, Z_BUFSIZE);
|
||||
s->stream.avail_in = (uInt)s->fs->read(s->file, s->inbuf, Z_BUFSIZE);
|
||||
if (s->stream.avail_in == 0) {
|
||||
s->z_eof = 1;
|
||||
return EOF;
|
||||
@ -167,7 +169,7 @@ local void check_header(s)
|
||||
len = s->stream.avail_in;
|
||||
if (len < 2) {
|
||||
if (len) s->inbuf[0] = s->stream.next_in[0];
|
||||
len = (uInt)s->fs.read(s->fs.file, s->inbuf + len, Z_BUFSIZE >> len);
|
||||
len = (uInt)s->fs->read(s->file, s->inbuf + len, Z_BUFSIZE >> len);
|
||||
s->stream.avail_in += len;
|
||||
s->stream.next_in = s->inbuf;
|
||||
if (s->stream.avail_in < 2) {
|
||||
@ -287,7 +289,7 @@ int ZEXPORT gzread (file, buf, len)
|
||||
}
|
||||
if (s->stream.avail_out > 0) {
|
||||
s->stream.avail_out -=
|
||||
(uInt)s->fs.read(s->fs.file, next_out, s->stream.avail_out);
|
||||
(uInt)s->fs->read(s->file, next_out, s->stream.avail_out);
|
||||
}
|
||||
len -= s->stream.avail_out;
|
||||
s->in += len;
|
||||
@ -297,7 +299,7 @@ int ZEXPORT gzread (file, buf, len)
|
||||
}
|
||||
if (s->stream.avail_in == 0 && !s->z_eof) {
|
||||
|
||||
s->stream.avail_in = (uInt)s->fs.read(s->fs.file, s->inbuf, Z_BUFSIZE);
|
||||
s->stream.avail_in = (uInt)s->fs->read(s->file, s->inbuf, Z_BUFSIZE);
|
||||
if (s->stream.avail_in == 0) {
|
||||
s->z_eof = 1;
|
||||
}
|
||||
@ -373,7 +375,7 @@ z_off_t ZEXPORT gzseek (file, offset, whence)
|
||||
s->back = EOF;
|
||||
s->stream.avail_in = 0;
|
||||
s->stream.next_in = s->inbuf;
|
||||
if (s->fs.lseek(s->fs.file, offset, SEEK_SET) < 0) return -1L;
|
||||
if (s->fs->lseek(s->file, offset, SEEK_SET) < 0) return -1L;
|
||||
|
||||
s->in = s->out = offset;
|
||||
return offset;
|
||||
@ -427,7 +429,7 @@ int ZEXPORT gzrewind (file)
|
||||
if (!s->transparent) (void)inflateReset(&s->stream);
|
||||
s->in = 0;
|
||||
s->out = 0;
|
||||
return s->fs.lseek(s->fs.file, s->start, SEEK_SET);
|
||||
return s->fs->lseek(s->file, s->start, SEEK_SET);
|
||||
}
|
||||
|
||||
/* ===========================================================================
|
||||
@ -473,7 +475,7 @@ local uLong getLong (s)
|
||||
int ZEXPORT gzclose (file)
|
||||
gzFile file;
|
||||
{
|
||||
filesystem_io_t fs;
|
||||
filesystem_io_t *fs;
|
||||
gz_stream *s = (gz_stream*)file;
|
||||
int ret;
|
||||
|
||||
@ -482,8 +484,8 @@ int ZEXPORT gzclose (file)
|
||||
if (s == NULL) return Z_STREAM_ERROR;
|
||||
|
||||
ret = destroy((gz_stream*)file);
|
||||
fs.close(fs.file);
|
||||
if (fs.umount) fs.umount(fs.file);
|
||||
fs->close(s->file);
|
||||
if (fs->umount) fs->umount(s->file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -15,43 +15,56 @@ typedef enum {
|
||||
} device_t;
|
||||
|
||||
typedef enum {
|
||||
fs_BLOCK,
|
||||
fs_CONTAINER,
|
||||
fs_ISO9660,
|
||||
fs_EXT2,
|
||||
fs_ISO9660,
|
||||
fs_CONTAINER,
|
||||
fs_BLOCK,
|
||||
fs_LAST
|
||||
} fs_t;
|
||||
|
||||
struct stream_stat {
|
||||
int st_dev;
|
||||
off_t st_size;
|
||||
off_t st_base;
|
||||
};
|
||||
|
||||
typedef struct device_io_t device_io_t;
|
||||
typedef struct filesystem_io_t filesystem_io_t;
|
||||
typedef void *stream_FILE;
|
||||
typedef void *stream_VOLUME;
|
||||
typedef void *stream_DIR;
|
||||
;
|
||||
typedef int (*stream_read_sector_t)(void *data,off_t offset, void* buffer, size_t size);
|
||||
typedef int (*stream_write_sector_t)(void *data,off_t offset, void* buffer, size_t size);
|
||||
typedef ssize_t (*stream_read_t)(void *data, void *buf, size_t count);
|
||||
typedef int (*stream_lseek_t)(void *data, long offset, int whence);
|
||||
typedef int (*stream_close_t)(void *data);
|
||||
typedef int (*stream_umount_t)(void *data);
|
||||
typedef int (*stream_fstat_t)(void *data, struct stream_stat *buf);
|
||||
typedef int (*stream_get_blocksize_t)(void *data);
|
||||
|
||||
typedef struct {
|
||||
typedef stream_VOLUME *(*stream_mount_t)(device_io_t *device);
|
||||
typedef int (*stream_init_t)(device_io_t *device, filesystem_io_t *fs);
|
||||
typedef stream_FILE *(*stream_open_t)(stream_VOLUME *volume, char *path);
|
||||
typedef int (*stream_umount_t)(stream_VOLUME *volume);
|
||||
|
||||
typedef size_t (*stream_read_t)(stream_FILE *file, void *buf, size_t count);
|
||||
typedef int (*stream_lseek_t)(stream_FILE *file, long offset, int whence);
|
||||
typedef void (*stream_close_t)(stream_FILE *file);
|
||||
typedef int (*stream_fstat_t)(stream_FILE *file, struct stream_stat *buf);
|
||||
|
||||
struct device_io_t {
|
||||
void *data;
|
||||
stream_write_sector_t write_sector;
|
||||
stream_read_sector_t read_sector;
|
||||
stream_close_t close;
|
||||
stream_get_blocksize_t get_blocksize;
|
||||
} device_io_t;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
void *volume;
|
||||
void *file;
|
||||
struct filesystem_io_t {
|
||||
stream_mount_t mount;
|
||||
stream_umount_t umount;
|
||||
stream_open_t open;
|
||||
stream_read_t read;
|
||||
stream_lseek_t lseek;
|
||||
stream_close_t close;
|
||||
stream_umount_t umount;
|
||||
stream_fstat_t fstat;
|
||||
} filesystem_io_t;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* device interface */
|
||||
@ -64,6 +77,8 @@ typedef struct {
|
||||
|
||||
/* info */
|
||||
|
||||
void *volume;
|
||||
void *file;
|
||||
fs_t fs_id;
|
||||
device_t device_id;
|
||||
int unit, partition;
|
||||
|
@ -10,15 +10,13 @@
|
||||
|
||||
int stream_close(stream_t *stream)
|
||||
{
|
||||
if (stream->fs.close &&
|
||||
stream->fs.close(stream->fs.file) != 0)
|
||||
return -1;
|
||||
if (stream->fs.close)
|
||||
stream->fs.close(stream->file);
|
||||
if (stream->fs.umount &&
|
||||
stream->fs.umount(stream->fs.volume) != 0)
|
||||
return -1;
|
||||
if (stream->device.close &&
|
||||
stream->device.close(stream->device.data) != 0)
|
||||
stream->fs.umount(stream->volume) != 0)
|
||||
return -1;
|
||||
if (stream->device.close)
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
return 0;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ int stream_fstat(stream_t *stream, struct stream_stat *buf)
|
||||
if (stream->fs.fstat == NULL)
|
||||
return -1;
|
||||
|
||||
ret = stream->fs.fstat(stream->fs.file, buf);
|
||||
ret = stream->fs.fstat(stream->file, buf);
|
||||
buf->st_dev = stream->unit;
|
||||
|
||||
return ret;
|
||||
|
@ -8,5 +8,5 @@
|
||||
|
||||
int stream_lseek(stream_t *stream, long offset, int whence)
|
||||
{
|
||||
return stream->fs.lseek(stream->fs.file, offset, whence);
|
||||
return stream->fs.lseek(stream->file, offset, whence);
|
||||
}
|
||||
|
@ -31,6 +31,21 @@
|
||||
#include <libmap.h>
|
||||
#endif
|
||||
|
||||
stream_init_t fs_init[] = {
|
||||
#ifdef EXT2_SUPPORT
|
||||
[fs_EXT2] = ext2_init,
|
||||
#endif
|
||||
#ifdef ISO9660_SUPPORT
|
||||
[fs_ISO9660] = iso9660_init,
|
||||
#endif
|
||||
#ifdef CONTAINER_SUPPORT
|
||||
[fs_CONTAINER] = container_init,
|
||||
#endif
|
||||
#ifdef BLOCK_SUPPORT
|
||||
[fs_BLOCK] = block_init,
|
||||
#endif
|
||||
};
|
||||
|
||||
static char* get_fs(char *path, fs_t *fs)
|
||||
{
|
||||
if (strncmp("block:", path, 6) == 0)
|
||||
@ -182,32 +197,13 @@ stream_t *stream_open(char *dev)
|
||||
if (partition != -1)
|
||||
{
|
||||
#ifdef MAP_SUPPORT
|
||||
int ret;
|
||||
map_t *map;
|
||||
|
||||
map = map_open(&stream->device);
|
||||
if (map == NULL)
|
||||
if (map_init(&stream->device, partition) == -1)
|
||||
{
|
||||
printf("Cannot open map\n");
|
||||
stream->device.close(&stream->device);
|
||||
stream->device.close(stream->volume);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stream->device.data = map;
|
||||
ret = map_read(map, partition);
|
||||
if (ret == -1)
|
||||
{
|
||||
printf("Cannot read partition %d\n", partition);
|
||||
map_close(map);
|
||||
stream->device.close(&stream->device);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->device.read_sector = (stream_read_sector_t)map_read_sector;
|
||||
stream->device.close = (stream_close_t)map_close;
|
||||
stream->device.get_blocksize =
|
||||
(stream_close_t)map_get_blocksize;
|
||||
#else
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
@ -215,83 +211,24 @@ stream_t *stream_open(char *dev)
|
||||
#endif /* MAP_SUPPORT */
|
||||
}
|
||||
|
||||
switch(fs)
|
||||
if (fs >= fs_LAST || fs_init[fs](&stream->device, &stream->fs) == -1)
|
||||
{
|
||||
#ifdef BLOCK_SUPPORT
|
||||
case fs_BLOCK:
|
||||
stream->fs.volume = NULL;
|
||||
stream->fs.file = block_open(&stream->device, current);
|
||||
if (stream->fs.file == NULL)
|
||||
goto outfs;
|
||||
stream->fs.read = (stream_read_t)block_read;
|
||||
stream->fs.lseek = (stream_lseek_t)block_lseek;
|
||||
stream->fs.close = (stream_close_t)block_close;
|
||||
stream->fs.umount = NULL;
|
||||
stream->fs.fstat = (stream_fstat_t)block_fstat;
|
||||
break;
|
||||
#endif /* BLOCK_SUPPORT */
|
||||
#ifdef CONTAINER_SUPPORT
|
||||
case fs_CONTAINER:
|
||||
stream->fs.volume = NULL;
|
||||
stream->fs.file = container_open(&stream->device, current);
|
||||
if (stream->fs.file == NULL)
|
||||
goto outfs;
|
||||
stream->fs.read = (stream_read_t)container_read;
|
||||
stream->fs.lseek = (stream_lseek_t)container_lseek;
|
||||
stream->fs.close = (stream_close_t)container_close;
|
||||
stream->fs.umount = NULL;
|
||||
stream->fs.fstat = (stream_fstat_t)container_fstat;
|
||||
break;
|
||||
#endif /* CONTAINER_SUPPORT */
|
||||
|
||||
#ifdef ISO9660_SUPPORT
|
||||
case fs_ISO9660:
|
||||
stream->fs.volume = iso9660_mount(&stream->device);
|
||||
if (stream->fs.volume == NULL)
|
||||
{
|
||||
printf("Cannot mount volume ISO9660\n");
|
||||
goto outfs;
|
||||
}
|
||||
stream->fs.file = iso9660_open(stream->fs.volume, current);
|
||||
if (stream->fs.file == NULL)
|
||||
{
|
||||
iso9660_umount(stream->fs.volume);
|
||||
goto outfs;
|
||||
}
|
||||
stream->fs.read = (stream_read_t)iso9660_read;
|
||||
stream->fs.lseek = (stream_lseek_t)iso9660_lseek;
|
||||
stream->fs.close = (stream_close_t)iso9660_close;
|
||||
stream->fs.umount = (stream_umount_t)iso9660_umount;
|
||||
stream->fs.fstat = (stream_fstat_t)iso9660_fstat;
|
||||
break;
|
||||
#endif /* ISO9660_SUPPORT */
|
||||
|
||||
#ifdef EXT2_SUPPORT
|
||||
case fs_EXT2:
|
||||
stream->fs.volume = ext2_mount(&stream->device);
|
||||
if (stream->fs.volume == NULL)
|
||||
{
|
||||
printf("Cannot mount volume ext2\n");
|
||||
goto outfs;
|
||||
}
|
||||
stream->fs.file = ext2_open(stream->fs.volume, current);
|
||||
if (stream->fs.file == NULL)
|
||||
{
|
||||
ext2_umount(stream->fs.volume);
|
||||
goto outfs;
|
||||
}
|
||||
stream->fs.read = (stream_read_t)ext2_read;
|
||||
stream->fs.lseek = (stream_lseek_t)ext2_lseek;
|
||||
stream->fs.close = (stream_close_t)ext2_close;
|
||||
stream->fs.umount = (stream_umount_t)ext2_umount;
|
||||
stream->fs.fstat = (stream_fstat_t)ext2_fstat;
|
||||
break;
|
||||
#endif /* EXT2_SUPPORT */
|
||||
default:
|
||||
outfs:
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
return NULL;
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->volume = stream->fs.mount(&stream->device);
|
||||
if (stream->volume == NULL) {
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
stream->file = stream->fs.open(stream->volume, current);
|
||||
if (stream->file == NULL) {
|
||||
stream->fs.umount(stream->volume);
|
||||
stream->device.close(stream->device.data);
|
||||
free(stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return stream;
|
||||
|
@ -8,5 +8,5 @@
|
||||
|
||||
int stream_read(stream_t *stream, void *buf, size_t count)
|
||||
{
|
||||
return stream->fs.read(stream->fs.file, buf, count);
|
||||
return stream->fs.read(stream->file, buf, count);
|
||||
}
|
||||
|
@ -2,17 +2,18 @@
|
||||
|
||||
#include "libstream.h"
|
||||
|
||||
extern gzFile gzopen (filesystem_io_t *fs);
|
||||
extern gzFile gzopen (stream_t *stream);
|
||||
|
||||
int stream_uncompress(stream_t *stream)
|
||||
{
|
||||
gzFile *gz;
|
||||
|
||||
gz = gzopen(&stream->fs);
|
||||
gz = gzopen(stream);
|
||||
if (gz == NULL)
|
||||
return -1;
|
||||
|
||||
stream->fs.volume = NULL;
|
||||
stream->fs.file = gz;
|
||||
stream->volume = NULL;
|
||||
stream->file = gz;
|
||||
stream->fs.read = (stream_read_t)gzread;
|
||||
stream->fs.lseek = (stream_lseek_t)gzseek;
|
||||
stream->fs.close = (stream_close_t)gzclose;
|
||||
|
Loading…
x
Reference in New Issue
Block a user