move volume and file to stream, add fs.mount, fs.open

This commit is contained in:
Laurent Vivier 2008-04-20 16:07:24 +00:00
parent d90125f60c
commit 5caae75dc2
8 changed files with 94 additions and 141 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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;