* Copyright 2018-2025, Andrew Lindesay <apl@lindesay.co.nz>.
* Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
* Copyright 2013, Rene Gollent, rene@gollent.com.
* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* All rights reserved. Distributed under the terms of the MIT License.
*
* Note that this file included code earlier from `MainWindow.cpp` and
* copyrights have been latterly been carried across in 2021.
*/
#include "LocalPkgDataLoadProcess.h"
#include <map>
#include <set>
#include <vector>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include <Autolock.h>
#include <Catalog.h>
#include <Roster.h>
#include <StringList.h>
#include "AppUtils.h"
#include "HaikuDepotConstants.h"
#include "Logger.h"
#include "PackageInfo.h"
#include "PackageKitUtils.h"
#include "PackageManager.h"
#include "PackageUtils.h"
#include "StorageUtils.h"
#include "package/RepositoryCache.h"
#include <package/Context.h>
#include <package/PackageRoster.h>
#include <package/RefreshRepositoryRequest.h>
#include <package/manager/Exceptions.h>
#include <package/manager/RepositoryBuilder.h>
#include <package/solver/SolverPackage.h>
#include <package/solver/SolverResult.h>
#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "LocalPkgDataLoadProcess"
using namespace BPackageKit;
using namespace BPackageKit::BManager::BPrivate;
class LocalPkgDataLoadProcessUtilsData {
public:
int32 CountPackages() const;
void AddPackage(PackageInfoRef packageInfo);
const PackageInfoRef
PackageByName(const BString& name) const;
int32 CountDepots() const;
void AddDepot(DepotInfoRef depotInfo);
const DepotInfoRef DepotByName(const BString& name) const;
int32 CountSolverPackages() const;
void AddSolverPackage(const BSolverPackage* solverPackage);
void AddRemotePackageName(const BString& name);
bool IsRemotePackageName(const BString& name) const;
void AddSystemFlaggedPackageFilename(const BString& filename);
void AddSystemInstalledPackage(const BPackageInfo& solverPackageInfo);
const PackageInfoRef
PackageBySystemInstalledFilename(const BString& filename);
public:
std::map<BString, DepotInfoRef>
fDepots;
std::vector<const BSolverPackage*>
fSolverPackages;
std::map<BString, PackageInfoRef>
fFoundPackages;
std::set<BString> fRemotePackageNames;
std::set<BString> fSystemFlaggedPackageFilenames;
std::map<BString, BString>
fSystemInstalledFilenamesToPackageNames;
};
class LocalPkgDataLoadProcessUtils {
public:
static void _NotifyError(const BString& messageText);
static status_t _CollateDepotInfos(LocalPkgDataLoadProcessUtilsData& data);
static status_t _InitPackageManager(PackageManager& manager);
static status_t _CollateSolverPackages(PackageManager& manager,
LocalPkgDataLoadProcessUtilsData& data);
static status_t _CollatePackagesData(PackageManager& manager,
LocalPkgDataLoadProcessUtilsData& data);
static status_t _CollatePackageData(PackageManager& manager,
const BSolverPackage* solverPackage,
LocalPkgDataLoadProcessUtilsData& data);
static status_t _CollateLocalDepotAndPackageData(
LocalPkgDataLoadProcessUtilsData& data);
static status_t _EnhanceSystemPackages(
LocalPkgDataLoadProcessUtilsData& data);
static status_t _PopulateModel(LocalPkgDataLoadProcessUtilsData& data,
Model* model, bool force);
static bool _IsHomeRepository(PackageManager& manager,
BSolverRepository* solverRepository);
static bool _IsSystemRepository(PackageManager& manager,
BSolverRepository* solverRepository);
static BString _LogMessageFromFatalError(BFatalErrorException& ex);
};
\param packageInfoListener is assigned to each package model object.
*/
LocalPkgDataLoadProcess::LocalPkgDataLoadProcess(Model* model, bool force)
:
AbstractProcess(),
fModel(model),
fForce(force)
{
}
LocalPkgDataLoadProcess::~LocalPkgDataLoadProcess()
{
}
const char*
LocalPkgDataLoadProcess::Name() const
{
return "LocalPkgDataLoadProcess";
}
const char*
LocalPkgDataLoadProcess::Description() const
{
return B_TRANSLATE("Reading repository data");
}
from MainWindow.cpp in order that the logic fits into the background
loading processes. The code needs to be broken up into methods with some
sort of a state object carrying the state of the process. As part of this,
better error handling and error reporting would also be advantageous.
*/
status_t
LocalPkgDataLoadProcess::RunInternal()
{
HDINFO("[%s] will refresh the package list", Name());
status_t result = B_OK;
LocalPkgDataLoadProcessUtilsData data;
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_CollateDepotInfos(data);
if (result == B_OK)
HDINFO("[%s] did collate %" B_PRIi32 " depots", Name(), data.CountDepots());
else
HDERROR("[%s] failed to collate depot infos", Name());
}
PackageManager manager(B_PACKAGE_INSTALLATION_LOCATION_HOME);
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_InitPackageManager(manager);
if (result == B_OK)
HDINFO("[%s] did initialize the package manager", Name());
else
HDERROR("[%s] failed to initialize the package manager", Name());
}
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_CollateSolverPackages(manager, data);
if (result == B_OK) {
HDINFO("[%s] did collate %" B_PRIi32 " solver packages", Name(),
data.CountSolverPackages());
} else {
HDERROR("[%s] failed to collate solver packages", Name());
}
}
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_CollatePackagesData(manager, data);
if (result == B_OK)
HDINFO("[%s] did collate %" B_PRIi32 " packages", Name(), data.CountPackages());
else
HDERROR("[%s] failed to collate packages", Name());
}
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_CollateLocalDepotAndPackageData(data);
if (result == B_OK)
HDINFO("[%s] did collate local depot and package data", Name());
else
HDERROR("[%s] failed to collate local depot and package data", Name());
}
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_EnhanceSystemPackages(data);
if (result == B_OK)
HDINFO("[%s] did enhance system packages", Name());
else
HDERROR("[%s] failed to enhance system packages", Name());
}
if (result == B_OK) {
result = LocalPkgDataLoadProcessUtils::_PopulateModel(data, fModel, fForce);
if (result == B_OK)
HDINFO("[%s] did populate model", Name());
else
HDERROR("[%s] failed to populate model", Name());
}
if (result == B_OK)
HDINFO("did refresh the package list");
else
HDERROR("failed to refresh the package list");
return result;
}
status_t
LocalPkgDataLoadProcessUtils::_CollateDepotInfos(LocalPkgDataLoadProcessUtilsData& data)
{
BPackageRoster roster;
BStringList repositoryNames;
status_t result = roster.GetRepositoryNames(repositoryNames);
if (result != B_OK)
return result;
for (int32 i = repositoryNames.CountStrings() - 1; i >= 0; i--) {
const BString& repositoryName = repositoryNames.StringAt(i);
DepotInfoBuilder depotInfoBuilder;
depotInfoBuilder.WithName(repositoryName);
BRepositoryConfig repoConfig;
status_t getRepositoryConfigStatus
= roster.GetRepositoryConfig(repositoryName, &repoConfig);
if (getRepositoryConfigStatus == B_OK) {
depotInfoBuilder.WithIdentifier(repoConfig.Identifier());
HDDEBUG("local repository [%s] identifier; [%s]", repositoryName.String(),
repoConfig.Identifier().String());
} else {
HDINFO("unable to obtain the repository config for local repository '%s'; %s",
repositoryName.String(), strerror(getRepositoryConfigStatus));
}
data.AddDepot(depotInfoBuilder.BuildRef());
}
return result;
}
status_t
LocalPkgDataLoadProcessUtils::_InitPackageManager(PackageManager& manager)
{
try {
manager.Init(PackageManager::B_ADD_INSTALLED_REPOSITORIES
| PackageManager::B_ADD_REMOTE_REPOSITORIES);
return B_OK;
} catch (BException& ex) {
BString message(B_TRANSLATE("An error occurred while initializing the package manager: "
"%message%"));
message.ReplaceFirst("%message%", ex.Message());
_NotifyError(message.String());
return B_ERROR;
}
}
status_t
LocalPkgDataLoadProcessUtils::_CollateSolverPackages(PackageManager& manager,
LocalPkgDataLoadProcessUtilsData& data)
{
BObjectList<BSolverPackage> packages;
status_t result = manager.Solver()->FindPackages("",
BSolver::B_FIND_CASE_INSENSITIVE | BSolver::B_FIND_IN_NAME | BSolver::B_FIND_IN_SUMMARY
| BSolver::B_FIND_IN_DESCRIPTION | BSolver::B_FIND_IN_PROVIDES,
packages);
if (result != B_OK) {
BString message(
B_TRANSLATE("An error occurred while obtaining the package list: %message%"));
message.ReplaceFirst("%message%", strerror(result));
_NotifyError(message.String());
} else if (packages.IsEmpty()) {
HDERROR("no packages were found");
result = B_ERROR;
}
if (result == B_OK) {
for (int32 i = packages.CountItems() - 1; i >= 0; i--)
data.AddSolverPackage(packages.ItemAt(i));
}
return result;
}
status_t
LocalPkgDataLoadProcessUtils::_CollatePackagesData(PackageManager& manager,
LocalPkgDataLoadProcessUtilsData& data)
{
std::vector<const BSolverPackage*>::iterator solverPackageIt;
status_t result = B_OK;
for (solverPackageIt = data.fSolverPackages.begin();
solverPackageIt != data.fSolverPackages.end() && result == B_OK; solverPackageIt++) {
const BSolverPackage* solverPackage = *solverPackageIt;
result = _CollatePackageData(manager, solverPackage, data);
}
return result;
}
the supplied `data`.
*/
status_t
LocalPkgDataLoadProcessUtils::_CollatePackageData(PackageManager& manager,
const BSolverPackage* solverPackage, LocalPkgDataLoadProcessUtilsData& data)
{
status_t result = B_OK;
const BPackageInfo& solverPackageInfo = solverPackage->Info();
const BString repositoryName = solverPackage->Repository()->Name();
const BString packageName = solverPackageInfo.Name();
PackageCoreInfoBuilder coreInfoBuilder;
PackageLocalizedTextBuilder localizedTextBuilder;
PackageLocalInfoBuilder localInfoBuilder;
PackageClassificationInfoRef classificationInfo;
PackageUserRatingInfoRef userRatingInfo;
PackageScreenshotInfoBuilder screenshotInfoBuilder;
PackageInfoRef preexistingPackageInfo = data.PackageByName(packageName);
if (preexistingPackageInfo.IsSet()) {
coreInfoBuilder = PackageCoreInfoBuilder(preexistingPackageInfo->CoreInfo());
localizedTextBuilder = PackageLocalizedTextBuilder(preexistingPackageInfo->LocalizedText());
localInfoBuilder = PackageLocalInfoBuilder(preexistingPackageInfo->LocalInfo());
classificationInfo
= PackageClassificationInfoRef(preexistingPackageInfo->PackageClassificationInfo());
userRatingInfo = PackageUserRatingInfoRef(preexistingPackageInfo->UserRatingInfo());
screenshotInfoBuilder
= PackageScreenshotInfoBuilder(preexistingPackageInfo->ScreenshotInfo());
BString preexistingPackageDepotName = PackageUtils::DepotName(preexistingPackageInfo);
if (preexistingPackageDepotName.IsEmpty()
|| preexistingPackageDepotName == REPOSITORY_NAME_SYSTEM
|| preexistingPackageDepotName == REPOSITORY_NAME_INSTALLED) {
coreInfoBuilder.WithDepotName(repositoryName);
}
} else {
coreInfoBuilder
= PackageCoreInfoBuilder()
.WithDepotName(repositoryName)
.WithArchitecture(solverPackageInfo.ArchitectureName())
.WithVersion(new PackageVersion(solverPackageInfo.Version()))
.WithPublisher(PackageKitUtils::CreatePublisherInfo(solverPackageInfo));
localizedTextBuilder = PackageLocalizedTextBuilder()
.WithTitle(solverPackageInfo.Name())
.WithSummary(solverPackageInfo.Summary())
.WithDescription(solverPackageInfo.Description());
localInfoBuilder = PackageLocalInfoBuilder()
.WithFlags(solverPackageInfo.Flags())
.WithFileName(solverPackageInfo.FileName());
}
BSolverRepository* solverRepository = solverPackage->Repository();
BPackageManager::RemoteRepository* solverRemoteRepository
= dynamic_cast<BPackageManager::RemoteRepository*>(solverRepository);
uint32 solverPackageFlags = solverPackageInfo.Flags();
if (solverRemoteRepository != NULL) {
const BString solverRemoteRepositoryName = solverRemoteRepository->Config().Name();
DepotInfoRef depotInfoForSolverRemoteRepository
= data.DepotByName(solverRemoteRepositoryName);
if (depotInfoForSolverRemoteRepository.IsSet()) {
coreInfoBuilder.WithDepotName(solverRemoteRepositoryName);
HDTRACE("pkg [%s]; assigned to [%s]", packageName.String(), repositoryName.String());
} else {
HDDEBUG("pkg [%s]; repository [%s] not recognized --> ignored", packageName.String(),
repositoryName.String());
}
data.AddRemotePackageName(packageName);
} else {
if (LocalPkgDataLoadProcessUtils::_IsSystemRepository(manager, solverRepository)) {
localInfoBuilder.AddInstallationLocation(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
if ((solverPackageFlags & BPackageKit::B_PACKAGE_FLAG_SYSTEM_PACKAGE) == 0)
data.AddSystemInstalledPackage(solverPackageInfo);
} else if (LocalPkgDataLoadProcessUtils::_IsHomeRepository(manager, solverRepository)) {
localInfoBuilder.AddInstallationLocation(B_PACKAGE_INSTALLATION_LOCATION_HOME);
}
}
if ((solverPackageFlags & BPackageKit::B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0) {
HDTRACE("am adding system flagged package [%s]", solverPackageInfo.FileName().String());
data.AddSystemFlaggedPackageFilename(solverPackageInfo.FileName());
}
PackageLocalInfoRef localInfo = localInfoBuilder.BuildRef();
PackageLocalizedTextRef localizedText = localizedTextBuilder.BuildRef();
PackageCoreInfoRef coreInfo = coreInfoBuilder.BuildRef();
PackageScreenshotInfoRef screenshotInfo = screenshotInfoBuilder.BuildRef();
PackageInfoRef package = PackageInfoBuilder(packageName)
.WithLocalInfo(localInfo)
.WithLocalizedText(localizedText)
.WithCoreInfo(coreInfo)
.WithPackageClassificationInfo(classificationInfo)
.WithUserRatingInfo(userRatingInfo)
.WithScreenshotInfo(screenshotInfo)
.BuildRef();
data.AddPackage(package);
return result;
}
then be able to identify those that are "local" only. A fake Depot is
created for these so that they can be seen.
*/
status_t
LocalPkgDataLoadProcessUtils::_CollateLocalDepotAndPackageData(
LocalPkgDataLoadProcessUtilsData& data)
{
uint32 count = 0;
std::map<BString, PackageInfoRef>::const_iterator it;
for (it = data.fFoundPackages.begin(); it != data.fFoundPackages.end(); it++) {
BString packageName = it->first;
PackageInfoRef packageInfo = it->second;
if (!data.IsRemotePackageName(packageName)) {
BString repoName = B_TRANSLATE("Local");
if (count == 0) {
data.AddDepot(DepotInfoBuilder()
.WithName(repoName)
.WithIdentifier(LOCAL_DEPOT_IDENTIFIER)
.BuildRef());
}
PackageCoreInfoRef coreInfo = PackageCoreInfoBuilder(packageInfo->CoreInfo())
.WithDepotName(repoName)
.BuildRef();
PackageInfoRef replacementPackageInfo
= PackageInfoBuilder(packageInfo).WithCoreInfo(coreInfo).BuildRef();
data.AddPackage(replacementPackageInfo);
count++;
}
}
return B_OK;
}
to function and mark those on the in-memory models of the packages.
*/
status_t
LocalPkgDataLoadProcessUtils::_EnhanceSystemPackages(LocalPkgDataLoadProcessUtilsData& data)
{
try {
BSolver* solver;
status_t error = BSolver::Create(solver);
if (error != B_OK)
throw BFatalErrorException(error, "Failed to create solver.");
ObjectDeleter<BSolver> solverDeleter(solver);
BPath systemPath;
error = find_directory(B_SYSTEM_PACKAGES_DIRECTORY, &systemPath);
if (error != B_OK)
throw BFatalErrorException(error, "Unable to retrieve system packages directory.");
HDDEBUG("will assemble the system packages to enhance");
BSolverRepository installedRepository;
{
BRepositoryBuilder installedRepositoryBuilder(installedRepository,
REPOSITORY_NAME_INSTALLED);
std::set<BString>::iterator it;
for (it = data.fSystemFlaggedPackageFilenames.begin();
it != data.fSystemFlaggedPackageFilenames.end(); it++) {
BPath packagePath(systemPath);
packagePath.Append(*(it));
bool exists = false;
if (StorageUtils::ExistsObject(packagePath, &exists, NULL, NULL) != B_OK)
throw BFatalErrorException(error, "unable to check package file's existence.");
const char* packagePathStr = packagePath.Path();
if (exists) {
HDTRACE("adding system flagged package filename [%s]", packagePathStr);
installedRepositoryBuilder.AddPackage(packagePathStr);
} else {
HDINFO("system flagged package filename [%s] is not existing --> ignored",
packagePathStr);
}
}
installedRepositoryBuilder.AddToSolver(solver, true);
}
HDDEBUG("creating a system repository");
BSolverRepository systemRepository;
{
BRepositoryBuilder systemRepositoryBuilder(systemRepository, REPOSITORY_NAME_SYSTEM);
std::map<BString, BString>::iterator it;
for (it = data.fSystemInstalledFilenamesToPackageNames.begin();
it != data.fSystemInstalledFilenamesToPackageNames.end(); it++) {
BPath packagePath(systemPath);
packagePath.Append(it->first);
systemRepositoryBuilder.AddPackage(packagePath.Path());
}
systemRepositoryBuilder.AddToSolver(solver, false);
}
HDDEBUG("verifying system repository");
error = solver->VerifyInstallation();
if (error != B_OK)
throw BFatalErrorException(error, "Failed to compute packages to install.");
HDDEBUG("getting system repository result");
BSolverResult solverResult;
error = solver->GetResult(solverResult);
if (error != B_OK)
throw BFatalErrorException(error, "Failed to retrieve system package dependency list.");
HDDEBUG("processing system repository files");
for (int32 i = 0; const BSolverResultElement* element = solverResult.ElementAt(i); i++) {
BSolverPackage* package = element->Package();
if (element->Type() == BSolverResultElement::B_TYPE_INSTALL) {
BString packageFilename = package->Info().FileName();
HDTRACE("will process package filename [%s]", packageFilename.String());
PackageInfoRef systemInstalledPackage
= data.PackageBySystemInstalledFilename(packageFilename);
if (systemInstalledPackage.IsSet()) {
PackageLocalInfoRef localInfo
= PackageLocalInfoBuilder(systemInstalledPackage->LocalInfo())
.WithSystemDependency(true)
.BuildRef();
PackageInfoRef systemInstalledPackageUpdated
= PackageInfoBuilder(systemInstalledPackage)
.WithLocalInfo(localInfo)
.BuildRef();
data.AddPackage(systemInstalledPackageUpdated);
}
}
}
} catch (BFatalErrorException& ex) {
BString logMessage = _LogMessageFromFatalError(ex);
HDERROR(logMessage.String());
return B_ERROR;
} catch (BNothingToDoException&) {
} catch (BException& ex) {
HDERROR("Exception occurred while resolving system dependencies: %s",
ex.Message().String());
return B_ERROR;
} catch (...) {
HDERROR("Unknown exception occurred while resolving system dependencies.");
return B_ERROR;
}
return B_OK;
}
BString
LocalPkgDataLoadProcessUtils::_LogMessageFromFatalError(BFatalErrorException& ex)
{
BString logMessage;
logMessage.SetToFormat("a fatal exception has occurred resolving system dependencies: [%s]",
strerror(ex.Error()));
if (!ex.Details().IsEmpty()) {
logMessage.Append(", details: [");
logMessage.Append(ex.Details());
logMessage.Append("]");
}
if (ex.HasCommitTransactionFailed()) {
logMessage.Append("txn result: [");
logMessage.Append(ex.CommitTransactionResult().FullErrorMessage());
logMessage.Append("]");
}
return logMessage;
}
also load in the Depots as well.
*/
status_t
LocalPkgDataLoadProcessUtils::_PopulateModel(LocalPkgDataLoadProcessUtilsData& data, Model* model,
bool force)
{
std::vector<PackageInfoRef> packages;
std::map<BString, PackageInfoRef>::iterator packageIt;
for (packageIt = data.fFoundPackages.begin(); packageIt != data.fFoundPackages.end();
packageIt++) {
packages.push_back(packageIt->second);
}
if (force)
model->Clear();
std::map<BString, DepotInfoRef>::iterator depotIt;
std::vector<DepotInfoRef> depots;
for (depotIt = data.fDepots.begin(); depotIt != data.fDepots.end(); depotIt++) {
const DepotInfoRef depotInfo = depotIt->second;
if (!depotInfo->Identifier().IsEmpty())
depots.push_back(depotInfo);
}
model->SetDepots(depots);
uint32 changeMask = PKG_CHANGED_LOCAL_INFO | PKG_CHANGED_CORE_INFO | PKG_CHANGED_LOCALIZED_TEXT;
model->AddPackagesWithChange(packages, changeMask);
return B_OK;
}
void
LocalPkgDataLoadProcessUtils::_NotifyError(const BString& messageText)
{
HDERROR("an error has arisen loading data of packages from local : %s", messageText.String());
AppUtils::NotifySimpleError(B_TRANSLATE("Local repository load error"), messageText);
}
bool
LocalPkgDataLoadProcessUtils::_IsHomeRepository(PackageManager& manager,
BSolverRepository* solverRepository)
{
return solverRepository == static_cast<const BSolverRepository*>(manager.HomeRepository());
}
bool
LocalPkgDataLoadProcessUtils::_IsSystemRepository(PackageManager& manager,
BSolverRepository* solverRepository)
{
return solverRepository == static_cast<const BSolverRepository*>(manager.SystemRepository());
}
int32
LocalPkgDataLoadProcessUtilsData::CountPackages() const
{
return static_cast<int32>(fFoundPackages.size());
}
void
LocalPkgDataLoadProcessUtilsData::AddPackage(PackageInfoRef packageInfo)
{
if (!packageInfo.IsSet())
HDFATAL("attempt to work with unset package info");
const BString packageName = packageInfo->Name();
HDTRACE("did add package [%s]", packageName.String());
fFoundPackages[packageName] = packageInfo;
}
const PackageInfoRef
LocalPkgDataLoadProcessUtilsData::PackageByName(const BString& name) const
{
if (!name.IsEmpty()) {
std::map<BString, PackageInfoRef>::const_iterator it = fFoundPackages.find(name);
if (it != fFoundPackages.end())
return it->second;
}
return PackageInfoRef();
}
void
LocalPkgDataLoadProcessUtilsData::AddDepot(DepotInfoRef depotInfo)
{
if (!depotInfo.IsSet())
HDFATAL("attempt to work with unset depot info");
fDepots[depotInfo->Name()] = depotInfo;
}
int32
LocalPkgDataLoadProcessUtilsData::CountSolverPackages() const
{
return static_cast<int32>(fSolverPackages.size());
}
void
LocalPkgDataLoadProcessUtilsData::AddSolverPackage(const BSolverPackage* solverPackage)
{
fSolverPackages.push_back(solverPackage);
}
void
LocalPkgDataLoadProcessUtilsData::AddRemotePackageName(const BString& name)
{
fRemotePackageNames.insert(name);
}
bool
LocalPkgDataLoadProcessUtilsData::IsRemotePackageName(const BString& name) const
{
return fRemotePackageNames.find(name) != fRemotePackageNames.end();
}
void
LocalPkgDataLoadProcessUtilsData::AddSystemFlaggedPackageFilename(const BString& filename)
{
fSystemFlaggedPackageFilenames.insert(filename);
}
void
LocalPkgDataLoadProcessUtilsData::AddSystemInstalledPackage(const BPackageInfo& solverPackageInfo)
{
const BString packageName = solverPackageInfo.Name();
const BString packageFilename = solverPackageInfo.FileName();
fSystemInstalledFilenamesToPackageNames[packageFilename] = packageName;
}
const PackageInfoRef
LocalPkgDataLoadProcessUtilsData::PackageBySystemInstalledFilename(const BString& packageFilename)
{
BString packageName;
if (packageFilename.IsEmpty()) {
std::map<BString, BString>::const_iterator it;
BString packageName;
it = fSystemInstalledFilenamesToPackageNames.find(packageFilename);
if (it != fSystemInstalledFilenamesToPackageNames.end())
packageName = it->second;
}
return PackageByName(packageName);
}
const DepotInfoRef
LocalPkgDataLoadProcessUtilsData::DepotByName(const BString& name) const
{
if (!name.IsEmpty()) {
std::map<BString, DepotInfoRef>::const_iterator it = fDepots.find(name);
if (it != fDepots.end())
return it->second;
}
return DepotInfoRef();
}
int32
LocalPkgDataLoadProcessUtilsData::CountDepots() const
{
return static_cast<int32>(fDepots.size());
}