input_stream: return allocated input_stream objects
Major API redesign: don't let the caller allocate the input_stream object. Let each input plugin allocate its own (derived/extended) input_stream pointer. The "data" attribute can now be removed, and all input plugins simply cast the input_stream pointer to their own structure (with an "struct input_stream base" as the first attribute).
This commit is contained in:
@@ -45,10 +45,12 @@ struct bz2_archive_file {
|
||||
|
||||
char *name;
|
||||
bool reset;
|
||||
struct input_stream istream;
|
||||
struct input_stream *istream;
|
||||
};
|
||||
|
||||
struct bz2_input_stream {
|
||||
struct input_stream base;
|
||||
|
||||
struct bz2_archive_file *archive;
|
||||
|
||||
bool eof;
|
||||
@@ -111,7 +113,8 @@ bz2_open(const char *pathname, GError **error_r)
|
||||
refcount_init(&context->ref);
|
||||
|
||||
//open archive
|
||||
if (!input_stream_open(&context->istream, pathname, error_r)) {
|
||||
context->istream = input_stream_open(pathname, error_r);
|
||||
if (context->istream == NULL) {
|
||||
g_free(context);
|
||||
return NULL;
|
||||
}
|
||||
@@ -158,44 +161,42 @@ bz2_close(struct archive_file *file)
|
||||
|
||||
g_free(context->name);
|
||||
|
||||
input_stream_close(&context->istream);
|
||||
input_stream_close(context->istream);
|
||||
g_free(context);
|
||||
}
|
||||
|
||||
/* single archive handling */
|
||||
|
||||
static bool
|
||||
bz2_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
static struct input_stream *
|
||||
bz2_open_stream(struct archive_file *file,
|
||||
G_GNUC_UNUSED const char *path, GError **error_r)
|
||||
{
|
||||
struct bz2_archive_file *context = (struct bz2_archive_file *) file;
|
||||
struct bz2_input_stream *bis = g_new(struct bz2_input_stream, 1);
|
||||
|
||||
input_stream_init(&bis->base, &bz2_inputplugin);
|
||||
|
||||
bis->archive = context;
|
||||
|
||||
//setup file ops
|
||||
is->plugin = &bz2_inputplugin;
|
||||
//insert back reference
|
||||
is->data = bis;
|
||||
is->ready = true;
|
||||
is->seekable = false;
|
||||
bis->base.ready = true;
|
||||
bis->base.seekable = false;
|
||||
|
||||
if (!bz2_alloc(bis, error_r)) {
|
||||
g_free(bis);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bis->eof = false;
|
||||
|
||||
refcount_inc(&context->ref);
|
||||
|
||||
return true;
|
||||
return &bis->base;
|
||||
}
|
||||
|
||||
static void
|
||||
bz2_is_close(struct input_stream *is)
|
||||
{
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data;
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is;
|
||||
|
||||
bz2_destroy(bis);
|
||||
|
||||
@@ -215,7 +216,7 @@ bz2_fillbuffer(struct bz2_input_stream *bis, GError **error_r)
|
||||
if (bzstream->avail_in > 0)
|
||||
return true;
|
||||
|
||||
count = input_stream_read(&bis->archive->istream,
|
||||
count = input_stream_read(bis->archive->istream,
|
||||
bis->buffer, sizeof(bis->buffer),
|
||||
error_r);
|
||||
if (count == 0)
|
||||
@@ -230,7 +231,7 @@ static size_t
|
||||
bz2_is_read(struct input_stream *is, void *ptr, size_t length,
|
||||
GError **error_r)
|
||||
{
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data;
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is;
|
||||
bz_stream *bzstream;
|
||||
int bz_result;
|
||||
size_t nbytes = 0;
|
||||
@@ -269,7 +270,7 @@ bz2_is_read(struct input_stream *is, void *ptr, size_t length,
|
||||
static bool
|
||||
bz2_is_eof(struct input_stream *is)
|
||||
{
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is->data;
|
||||
struct bz2_input_stream *bis = (struct bz2_input_stream *)is;
|
||||
|
||||
return bis->eof;
|
||||
}
|
||||
|
@@ -163,14 +163,16 @@ iso9660_archive_close(struct archive_file *file)
|
||||
/* single archive handling */
|
||||
|
||||
struct iso9660_input_stream {
|
||||
struct input_stream base;
|
||||
|
||||
struct iso9660_archive_file *archive;
|
||||
|
||||
iso9660_stat_t *statbuf;
|
||||
size_t max_blocks;
|
||||
};
|
||||
|
||||
static bool
|
||||
iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
static struct input_stream *
|
||||
iso9660_archive_open_stream(struct archive_file *file,
|
||||
const char *pathname, GError **error_r)
|
||||
{
|
||||
struct iso9660_archive_file *context =
|
||||
@@ -178,6 +180,7 @@ iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
struct iso9660_input_stream *iis;
|
||||
|
||||
iis = g_new(struct iso9660_input_stream, 1);
|
||||
input_stream_init(&iis->base, &iso9660_input_plugin);
|
||||
|
||||
iis->archive = context;
|
||||
iis->statbuf = iso9660_ifs_stat_translate(context->iso, pathname);
|
||||
@@ -185,31 +188,26 @@ iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
g_free(iis);
|
||||
g_set_error(error_r, iso9660_quark(), 0,
|
||||
"not found in the ISO file: %s", pathname);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//setup file ops
|
||||
is->plugin = &iso9660_input_plugin;
|
||||
//insert back reference
|
||||
is->data = iis;
|
||||
is->ready = true;
|
||||
iis->base.ready = true;
|
||||
//we are not seekable
|
||||
is->seekable = false;
|
||||
iis->base.seekable = false;
|
||||
|
||||
is->size = iis->statbuf->size;
|
||||
iis->base.size = iis->statbuf->size;
|
||||
|
||||
iis->max_blocks = CEILING(iis->statbuf->size, ISO_BLOCKSIZE);
|
||||
|
||||
refcount_inc(&context->ref);
|
||||
|
||||
return true;
|
||||
return &iis->base;
|
||||
}
|
||||
|
||||
static void
|
||||
iso9660_input_close(struct input_stream *is)
|
||||
{
|
||||
struct iso9660_input_stream *iis =
|
||||
(struct iso9660_input_stream *)is->data;
|
||||
struct iso9660_input_stream *iis = (struct iso9660_input_stream *)is;
|
||||
|
||||
g_free(iis->statbuf);
|
||||
|
||||
@@ -220,8 +218,7 @@ iso9660_input_close(struct input_stream *is)
|
||||
static size_t
|
||||
iso9660_input_read(struct input_stream *is, void *ptr, size_t size, GError **error_r)
|
||||
{
|
||||
struct iso9660_input_stream *iis =
|
||||
(struct iso9660_input_stream *)is->data;
|
||||
struct iso9660_input_stream *iis = (struct iso9660_input_stream *)is;
|
||||
int toread, readed = 0;
|
||||
int no_blocks, cur_block;
|
||||
size_t left_bytes = iis->statbuf->size - is->offset;
|
||||
|
@@ -125,13 +125,15 @@ zzip_archive_close(struct archive_file *file)
|
||||
/* single archive handling */
|
||||
|
||||
struct zzip_input_stream {
|
||||
struct input_stream base;
|
||||
|
||||
struct zzip_archive *archive;
|
||||
|
||||
ZZIP_FILE *file;
|
||||
};
|
||||
|
||||
static bool
|
||||
zzip_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
static struct input_stream *
|
||||
zzip_archive_open_stream(struct archive_file *file,
|
||||
const char *pathname, GError **error_r)
|
||||
{
|
||||
struct zzip_archive *context = (struct zzip_archive *) file;
|
||||
@@ -139,6 +141,7 @@ zzip_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
ZZIP_STAT z_stat;
|
||||
|
||||
zis = g_new(struct zzip_input_stream, 1);
|
||||
input_stream_init(&zis->base, &zzip_input_plugin);
|
||||
|
||||
zis->archive = context;
|
||||
zis->file = zzip_file_open(context->dir, pathname, 0);
|
||||
@@ -146,29 +149,25 @@ zzip_archive_open_stream(struct archive_file *file, struct input_stream *is,
|
||||
g_free(zis);
|
||||
g_set_error(error_r, zzip_quark(), 0,
|
||||
"not found in the ZIP file: %s", pathname);
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//setup file ops
|
||||
is->plugin = &zzip_input_plugin;
|
||||
//insert back reference
|
||||
is->data = zis;
|
||||
is->ready = true;
|
||||
zis->base.ready = true;
|
||||
//we are seekable (but its not recommendent to do so)
|
||||
is->seekable = true;
|
||||
zis->base.seekable = true;
|
||||
|
||||
zzip_file_stat(zis->file, &z_stat);
|
||||
is->size = z_stat.st_size;
|
||||
zis->base.size = z_stat.st_size;
|
||||
|
||||
refcount_inc(&context->ref);
|
||||
|
||||
return true;
|
||||
return &zis->base;
|
||||
}
|
||||
|
||||
static void
|
||||
zzip_input_close(struct input_stream *is)
|
||||
{
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data;
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is;
|
||||
|
||||
zzip_file_close(zis->file);
|
||||
zzip_archive_close(&zis->archive->base);
|
||||
@@ -179,7 +178,7 @@ static size_t
|
||||
zzip_input_read(struct input_stream *is, void *ptr, size_t size,
|
||||
GError **error_r)
|
||||
{
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data;
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is;
|
||||
int ret;
|
||||
|
||||
ret = zzip_file_read(zis->file, ptr, size);
|
||||
@@ -197,7 +196,7 @@ zzip_input_read(struct input_stream *is, void *ptr, size_t size,
|
||||
static bool
|
||||
zzip_input_eof(struct input_stream *is)
|
||||
{
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data;
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is;
|
||||
|
||||
return (goffset)zzip_tell(zis->file) == is->size;
|
||||
}
|
||||
@@ -206,7 +205,7 @@ static bool
|
||||
zzip_input_seek(struct input_stream *is,
|
||||
goffset offset, int whence, GError **error_r)
|
||||
{
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is->data;
|
||||
struct zzip_input_stream *zis = (struct zzip_input_stream *)is;
|
||||
zzip_off_t ofs = zzip_seek(zis->file, offset, whence);
|
||||
if (ofs != -1) {
|
||||
g_set_error(error_r, zzip_quark(), ofs,
|
||||
|
Reference in New Issue
Block a user