From: Michael Tremer Date: Wed, 7 Apr 2021 15:37:57 +0000 (+0000) Subject: archive: Read metadata only when needed X-Git-Tag: 0.9.28~1285^2~404 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4372da146fa317799a2c8e9ed977c490a572a89b;p=pakfire.git archive: Read metadata only when needed Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index d488ebd5b..e764e8c95 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -368,19 +368,9 @@ static int pakfire_archive_create(PakfireArchive* archive, Pakfire pakfire) { STAILQ_INIT(&a->chksums); - // Setup the parser - a->parser = pakfire_parser_create(pakfire, NULL, NULL, 0); - if (!a->parser) - goto ERROR; - *archive = a; return 0; - -ERROR: - pakfire_archive_free(a); - - return 1; } PAKFIRE_EXPORT PakfireArchive pakfire_archive_ref(PakfireArchive archive) { @@ -402,6 +392,69 @@ PAKFIRE_EXPORT Pakfire pakfire_archive_get_pakfire(PakfireArchive archive) { return pakfire_ref(archive->pakfire); } +// Metadata + +static int pakfire_archive_parse_metadata(PakfireArchive archive) { + struct archive* a = NULL; + struct archive_entry* entry = NULL; + + char* data = NULL; + size_t size; + + // Do nothing if this has already been loaded + if (archive->parser) + return 0; + + // Open the archive + int r = archive_open(archive, &a); + if (r) + goto ERROR; + + // Find the metadata file + r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_METADATA); + if (r) { + ERROR(archive->pakfire, "Could not find metadata in %s\n", archive->path); + goto ERROR; + } + + // Read the data into memory + r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, entry, &data, &size); + if (r) { + ERROR(archive->pakfire, "Could not read metadata: %s\n", archive_error_string(a)); + goto ERROR; + } + + // Allocate a new parser + archive->parser = pakfire_parser_create(archive->pakfire, NULL, NULL, 0); + if (!archive->parser) + goto ERROR; + + // Parse the metadata + r = pakfire_parser_parse_data(archive->parser, data, size, NULL); + if (r) { + ERROR(archive->pakfire, "Error parsing metadata\n"); + goto ERROR; + } + + // Success + r = 0; + goto CLEANUP; + +ERROR: + if (archive->parser) { + pakfire_parser_unref(archive->parser); + archive->parser = NULL; + } + +CLEANUP: + if (data) + free(data); + if (a) + archive_read_free(a); + + return r; +} + static int pakfire_archive_parse_entry_format(PakfireArchive archive, struct archive* a, struct archive_entry* e) { char format[10]; @@ -416,22 +469,6 @@ static int pakfire_archive_parse_entry_format(PakfireArchive archive, return (archive->format < 0); } -static int pakfire_archive_parse_entry_metadata(PakfireArchive archive, - struct archive* a, struct archive_entry* e) { - char* data; - size_t data_size; - - int r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, &data, &data_size); - if (r) - return r; - - // Parse metadata file - r = pakfire_parser_parse_data(archive->parser, data, data_size, NULL); - free(data); - - return r; -} - static int pakfire_archive_parse_entry_filelist(PakfireArchive archive, struct archive* a, struct archive_entry* e) { char* data; @@ -595,14 +632,8 @@ static int pakfire_archive_read_metadata_entry(PakfireArchive archive, struct ar // If the format is set, we can go on... } else { - // Parse the metadata - if (strcmp(PAKFIRE_ARCHIVE_FN_METADATA, entry_name) == 0) { - ret = pakfire_archive_parse_entry_metadata(archive, a, e); - if (ret) - return EINVAL; - // Parse the filelist - } else if (strcmp(PAKFIRE_ARCHIVE_FN_FILELIST, entry_name) == 0) { + if (strcmp(PAKFIRE_ARCHIVE_FN_FILELIST, entry_name) == 0) { ret = pakfire_archive_parse_entry_filelist(archive, a, e); if (ret) return EINVAL; @@ -679,6 +710,10 @@ ERROR: PAKFIRE_EXPORT char* pakfire_archive_get(PakfireArchive archive, const char* namespace, const char* key) { + int r = pakfire_archive_parse_metadata(archive); + if (r) + return NULL; + return pakfire_parser_get(archive->parser, namespace, key); }