0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

libarchive: unify entry iteration between stream/demux layers

No really good reason to duplicate this.
This commit is contained in:
wm4 2016-07-18 12:44:56 +02:00
parent 77e1e8e38e
commit fb8deb69a6
3 changed files with 54 additions and 42 deletions

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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);