mirror of
https://github.com/mpv-player/mpv
synced 2025-03-21 10:51:51 +00:00
libarchive: unify entry iteration between stream/demux layers
No really good reason to duplicate this.
This commit is contained in:
parent
77e1e8e38e
commit
fb8deb69a6
@ -65,23 +65,10 @@ static int open_file(struct demuxer *demuxer, enum demux_check check)
|
|||||||
char **files = NULL;
|
char **files = NULL;
|
||||||
int num_files = 0;
|
int num_files = 0;
|
||||||
|
|
||||||
for (;;) {
|
while (mp_archive_next_entry(mpa)) {
|
||||||
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);
|
|
||||||
// stream_libarchive.c does the real work
|
// 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);
|
MP_TARRAY_APPEND(mpa, files, num_files, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +218,7 @@ struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
|
|||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
struct mp_archive *mpa = talloc_zero(NULL, struct mp_archive);
|
struct mp_archive *mpa = talloc_zero(NULL, struct mp_archive);
|
||||||
|
mpa->log = log;
|
||||||
mpa->arch = archive_read_new();
|
mpa->arch = archive_read_new();
|
||||||
mpa->primary_src = src;
|
mpa->primary_src = src;
|
||||||
if (!mpa->arch)
|
if (!mpa->arch)
|
||||||
@ -265,6 +266,43 @@ err:
|
|||||||
return NULL;
|
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 priv {
|
||||||
struct mp_archive *mpa;
|
struct mp_archive *mpa;
|
||||||
struct stream *src;
|
struct stream *src;
|
||||||
@ -282,39 +320,18 @@ static int reopen_archive(stream_t *s)
|
|||||||
|
|
||||||
// Follows the same logic as demux_libarchive.c.
|
// Follows the same logic as demux_libarchive.c.
|
||||||
struct mp_archive *mpa = p->mpa;
|
struct mp_archive *mpa = p->mpa;
|
||||||
int num_files = 0;
|
while (mp_archive_next_entry(mpa)) {
|
||||||
for (;;) {
|
if (strcmp(p->entry_name, mpa->entry_filename) == 0) {
|
||||||
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) {
|
|
||||||
p->entry_size = -1;
|
p->entry_size = -1;
|
||||||
if (archive_entry_size_is_set(entry))
|
if (archive_entry_size_is_set(mpa->entry))
|
||||||
p->entry_size = archive_entry_size(entry);
|
p->entry_size = archive_entry_size(mpa->entry);
|
||||||
return STREAM_OK;
|
return STREAM_OK;
|
||||||
}
|
}
|
||||||
num_files++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
|
||||||
mp_archive_free(p->mpa);
|
mp_archive_free(p->mpa);
|
||||||
p->mpa = NULL;
|
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;
|
return STREAM_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
struct mp_log;
|
struct mp_log;
|
||||||
|
|
||||||
struct mp_archive {
|
struct mp_archive {
|
||||||
|
struct mp_log *log;
|
||||||
struct archive *arch;
|
struct archive *arch;
|
||||||
struct stream *primary_src;
|
struct stream *primary_src;
|
||||||
char buffer[4096];
|
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);
|
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
|
#define MP_ARCHIVE_FLAG_UNSAFE 1
|
||||||
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
|
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
|
||||||
int flags);
|
int flags);
|
||||||
|
|
||||||
|
bool mp_archive_next_entry(struct mp_archive *mpa);
|
||||||
|
Loading…
Reference in New Issue
Block a user