From 98ca7dcb7066df201a8fc9340b98c6a786082ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Thu, 20 Aug 2015 12:32:00 +0300 Subject: [PATCH] FS|libcore: Finding all available packages --- doomsday/sdk/libcore/src/filesys/package.cpp | 20 ++++++---- .../sdk/libcore/src/filesys/packageloader.cpp | 40 ++++++++++++++----- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/doomsday/sdk/libcore/src/filesys/package.cpp b/doomsday/sdk/libcore/src/filesys/package.cpp index 27293be732..89c75b4b8f 100644 --- a/doomsday/sdk/libcore/src/filesys/package.cpp +++ b/doomsday/sdk/libcore/src/filesys/package.cpp @@ -31,6 +31,8 @@ static String const PACKAGE("package"); static String const PACKAGE_ORDER("package.__order__"); static String const PACKAGE_IMPORT_PATH("package.importPath"); +static String const VAR_ID("ID"); + Package::Asset::Asset(Record const &rec) : RecordAccessor(rec) {} Package::Asset::Asset(Record const *rec) : RecordAccessor(rec) {} @@ -230,7 +232,7 @@ void Package::parseMetadata(File &packageFile) // static if(!needParse) return; // The package identifier and path are automatically set. - metadata.set("id", identifierForFile(packageFile)); + metadata.set(VAR_ID, identifierForFile(packageFile)); metadata.set("path", packageFile.path()); // Check for a ScriptedInfo source. @@ -266,8 +268,13 @@ void Package::parseMetadata(File &packageFile) // static void Package::validateMetadata(Record const &packageInfo) { + if(!packageInfo.has(VAR_ID)) + { + throw ValidationError("Package::validateMetadata", "Not a package"); + } + // A domain is required in all package identifiers. - DotPath const ident(packageInfo.gets("id")); + DotPath const ident(packageInfo.gets(VAR_ID)); if(ident.segmentCount() <= 1) { @@ -286,16 +293,15 @@ void Package::validateMetadata(Record const &packageInfo) .arg(packageInfo.gets("path"))); } - char const *required[] = { "title", "version", "license", "tags", 0 }; - - for(int i = 0; required[i]; ++i) + static char const *required[] = { "title", "version", "license", "tags" }; + for(char const *req : required) { - if(!packageInfo.has(required[i])) + if(!packageInfo.has(req)) { throw IncompleteMetadataError("Package::validateMetadata", QString("Package \"%1\" does not have '%2' in its metadata") .arg(packageInfo.gets("path")) - .arg(required[i])); + .arg(req)); } } } diff --git a/doomsday/sdk/libcore/src/filesys/packageloader.cpp b/doomsday/sdk/libcore/src/filesys/packageloader.cpp index c4d97c4eb9..4d9e178dcc 100644 --- a/doomsday/sdk/libcore/src/filesys/packageloader.cpp +++ b/doomsday/sdk/libcore/src/filesys/packageloader.cpp @@ -104,6 +104,19 @@ DENG2_PIMPL(PackageLoader) return int(found.size()); } + /** + * Parses or updates the metadata of a package, and checks it for validity. + * A ValidationError is thrown if the package metadata does not comply with the + * minimum requirements. + * + * @param packFile Package file (".pack" folder). + */ + static void checkPackage(File &packFile) + { + Package::parseMetadata(packFile); + Package::validateMetadata(packFile.info().subrecord("package")); + } + /** * Given a package identifier, pick one of the available versions of the package * based on predefined criteria. @@ -126,9 +139,7 @@ DENG2_PIMPL(PackageLoader) // Each must have a version specified. DENG2_FOR_EACH_CONST(FS::FoundFiles, i, found) { - File *pkg = *i; - Package::parseMetadata(*pkg); - Package::validateMetadata(pkg->info().subrecord("package")); + checkPackage(**i); } found.sort(ascendingPackagesByLatest); @@ -173,12 +184,23 @@ DENG2_PIMPL(PackageLoader) { if(i->first.fileNameExtension() == ".pack") { - String path = i->second->path(); - - // The special persistent data package should be ignored. - if(path == "/home/persist.pack") continue; - - list.append(path); + try + { + File &file = *i->second; + String path = file.path(); + + // The special persistent data package should be ignored. + if(path == "/home/persist.pack") continue; + + // Check the metadata. + checkPackage(file); + + list.append(path); + } + catch(Package::ValidationError const &) + { + // Not a loadable package. + } } } }