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 += \ ARCHIVE_SRC += \
src/archive_api.c \ src/archive_api.c \
src/archive_list.c \ src/archive_list.c \
src/archive_plugin.c \
src/input/archive_input_plugin.c src/input/archive_input_plugin.c
endif endif

View File

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

View File

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

View File

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

View File

@ -21,7 +21,14 @@
#define MPD_ARCHIVE_INTERNAL_H #define MPD_ARCHIVE_INTERNAL_H
struct archive_file { 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 #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; 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; return false;
} }
file = arplug->open(archive); file = archive_file_open(arplug, archive);
//setup fileops //setup fileops
opened = arplug->open_stream(file, is, filename, error_r); opened = archive_file_open_stream(file, is, filename, error_r);
g_free(pname); g_free(pname);
if (!opened) { if (!opened) {
arplug->close(file); archive_file_close(file);
} else { } else {
is->ready = true; 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); path_fs = map_directory_child_fs(parent, name);
/* open archive */ /* open archive */
file = plugin->open(path_fs); file = archive_file_open(plugin, path_fs);
if (file == NULL) { if (file == NULL) {
g_warning("unable to open archive %s", path_fs); g_warning("unable to open archive %s", path_fs);
g_free(path_fs); g_free(path_fs);
@ -429,15 +429,15 @@ update_archive_file(struct directory *parent, const char *name,
directory->mtime = st->st_mtime; 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 */ /* split name into directory and file */
g_debug("adding archive file: %s", filepath); g_debug("adding archive file: %s", filepath);
update_archive_tree(directory, filepath); update_archive_tree(directory, filepath);
} }
plugin->close(file); archive_file_close(file);
} }
#endif #endif