From 5caae75dc28701c7b04437afea246c51d6f533a0 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Sun, 20 Apr 2008 16:07:24 +0000 Subject: [PATCH] move volume and file to stream, add fs.mount, fs.open --- libstream/gzio.c | 32 +++++---- libstream/libstream.h | 45 ++++++++---- libstream/stream_close.c | 12 ++-- libstream/stream_fstat.c | 2 +- libstream/stream_lseek.c | 2 +- libstream/stream_open.c | 131 +++++++++------------------------- libstream/stream_read.c | 2 +- libstream/stream_uncompress.c | 9 +-- 8 files changed, 94 insertions(+), 141 deletions(-) diff --git a/libstream/gzio.c b/libstream/gzio.c index 1c52f44..200d533 100644 --- a/libstream/gzio.c +++ b/libstream/gzio.c @@ -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 @@ -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; } diff --git a/libstream/libstream.h b/libstream/libstream.h index dfd745b..a8275c4 100644 --- a/libstream/libstream.h +++ b/libstream/libstream.h @@ -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; diff --git a/libstream/stream_close.c b/libstream/stream_close.c index 4e3ec26..8fbdeb6 100644 --- a/libstream/stream_close.c +++ b/libstream/stream_close.c @@ -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; } diff --git a/libstream/stream_fstat.c b/libstream/stream_fstat.c index e532132..7909f79 100644 --- a/libstream/stream_fstat.c +++ b/libstream/stream_fstat.c @@ -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; diff --git a/libstream/stream_lseek.c b/libstream/stream_lseek.c index 1256101..4027345 100644 --- a/libstream/stream_lseek.c +++ b/libstream/stream_lseek.c @@ -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); } diff --git a/libstream/stream_open.c b/libstream/stream_open.c index 2645690..9c42cd3 100644 --- a/libstream/stream_open.c +++ b/libstream/stream_open.c @@ -31,6 +31,21 @@ #include #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; diff --git a/libstream/stream_read.c b/libstream/stream_read.c index 5c774fc..5d537f1 100644 --- a/libstream/stream_read.c +++ b/libstream/stream_read.c @@ -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); } diff --git a/libstream/stream_uncompress.c b/libstream/stream_uncompress.c index 489fd75..4252f02 100644 --- a/libstream/stream_uncompress.c +++ b/libstream/stream_uncompress.c @@ -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;