archive_plugin: wrap method calls

Make archive_file a "real" struct, extended by all plugins.  Add the
plugin pointer to it.  Wrap all method calls in functions.
This commit is contained in:
Max Kellermann 2009-12-16 16:28:26 +01:00
parent 74156d5bed
commit 0bc8c0c1da
9 changed files with 133 additions and 12 deletions

View File

@ -369,6 +369,7 @@ if ENABLE_ARCHIVE
ARCHIVE_SRC += \
src/archive_api.c \
src/archive_list.c \
src/archive_plugin.c \
src/input/archive_input_plugin.c
endif

View File

@ -40,6 +40,8 @@
#define BZ_BUFSIZE 5000
struct bz2_archive_file {
struct archive_file base;
char *name;
bool reset;
struct input_stream istream;
@ -102,6 +104,7 @@ bz2_open(const char *pathname)
int len;
context = g_malloc(sizeof(*context));
archive_file_init(&context->base, &bz2_archive_plugin);
//open archive
if (!input_stream_open(&context->istream, pathname, NULL)) {
@ -118,7 +121,7 @@ bz2_open(const char *pathname)
context->name[len - 4] = 0; //remove .bz2 suffix
}
return (struct archive_file *) context;
return &context->base;
}
static void

View File

@ -35,6 +35,8 @@
#define CEILING(x, y) ((x+(y-1))/y)
struct iso9660_archive_file {
struct archive_file base;
iso9660_t *iso;
iso9660_stat_t *statbuf;
size_t cur_ofs;
@ -93,6 +95,8 @@ iso9660_archive_open(const char *pathname)
struct iso9660_archive_file *context =
g_new(struct iso9660_archive_file, 1);
archive_file_init(&context->base, &iso9660_archive_plugin);
context->list = NULL;
/* open archive */
@ -104,7 +108,7 @@ iso9660_archive_open(const char *pathname)
listdir_recur("/", context);
return (struct archive_file *)context;
return &context->base;
}
static void

View File

@ -32,6 +32,8 @@
#include <string.h>
struct zzip_archive {
struct archive_file base;
ZZIP_DIR *dir;
ZZIP_FILE *file;
size_t length;
@ -55,6 +57,8 @@ zzip_archive_open(const char *pathname)
struct zzip_archive *context = g_malloc(sizeof(*context));
ZZIP_DIRENT dirent;
archive_file_init(&context->base, &zzip_archive_plugin);
// open archive
context->list = NULL;
context->dir = zzip_dir_open(pathname, NULL);
@ -71,7 +75,7 @@ zzip_archive_open(const char *pathname)
}
}
return (struct archive_file *)context;
return &context->base;
}
static void

View File

@ -21,7 +21,14 @@
#define MPD_ARCHIVE_INTERNAL_H
struct archive_file {
int placeholder;
const struct archive_plugin *plugin;
};
static inline void
archive_file_init(struct archive_file *archive_file,
const struct archive_plugin *plugin)
{
archive_file->plugin = plugin;
}
#endif

87
src/archive_plugin.c Normal file
View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "archive_plugin.h"
#include "archive_internal.h"
#include <assert.h>
struct archive_file *
archive_file_open(const struct archive_plugin *plugin, const char *path)
{
struct archive_file *file;
assert(plugin != NULL);
assert(plugin->open != NULL);
assert(path != NULL);
file = plugin->open(path);
if (file != NULL) {
assert(file->plugin != NULL);
assert(file->plugin->close != NULL);
assert(file->plugin->scan_reset != NULL);
assert(file->plugin->scan_next != NULL);
assert(file->plugin->open_stream != NULL);
}
return file;
}
void
archive_file_close(struct archive_file *file)
{
assert(file != NULL);
assert(file->plugin != NULL);
assert(file->plugin->close != NULL);
file->plugin->close(file);
}
void
archive_file_scan_reset(struct archive_file *file)
{
assert(file != NULL);
assert(file->plugin != NULL);
assert(file->plugin->scan_reset != NULL);
assert(file->plugin->scan_next != NULL);
file->plugin->scan_reset(file);
}
char *
archive_file_scan_next(struct archive_file *file)
{
assert(file != NULL);
assert(file->plugin != NULL);
assert(file->plugin->scan_next != NULL);
return file->plugin->scan_next(file);
}
bool
archive_file_open_stream(struct archive_file *file, struct input_stream *is,
const char *path, GError **error_r)
{
assert(file != NULL);
assert(file->plugin != NULL);
assert(file->plugin->open_stream != NULL);
return file->plugin->open_stream(file, is, path, error_r);
}

View File

@ -89,5 +89,20 @@ struct archive_plugin {
const char *const*suffixes;
};
#endif
struct archive_file *
archive_file_open(const struct archive_plugin *plugin, const char *path);
void
archive_file_close(struct archive_file *file);
void
archive_file_scan_reset(struct archive_file *file);
char *
archive_file_scan_next(struct archive_file *file);
bool
archive_file_open_stream(struct archive_file *file, struct input_stream *is,
const char *path, GError **error_r);
#endif

View File

@ -61,14 +61,14 @@ input_archive_open(struct input_stream *is, const char *pathname,
return false;
}
file = arplug->open(archive);
file = archive_file_open(arplug, archive);
//setup fileops
opened = arplug->open_stream(file, is, filename, error_r);
opened = archive_file_open_stream(file, is, filename, error_r);
g_free(pname);
if (!opened) {
arplug->close(file);
archive_file_close(file);
} else {
is->ready = true;
}

View File

@ -409,7 +409,7 @@ update_archive_file(struct directory *parent, const char *name,
path_fs = map_directory_child_fs(parent, name);
/* open archive */
file = plugin->open(path_fs);
file = archive_file_open(plugin, path_fs);
if (file == NULL) {
g_warning("unable to open archive %s", path_fs);
g_free(path_fs);
@ -429,15 +429,15 @@ update_archive_file(struct directory *parent, const char *name,
directory->mtime = st->st_mtime;
plugin->scan_reset(file);
archive_file_scan_reset(file);
while ((filepath = plugin->scan_next(file)) != NULL) {
while ((filepath = archive_file_scan_next(file)) != NULL) {
/* split name into directory and file */
g_debug("adding archive file: %s", filepath);
update_archive_tree(directory, filepath);
}
plugin->close(file);
archive_file_close(file);
}
#endif