diff --git a/demo/cat.c b/demo/cat.c index 4a42191..a95eebc 100644 --- a/demo/cat.c +++ b/demo/cat.c @@ -42,7 +42,7 @@ int main(int argc, char **argv) return 1; } - res = file->lstat(file, &info); + res = iso_file_source_lstat(file, &info); if (res < 0) { fprintf(stderr, "Can't stat file, err = %d\n", res); return 1; @@ -53,19 +53,19 @@ int main(int argc, char **argv) return 1; } else { char buf[1024]; - res = file->open(file); + res = iso_file_source_open(file); if (res < 0) { fprintf(stderr, "Can't open file, err = %d\n", res); return 1; } - while ((res = file->read(file, buf, 1024)) > 0) { + while ((res = iso_file_source_read(file, buf, 1024)) > 0) { fwrite(buf, 1, res, stdout); } if (res < 0) { fprintf(stderr, "Error reading, err = %d\n", res); return 1; } - file->close(file); + iso_file_source_close(file); } iso_file_source_unref(file); diff --git a/demo/lsl.c b/demo/lsl.c index 6dae4c1..17659f7 100644 --- a/demo/lsl.c +++ b/demo/lsl.c @@ -56,16 +56,16 @@ print_file_src(IsoFileSource *file) { struct stat info; char *name; - file->lstat(file, &info); + iso_file_source_lstat(file, &info); print_type(info.st_mode); print_permissions(info.st_mode); printf(" {%ld,%ld} ", (long)info.st_dev, (long)info.st_ino); - name = file->get_name(file); + name = iso_file_source_get_name(file); printf(" %s", name); free(name); if (S_ISLNK(info.st_mode)) { char buf[PATH_MAX]; - file->readlink(file, buf, PATH_MAX); + iso_file_source_readlink(file, buf, PATH_MAX); printf(" -> %s\n", buf); } printf("\n"); @@ -97,25 +97,25 @@ int main(int argc, char **argv) return 1; } - res = dir->lstat(dir, &info); + res = iso_file_source_lstat(dir, &info); if (res < 0) { fprintf(stderr, "Can't stat file, err = %d\n", res); return 1; } if (S_ISDIR(info.st_mode)) { - res = dir->open(dir); + res = iso_file_source_open(dir); if (res < 0) { fprintf(stderr, "Can't open file, err = %d\n", res); return 1; } - while (dir->readdir(dir, &file) == 1) { + while (iso_file_source_readdir(dir, &file) == 1) { print_file_src(file); iso_file_source_unref(file); } - res = dir->close(dir); + res = iso_file_source_close(dir); if (res < 0) { fprintf(stderr, "Can't close file, err = %d\n", res); return 1; diff --git a/src/builder.c b/src/builder.c index d1dd79a..3af4adf 100644 --- a/src/builder.c +++ b/src/builder.c @@ -43,7 +43,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image, return ISO_NULL_POINTER; } - res = src->stat(src, &info); + res = iso_file_source_stat(src, &info); if (res < 0) { return res; } @@ -65,7 +65,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image, /* fill node fields */ node->node.refcount = 1; node->node.type = LIBISO_FILE; - node->node.name = strdup(src->get_name(src)); + node->node.name = strdup(iso_file_source_get_name(src)); node->node.mode = S_IFREG | (info.st_mode & ~S_IFMT); node->node.uid = info.st_uid; node->node.gid = info.st_gid; @@ -96,13 +96,13 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image, return ISO_NULL_POINTER; } - name = src->get_name(src); + name = iso_file_source_get_name(src); /* get info about source */ if (image->recOpts->follow_symlinks) { - result = src->stat(src, &info); + result = iso_file_source_stat(src, &info); } else { - result = src->lstat(src, &info); + result = iso_file_source_lstat(src, &info); } if (result < 0) { return result; @@ -149,7 +149,7 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image, char dest[PATH_MAX]; IsoSymlink *link; - result = src->readlink(src, dest, PATH_MAX); + result = iso_file_source_readlink(src, dest, PATH_MAX); if (result < 0) { return result; } diff --git a/src/fs_local.c b/src/fs_local.c index 7211422..9adfa9f 100644 --- a/src/fs_local.c +++ b/src/fs_local.c @@ -381,7 +381,7 @@ void lfs_free(IsoFileSource *src) /* close the file if it is already openned */ if (data->openned) { - src->close(src); + src->class->close(src); } free(data->path); @@ -389,6 +389,20 @@ void lfs_free(IsoFileSource *src) iso_filesystem_unref(lfs); } +IsoFileSourceIface lfs_class = { + lfs_get_path, + lfs_get_name, + lfs_lstat, + lfs_stat, + lfs_open, + lfs_close, + lfs_read, + lfs_readdir, + lfs_readlink, + lfs_get_filesystem, + lfs_free +}; + /** * * @return @@ -435,17 +449,7 @@ int iso_file_source_new_lfs(const char *path, IsoFileSource **src) lfs_src->refcount = 1; lfs_src->data = data; - lfs_src->get_path = lfs_get_path; - lfs_src->get_name = lfs_get_name; - lfs_src->lstat = lfs_lstat; - lfs_src->stat = lfs_stat; - lfs_src->open = lfs_open; - lfs_src->close = lfs_close; - lfs_src->read = lfs_read; - lfs_src->readdir = lfs_readdir; - lfs_src->readlink = lfs_readlink; - lfs_src->get_filesystem = lfs_get_filesystem; - lfs_src->free = lfs_free; + lfs_src->class = &lfs_class; /* take a ref to local filesystem */ iso_filesystem_ref(lfs); diff --git a/src/fsource.c b/src/fsource.c index 3bd4480..0c62830 100644 --- a/src/fsource.c +++ b/src/fsource.c @@ -22,7 +22,7 @@ void iso_file_source_ref(IsoFileSource *src) void iso_file_source_unref(IsoFileSource *src) { if (--src->refcount == 0) { - src->free(src); + src->class->free(src); free(src); } } diff --git a/src/fsource.h b/src/fsource.h index b433ead..119fc4d 100644 --- a/src/fsource.h +++ b/src/fsource.h @@ -69,7 +69,7 @@ struct Iso_Filesystem void *data; }; -struct Iso_File_Source +typedef struct IsoFileSource_Iface { /** @@ -231,7 +231,10 @@ struct Iso_File_Source * TODO #00004 Add a get_mime_type() function. * This can be useful for GUI apps, to choose the icon of the file */ - +} IsoFileSourceIface; + +struct Iso_File_Source { + const IsoFileSourceIface *class; int refcount; void *data; }; @@ -239,6 +242,60 @@ struct Iso_File_Source void iso_file_source_ref(IsoFileSource *src); void iso_file_source_unref(IsoFileSource *src); +/* + * this are just helpers to invoque methods in class + */ +extern inline +const char* iso_file_source_get_path(IsoFileSource *src) { + return src->class->get_path(src); +} + +extern inline +char* iso_file_source_get_name(IsoFileSource *src) { + return src->class->get_name(src); +} + +extern inline +int iso_file_source_lstat(IsoFileSource *src, struct stat *info) { + return src->class->lstat(src, info); +} + +extern inline +int iso_file_source_stat(IsoFileSource *src, struct stat *info) { + return src->class->stat(src, info); +} + +extern inline +int iso_file_source_open(IsoFileSource *src) { + return src->class->open(src); +} + +extern inline +int iso_file_source_close(IsoFileSource *src) { + return src->class->close(src); +} + +extern inline +int iso_file_source_read(IsoFileSource *src, void *buf, size_t count) { + return src->class->read(src, buf, count); +} + +extern inline +int iso_file_source_readdir(IsoFileSource *src, IsoFileSource **child) +{ + return src->class->readdir(src, child); +} + +extern inline +int iso_file_source_readlink(IsoFileSource *src, char *buf, size_t bufsiz) { + return src->class->readlink(src, buf, bufsiz); +} + +extern inline +IsoFilesystem* iso_file_source_get_filesystem(IsoFileSource *src) { + return src->class->get_filesystem(src); +} + /** * Create a new IsoFileSource from a local filesystem path. * While this is usually called by corresponding method in IsoFilesystem diff --git a/src/stream.c b/src/stream.c index 9abf101..9a48392 100644 --- a/src/stream.c +++ b/src/stream.c @@ -31,7 +31,7 @@ int fsrc_open(IsoStream *stream) return ISO_NULL_POINTER; } src = ((FSrcStreamData*)stream->data)->src; - return src->open(src); + return iso_file_source_open(src); } static @@ -42,7 +42,7 @@ int fsrc_close(IsoStream *stream) return ISO_NULL_POINTER; } src = ((FSrcStreamData*)stream->data)->src; - return src->close(src); + return iso_file_source_close(src); } static @@ -62,7 +62,7 @@ int fsrc_read(IsoStream *stream, void *buf, size_t count) return ISO_NULL_POINTER; } src = ((FSrcStreamData*)stream->data)->src; - return src->read(src, buf, count); + return iso_file_source_read(src, buf, count); } static @@ -77,7 +77,7 @@ int fsrc_is_repeatable(IsoStream *stream) data = (FSrcStreamData*)stream->data; /* mode is not cached, this function is only useful for filters */ - ret = data->src->stat(data->src, &info); + ret = iso_file_source_stat(data->src, &info); if (ret < 0) { return ret; } @@ -100,7 +100,7 @@ int fsrc_get_id(IsoStream *stream, unsigned int *fs_id, dev_t *dev_id, } data = (FSrcStreamData*)stream->data; - fs = data->src->get_filesystem(data->src); + fs = iso_file_source_get_filesystem(data->src); *fs_id = fs->get_id(fs); if (fs_id == 0) { @@ -132,7 +132,7 @@ int iso_file_source_stream_new(IsoFileSource *src, IsoStream **stream) return ISO_NULL_POINTER; } - r = src->stat(src, &info); + r = iso_file_source_stat(src, &info); if (r < 0) { return r; } diff --git a/src/tree.c b/src/tree.c index 7c5c586..0d1d43b 100644 --- a/src/tree.c +++ b/src/tree.c @@ -313,7 +313,7 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent, *node = NULL; } - name = src->get_name(src); + name = iso_file_source_get_name(src); /* find place where to insert */ pos = &(parent->children); @@ -400,24 +400,25 @@ int iso_add_dir_aux(IsoImage *image, IsoDir *parent, IsoFileSource *dir) IsoFileSource *file; IsoNode **pos; - result = dir->open(dir); + result = iso_file_source_open(dir); if (result < 0) { - iso_msg_debug(image, "Can't open dir %s", dir->get_path(dir)); + iso_msg_debug(image, "Can't open dir %s", + iso_file_source_get_path(dir)); return result; } builder = image->builder; action = 1; - while ( (result = dir->readdir(dir, &file)) == 1) { + while ( (result = iso_file_source_readdir(dir, &file)) == 1) { int flag; char *name; IsoNode *new; - iso_msg_debug(image, "Adding file %s", file->get_path(file)); + iso_msg_debug(image, "Adding file %s", iso_file_source_get_path(file)); - name = file->get_name(file); + name = iso_file_source_get_name(file); - if (check_excludes(image, file->get_path(file))) { + if (check_excludes(image, iso_file_source_get_path(file))) { action = 2; } else if (check_hidden(image, name)) { action = 2; @@ -458,7 +459,7 @@ int iso_add_dir_aux(IsoImage *image, IsoDir *parent, IsoFileSource *dir) if (result < 0) { iso_msg_debug(image, "Error %d when adding file %s", - result, file->get_path(file)); + result, iso_file_source_get_path(file)); if (image->recOpts->report) { action = image->recOpts->report(file, result, flag); @@ -521,7 +522,7 @@ int iso_add_dir_aux(IsoImage *image, IsoDir *parent, IsoFileSource *dir) action = result; } - result = dir->close(dir); + result = iso_file_source_close(dir); if (result < 0) { return result; } @@ -552,7 +553,7 @@ int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir) } /* we also allow dir path to be a symlink to a dir */ - result = file->stat(file, &info); + result = iso_file_source_stat(file, &info); if (result < 0) { iso_file_source_unref(file); return result; diff --git a/test/mocked_fsrc.c b/test/mocked_fsrc.c index a3f2c31..618ad17 100644 --- a/test/mocked_fsrc.c +++ b/test/mocked_fsrc.c @@ -171,6 +171,20 @@ void mfs_free(IsoFileSource *src) free(data); } +IsoFileSourceIface mfs_class = { + mfs_get_path, + mfs_get_name, + mfs_lstat, + mfs_stat, + mfs_open, + mfs_close, + mfs_read, + mfs_readdir, + mfs_readlink, + mfs_get_filesystem, + mfs_free +}; + /** * * @return @@ -214,17 +228,7 @@ int mocked_file_source_new(IsoFilesystem *fs, const char *path, mocked_src->refcount = 1; mocked_src->data = data; - mocked_src->get_path = mfs_get_path; - mocked_src->get_name = mfs_get_name; - mocked_src->lstat = mfs_lstat; - mocked_src->stat = mfs_stat; - mocked_src->open = mfs_open; - mocked_src->close = mfs_close; - mocked_src->read = mfs_read; - mocked_src->readdir = mfs_readdir; - mocked_src->readlink = mfs_readlink; - mocked_src->get_filesystem = mfs_get_filesystem; - mocked_src->free = mfs_free; + mocked_src->class = &mfs_class; /* take a ref to filesystem */ iso_filesystem_ref(fs);