diff options
author | Lukasz Marek <lukasz.m.luki2@gmail.com> | 2014-07-05 18:11:59 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2015-03-27 18:29:46 +0100 |
commit | 184084c6998cd04c0afdda076d7c95be0d6b2d22 (patch) | |
tree | eabe49bf64eac0d759da7230e0d10541fbe34779 /libavformat/avio.c | |
parent | dbce8cdacf0c610a69cbf0d2959d793957dd4dfa (diff) | |
download | ffmpeg-184084c6998cd04c0afdda076d7c95be0d6b2d22.tar.gz |
lavf: add directory listing API
API allows protocol implementations to provide API that
allows to list directory content.
API is similar to POSIX opendir/readdir/closedir.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/avio.c')
-rw-r--r-- | libavformat/avio.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libavformat/avio.c b/libavformat/avio.c index 4896782072..a990ea2229 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -23,6 +23,7 @@ #include "libavutil/dict.h" #include "libavutil/opt.h" #include "libavutil/time.h" +#include "libavutil/avassert.h" #include "os_support.h" #include "avformat.h" #if CONFIG_NETWORK @@ -418,6 +419,79 @@ int avio_check(const char *url, int flags) return ret; } +int avio_open_dir(AVIODirContext **s, const char *url, AVDictionary **options) +{ + URLContext *h = NULL; + AVIODirContext *ctx = NULL; + int ret; + av_assert0(s); + + ctx = av_mallocz(sizeof(*ctx)); + if (!ctx) { + ret = AVERROR(ENOMEM); + goto fail; + } + + if ((ret = ffurl_alloc(&h, url, AVIO_FLAG_READ, NULL)) < 0) + goto fail; + + if (h->prot->url_open_dir && h->prot->url_read_dir && h->prot->url_close_dir) { + if (options && h->prot->priv_data_class && + (ret = av_opt_set_dict(h->priv_data, options)) < 0) + goto fail; + ret = h->prot->url_open_dir(h); + } else + ret = AVERROR(ENOSYS); + if (ret < 0) + goto fail; + + ctx->url_context = h; + *s = ctx; + return 0; + + fail: + av_free(ctx); + *s = NULL; + ffurl_close(h); + return ret; +} + +int avio_read_dir(AVIODirContext *s, AVIODirEntry **next) +{ + URLContext *h; + int ret; + + if (!s || !s->url_context) + return AVERROR(EINVAL); + h = s->url_context; + if ((ret = h->prot->url_read_dir(h, next)) < 0) + avio_free_directory_entry(next); + return ret; +} + +int avio_close_dir(AVIODirContext **s) +{ + URLContext *h; + + av_assert0(s); + if (!(*s) || !(*s)->url_context) + return AVERROR(EINVAL); + h = (*s)->url_context; + h->prot->url_close_dir(h); + ffurl_close(h); + av_freep(s); + *s = NULL; + return 0; +} + +void avio_free_directory_entry(AVIODirEntry **entry) +{ + if (!entry || !*entry) + return; + av_free((*entry)->name); + av_freep(entry); +} + int64_t ffurl_size(URLContext *h) { int64_t pos, size; |