summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2016-07-18 12:44:56 +0200
committerwm4 <wm4@nowhere>2016-07-18 12:44:56 +0200
commitfb8deb69a6afc311deb2c3f9bfa13e460e03256f (patch)
treeca2a9f62c9c1b551c1a874494252641378dcda8a
parent77e1e8e38e7b8d9318dc1bb437a88d8f13b7a5c9 (diff)
downloadmpv-fb8deb69a6afc311deb2c3f9bfa13e460e03256f.tar.bz2
mpv-fb8deb69a6afc311deb2c3f9bfa13e460e03256f.tar.xz
libarchive: unify entry iteration between stream/demux layers
No really good reason to duplicate this.
-rw-r--r--demux/demux_libarchive.c19
-rw-r--r--stream/stream_libarchive.c69
-rw-r--r--stream/stream_libarchive.h8
3 files changed, 54 insertions, 42 deletions
diff --git a/demux/demux_libarchive.c b/demux/demux_libarchive.c
index 3f1a655726..dcdbe65fc0 100644
--- a/demux/demux_libarchive.c
+++ b/demux/demux_libarchive.c
@@ -65,23 +65,10 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
char **files = NULL;
int num_files = 0;
- for (;;) {
- struct archive_entry *entry;
- int r = archive_read_next_header(mpa->arch, &entry);
- if (r == ARCHIVE_EOF)
- break;
- if (r < ARCHIVE_OK)
- MP_ERR(demuxer, "%s\n", archive_error_string(mpa->arch));
- if (r < ARCHIVE_WARN)
- break;
- if (archive_entry_filetype(entry) != AE_IFREG)
- continue;
- const char *fn = archive_entry_pathname(entry);
- // Some archives may have no filenames.
- if (!fn)
- fn = talloc_asprintf(mpa, "mpv_unknown#%d\n", num_files);
+ while (mp_archive_next_entry(mpa)) {
// stream_libarchive.c does the real work
- char *f = talloc_asprintf(mpa, "archive://%s|%s", prefix, fn);
+ char *f = talloc_asprintf(mpa, "archive://%s|%s", prefix,
+ mpa->entry_filename);
MP_TARRAY_APPEND(mpa, files, num_files, f);
}
diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c
index a164da85b8..9d93af5450 100644
--- a/stream/stream_libarchive.c
+++ b/stream/stream_libarchive.c
@@ -218,6 +218,7 @@ struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
int flags)
{
struct mp_archive *mpa = talloc_zero(NULL, struct mp_archive);
+ mpa->log = log;
mpa->arch = archive_read_new();
mpa->primary_src = src;
if (!mpa->arch)
@@ -265,6 +266,43 @@ err:
return NULL;
}
+// Iterate entries. The first call establishes the first entry. Returns false
+// if no entry found, otherwise returns true and sets mpa->entry/entry_filename.
+bool mp_archive_next_entry(struct mp_archive *mpa)
+{
+ mpa->entry = NULL;
+ talloc_free(mpa->entry_filename);
+ mpa->entry_filename = NULL;
+
+ for (;;) {
+ struct archive_entry *entry;
+ int r = archive_read_next_header(mpa->arch, &entry);
+ if (r == ARCHIVE_EOF)
+ break;
+ if (r < ARCHIVE_OK)
+ MP_ERR(mpa, "%s\n", archive_error_string(mpa->arch));
+ if (r < ARCHIVE_WARN) {
+ MP_FATAL(mpa, "could not read archive entry\n");
+ break;
+ }
+ if (archive_entry_filetype(entry) != AE_IFREG)
+ continue;
+ // Some archives may have no filenames, or libarchive won't return some.
+ const char *fn = archive_entry_pathname(entry);
+ char buf[64];
+ if (!fn) {
+ snprintf(buf, sizeof(buf), "mpv_unknown#%d\n", mpa->entry_num);
+ fn = buf;
+ }
+ mpa->entry = entry;
+ mpa->entry_filename = talloc_strdup(mpa, fn);
+ mpa->entry_num += 1;
+ return true;
+ }
+
+ return false;
+}
+
struct priv {
struct mp_archive *mpa;
struct stream *src;
@@ -282,39 +320,18 @@ static int reopen_archive(stream_t *s)
// Follows the same logic as demux_libarchive.c.
struct mp_archive *mpa = p->mpa;
- int num_files = 0;
- for (;;) {
- struct archive_entry *entry;
- int r = archive_read_next_header(mpa->arch, &entry);
- if (r == ARCHIVE_EOF) {
- MP_ERR(s, "archive entry not found. '%s'\n", p->entry_name);
- goto error;
- }
- if (r < ARCHIVE_OK)
- MP_ERR(s, "%s\n", archive_error_string(mpa->arch));
- if (r < ARCHIVE_WARN)
- goto error;
- if (archive_entry_filetype(entry) != AE_IFREG)
- continue;
- const char *fn = archive_entry_pathname(entry);
- char buf[64];
- if (!fn) {
- snprintf(buf, sizeof(buf), "mpv_unknown#%d\n", num_files);
- fn = buf;
- }
- if (strcmp(p->entry_name, fn) == 0) {
+ while (mp_archive_next_entry(mpa)) {
+ if (strcmp(p->entry_name, mpa->entry_filename) == 0) {
p->entry_size = -1;
- if (archive_entry_size_is_set(entry))
- p->entry_size = archive_entry_size(entry);
+ if (archive_entry_size_is_set(mpa->entry))
+ p->entry_size = archive_entry_size(mpa->entry);
return STREAM_OK;
}
- num_files++;
}
-error:
mp_archive_free(p->mpa);
p->mpa = NULL;
- MP_ERR(s, "could not open archive\n");
+ MP_ERR(s, "archive entry not found. '%s'\n", p->entry_name);
return STREAM_ERROR;
}
diff --git a/stream/stream_libarchive.h b/stream/stream_libarchive.h
index ebded5b5ba..c15dc1b528 100644
--- a/stream/stream_libarchive.h
+++ b/stream/stream_libarchive.h
@@ -1,9 +1,15 @@
struct mp_log;
struct mp_archive {
+ struct mp_log *log;
struct archive *arch;
struct stream *primary_src;
char buffer[4096];
+
+ // Current entry, as set by mp_archive_next_entry().
+ struct archive_entry *entry;
+ char *entry_filename;
+ int entry_num;
};
void mp_archive_free(struct mp_archive *mpa);
@@ -11,3 +17,5 @@ void mp_archive_free(struct mp_archive *mpa);
#define MP_ARCHIVE_FLAG_UNSAFE 1
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
int flags);
+
+bool mp_archive_next_entry(struct mp_archive *mpa);