[haiku-commits] BRANCH weinhold-github.pm-flat - src/kits/package/solver headers/os/package/solver

  • From: weinhold-github.pm-flat <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 1 Apr 2013 00:30:39 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/weinhold-github/pm-flat'
old head: 10efbe6c5e9350b8683d5b79ca6b9c75d61131a2
new head: 479ca8169c85621dda097bebe337bcc373eba68f
overview: https://github.com/weinhold/Haiku/compare/10efbe6...479ca81

----------------------------------------------------------------------------

479ca81: Beginnings of the PackageKit dependency solver
  
  Not functional (or tested) yet. The libsolv setup for a somewhat
  simplified installation case should be more or less complete, though.
  The solution conversion to to-be-created Haiku data structures and the
  handling of problems is still missing, though.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

Commit:      479ca8169c85621dda097bebe337bcc373eba68f
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Mon Apr  1 00:25:37 2013 UTC

----------------------------------------------------------------------------

10 files changed, 1025 insertions(+)
headers/os/package/solver/Solver.h               |  43 +++
.../os/package/solver/SolverPackageSpecifier.h   |  47 +++
.../package/solver/SolverPackageSpecifierList.h  |  46 +++
headers/os/package/solver/SolverRepository.h     |  69 ++++
src/kits/package/Jamfile                         |   2 +
src/kits/package/solver/Jamfile                  |  23 ++
src/kits/package/solver/Solver.cpp               | 356 +++++++++++++++++++
.../package/solver/SolverPackageSpecifier.cpp    |  79 ++++
.../solver/SolverPackageSpecifierList.cpp        | 125 +++++++
src/kits/package/solver/SolverRepository.cpp     | 235 ++++++++++++

----------------------------------------------------------------------------

diff --git a/headers/os/package/solver/Solver.h 
b/headers/os/package/solver/Solver.h
new file mode 100644
index 0000000..d52d739
--- /dev/null
+++ b/headers/os/package/solver/Solver.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _PACKAGE__SOLVER_H_
+#define _PACKAGE__SOLVER_H_
+
+
+#include <SupportDefs.h>
+
+
+namespace BPackageKit {
+
+
+class BSolverPackageSpecifierList;
+class BSolverRepository;
+
+
+class BSolver {
+public:
+                                                               BSolver();
+                                                               ~BSolver();
+
+                       status_t                        Init();
+
+                       status_t                        
AddRepository(BSolverRepository* repository);
+
+                       status_t                        Install(
+                                                                       const 
BSolverPackageSpecifierList&
+                                                                               
packages);
+
+private:
+                       class Implementation;
+
+private:
+                       Implementation*         fImplementation;
+};
+
+
+}      // namespace BPackageKit
+
+
+#endif // _PACKAGE__SOLVER_H_
diff --git a/headers/os/package/solver/SolverPackageSpecifier.h 
b/headers/os/package/solver/SolverPackageSpecifier.h
new file mode 100644
index 0000000..cfef584
--- /dev/null
+++ b/headers/os/package/solver/SolverPackageSpecifier.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
+#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
+
+
+#include <package/PackageResolvableExpression.h>
+
+
+namespace BPackageKit {
+
+
+class BSolverRepository;
+
+
+class BSolverPackageSpecifier {
+public:
+                                                               
BSolverPackageSpecifier();
+                                                               
BSolverPackageSpecifier(
+                                                                       const 
BPackageResolvableExpression&
+                                                                               
expression);
+                                                               
BSolverPackageSpecifier(
+                                                                       
BSolverRepository* repository,
+                                                                       const 
BPackageResolvableExpression&
+                                                                               
expression);
+                                                               
BSolverPackageSpecifier(
+                                                                       const 
BSolverPackageSpecifier& other);
+                                                               
~BSolverPackageSpecifier();
+
+                       BSolverRepository*      Repository() const;
+                       const BPackageResolvableExpression& Expression() const;
+
+                       BSolverPackageSpecifier& operator=(
+                                                                       const 
BSolverPackageSpecifier& other);
+
+private:
+                       BSolverRepository*      fRepository;
+                       BPackageResolvableExpression fExpression;
+};
+
+
+}      // namespace BPackageKit
+
+
+#endif // _PACKAGE__SOLVER_PACKAGE_SPECIFIER_H_
diff --git a/headers/os/package/solver/SolverPackageSpecifierList.h 
b/headers/os/package/solver/SolverPackageSpecifierList.h
new file mode 100644
index 0000000..0557dec
--- /dev/null
+++ b/headers/os/package/solver/SolverPackageSpecifierList.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
+#define _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
+
+
+#include <SupportDefs.h>
+
+
+namespace BPackageKit {
+
+
+class BSolverPackageSpecifier;
+
+
+class BSolverPackageSpecifierList {
+public:
+                                                               
BSolverPackageSpecifierList();
+                                                               
BSolverPackageSpecifierList(
+                                                                       const 
BSolverPackageSpecifierList& other);
+                                                               
~BSolverPackageSpecifierList();
+
+                       bool                            IsEmpty() const;
+                       int32                           CountSpecifiers() const;
+                       const BSolverPackageSpecifier* SpecifierAt(int32 index) 
const;
+
+                       bool                            AppendSpecifier(
+                                                                       const 
BSolverPackageSpecifier& specifier);
+
+                       BSolverPackageSpecifierList& operator=(
+                                                                       const 
BSolverPackageSpecifierList& other);
+
+private:
+                       class Vector;
+
+private:
+                       Vector*                         fSpecifiers;
+};
+
+
+}      // namespace BPackageKit
+
+
+#endif // _PACKAGE__SOLVER_PACKAGE_SPECIFIER_LIST_H_
diff --git a/headers/os/package/solver/SolverRepository.h 
b/headers/os/package/solver/SolverRepository.h
new file mode 100644
index 0000000..579512d
--- /dev/null
+++ b/headers/os/package/solver/SolverRepository.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _PACKAGE__SOLVER_REPOSITORY_H_
+#define _PACKAGE__SOLVER_REPOSITORY_H_
+
+
+#include <package/PackageDefs.h>
+#include <package/PackageInfoSet.h>
+#include <String.h>
+
+
+namespace BPackageKit {
+
+
+class BPackageInfo;
+class BRepositoryConfig;
+
+
+class BSolverRepository {
+public:
+                       enum BAllInstallationLocations {
+                               B_ALL_INSTALLATION_LOCATIONS
+                       };
+
+                       typedef BPackageInfoSet::Iterator Iterator;
+
+public:
+                                                               
BSolverRepository();
+                                                               
BSolverRepository(const BString& name);
+                                                               
BSolverRepository(
+                                                                       
BPackageInstallationLocation location);
+                                                               
BSolverRepository(BAllInstallationLocations);
+                                                               
BSolverRepository(
+                                                                       const 
BRepositoryConfig& config);
+                                                               
~BSolverRepository();
+
+                       status_t                        SetTo(const BString& 
name);
+                       status_t                        
SetTo(BPackageInstallationLocation location);
+                       status_t                        
SetTo(BAllInstallationLocations);
+                       status_t                        SetTo(const 
BRepositoryConfig& config);
+                       void                            Unset();
+
+                       status_t                        InitCheck();
+
+                       bool                            IsInstalled() const;
+
+                       BString                         Name() const;
+                       uint8                           Priority() const;
+
+                       status_t                        AddPackage(const 
BPackageInfo& info);
+                       status_t                        AddPackages(
+                                                                       
BPackageInstallationLocation location);
+
+                       Iterator                        GetIterator() const;
+
+private:
+                       BString                         fName;
+                       uint8                           fPriority;
+                       bool                            fIsInstalled;
+                       BPackageInfoSet         fPackages;
+};
+
+
+}      // namespace BPackageKit
+
+
+#endif // _PACKAGE__SOLVER_REPOSITORY_H_
diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile
index a73037b..207e6a1 100644
--- a/src/kits/package/Jamfile
+++ b/src/kits/package/Jamfile
@@ -74,3 +74,5 @@ SharedLibrary libpackage.so
        :
        libshared.a be z $(TARGET_LIBSTDC++)
 ;
+
+HaikuSubInclude solver ;
diff --git a/src/kits/package/solver/Jamfile b/src/kits/package/solver/Jamfile
new file mode 100644
index 0000000..06ea5a5
--- /dev/null
+++ b/src/kits/package/solver/Jamfile
@@ -0,0 +1,23 @@
+SubDir HAIKU_TOP src kits package solver ;
+
+UsePrivateHeaders shared ;
+
+# TODO: Add properly to BuildFeatures and remove here!
+HAIKU_LIBSOLV_INSTALL_DIR ?= /Transfer/ports/libsolv-install/boot/common ;
+HAIKU_LIBSOLV_HEADERS ?= $(HAIKU_LIBSOLV_INSTALL_DIR)/include ;
+HAIKU_LIBSOLV_LIBS ?= $(HAIKU_LIBSOLV_INSTALL_DIR)/lib/libsolv.so
+       $(HAIKU_LIBSOLV_INSTALL_DIR)/lib/libsolvext.so ;
+
+SubDirSysHdrs $(HAIKU_LIBSOLV_HEADERS) ;
+SubDirHdrs $(HAIKU_LIBSOLV_HEADERS)/solv ;
+
+
+SharedLibrary libpackage_solver.so
+       :
+       Solver.cpp
+       SolverPackageSpecifier.cpp
+       SolverPackageSpecifierList.cpp
+       SolverRepository.cpp
+       :
+       package $(HAIKU_LIBSOLV_LIBS) be $(TARGET_LIBSTDC++)
+;
diff --git a/src/kits/package/solver/Solver.cpp 
b/src/kits/package/solver/Solver.cpp
new file mode 100644
index 0000000..10ff02d
--- /dev/null
+++ b/src/kits/package/solver/Solver.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include <package/solver/Solver.h>
+
+#include <new>
+
+#include <solv/pool.h>
+#include <solv/poolarch.h>
+#include <solv/repo.h>
+#include <solv/repo_haiku.h>
+#include <solv/selection.h>
+#include <solv/solver.h>
+
+#include <package/RepositoryCache.h>
+#include <package/solver/SolverPackageSpecifier.h>
+#include <package/solver/SolverPackageSpecifierList.h>
+#include <package/solver/SolverRepository.h>
+
+#include <ObjectList.h>
+
+
+// TODO: libsolv doesn't have any helpful out-of-memory handling. It just just
+// abort()s. Obviously that isn't good behavior for a library.
+
+
+namespace BPackageKit {
+
+
+// #pragma mark - BSolver::Implementation
+
+
+class BSolver::Implementation {
+public:
+                                                               
Implementation();
+                                                               
~Implementation();
+
+                       status_t                        Init();
+
+                       status_t                        
AddRepository(BSolverRepository* repository);
+
+                       status_t                        Install(
+                                                                       const 
BSolverPackageSpecifierList&
+                                                                               
packages);
+
+private:
+                       struct SolvQueue;
+                       struct RepositoryInfo;
+
+                       typedef BObjectList<RepositoryInfo> RepositoryInfoList;
+
+private:
+                       status_t                        _AddRepositories();
+                       RepositoryInfo*         _GetRepositoryInfo(
+                                                                       
BSolverRepository* repository) const;
+
+private:
+                       Pool*                           fPool;
+                       RepositoryInfoList      fRepositoryInfos;
+                       RepositoryInfo*         fInstalledRepository;
+};
+
+
+struct BSolver::Implementation::SolvQueue : Queue {
+       SolvQueue()
+       {
+               queue_init(this);
+       }
+
+       ~SolvQueue()
+       {
+               queue_free(this);
+       }
+};
+
+
+struct BSolver::Implementation::RepositoryInfo {
+       RepositoryInfo(BSolverRepository* repository)
+               :
+               fRepository(repository),
+               fSolvRepo(NULL)
+       {
+       }
+
+       BSolverRepository* Repository() const
+       {
+               return fRepository;
+       }
+
+       Repo* SolvRepo()
+       {
+               return fSolvRepo;
+       }
+
+       void SetSolvRepo(Repo* repo)
+       {
+               fSolvRepo = repo;
+       }
+
+private:
+       BSolverRepository*      fRepository;
+       Repo*                           fSolvRepo;
+};
+
+
+// #pragma mark - BSolver
+
+
+BSolver::BSolver()
+       :
+       fImplementation(new(std::nothrow) Implementation)
+{
+}
+
+
+BSolver::~BSolver()
+{
+       delete fImplementation;
+}
+
+
+status_t
+BSolver::Init()
+{
+       return fImplementation != NULL ? fImplementation->Init() : B_NO_MEMORY;
+}
+
+
+status_t
+BSolver::AddRepository(BSolverRepository* repository)
+{
+       return fImplementation != NULL
+               ? fImplementation->AddRepository(repository) : B_NO_MEMORY;
+}
+
+
+status_t
+BSolver::Install(const BSolverPackageSpecifierList& packages)
+{
+       return fImplementation != NULL
+               ? fImplementation->Install(packages) : B_NO_MEMORY;
+}
+
+
+// #pragma mark - BSolver::Implementation
+
+
+BSolver::Implementation::Implementation()
+       :
+       fPool(NULL),
+       fRepositoryInfos(),
+       fInstalledRepository(NULL)
+{
+}
+
+
+BSolver::Implementation::~Implementation()
+{
+       if (fPool != NULL)
+               pool_free(fPool);
+}
+
+
+status_t
+BSolver::Implementation::Init()
+{
+       // already initialized?
+       if (fPool != NULL)
+               return B_BAD_VALUE;
+
+       fPool = pool_create();
+
+       // Set the system architecture. We use what uname() returns unless 
we're on
+       // x86 gcc2.
+       {
+               const char* arch;
+               #ifdef __HAIKU_ARCH_X86
+                       #if (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) == 
B_HAIKU_ABI_GCC_2
+                               arch = "x86_gcc2";
+                       #else
+                               arch = "x86";
+                       #endif
+               #else
+                       struct utsname info;
+                       if (uname(&info) != 0)
+                               return errno;
+                       arch = info.machine;
+               #endif
+
+               pool_setarchpolicy(fPool, arch);
+       }
+
+       return B_OK;
+}
+
+
+status_t
+BSolver::Implementation::AddRepository(BSolverRepository* repository)
+{
+       if (repository == NULL || repository->InitCheck() != B_OK)
+               return B_BAD_VALUE;
+
+       // If the repository represents installed packages, check, if we already
+       // have such a repository.
+       if (repository->IsInstalled() && fInstalledRepository != NULL)
+               return B_BAD_VALUE;
+
+       // add the repository info
+       RepositoryInfo* info = new(std::nothrow) RepositoryInfo(repository);
+       if (info == NULL)
+               return B_NO_MEMORY;
+
+       if (!fRepositoryInfos.AddItem(info)) {
+               delete info;
+               return B_NO_MEMORY;
+       }
+
+       if (repository->IsInstalled())
+               fInstalledRepository = info;
+
+       return B_OK;
+}
+
+
+status_t
+BSolver::Implementation::Install(const BSolverPackageSpecifierList& packages)
+{
+       if (packages.IsEmpty())
+               return B_BAD_VALUE;
+
+// TODO: Clean up first?
+
+       // add repositories to pool
+       status_t error = _AddRepositories();
+       if (error != B_OK)
+               return error;
+
+       // prepare pool for solving
+       pool_createwhatprovides(fPool);
+
+       // add the packages to install to the job queue
+       SolvQueue jobs;
+
+       int32 packageCount = packages.CountSpecifiers();
+       for (int32 i = 0; i < packageCount; i++) {
+               const BSolverPackageSpecifier& specifier = 
*packages.SpecifierAt(i);
+
+               // find matching packages
+               SolvQueue matchingPackages;
+
+               int flags = SELECTION_NAME | SELECTION_PROVIDES | SELECTION_GLOB
+                       | SELECTION_CANON | SELECTION_DOTARCH | SELECTION_REL;
+// TODO: All flags needed/useful?
+               /*int matchFlags =*/ selection_make(fPool, &matchingPackages,
+                       specifier.Expression().Name(), flags);
+// TODO: Don't just match the name, but also the version, if given!
+               if (matchingPackages.count == 0)
+                       return B_NAME_NOT_FOUND;
+
+               // restrict to the matching repository
+               if (BSolverRepository* repository = specifier.Repository()) {
+                       RepositoryInfo* repositoryInfo = 
_GetRepositoryInfo(repository);
+                       if (repositoryInfo == NULL)
+                               return B_BAD_VALUE;
+
+                       SolvQueue repoFilter;
+                       queue_push2(&repoFilter,
+                               SOLVER_SOLVABLE_REPO/* | SOLVER_SETREPO | 
SOLVER_SETVENDOR*/,
+                               repositoryInfo->SolvRepo()->repoid);
+
+                       selection_filter(fPool, &matchingPackages, &repoFilter);
+
+                       if (matchingPackages.count == 0)
+                               return B_NAME_NOT_FOUND;
+               }
+
+               for (int j = 0; j < matchingPackages.count; j++)
+                       queue_push(&jobs, matchingPackages.elements[j]);
+       }
+
+       // add solver mode to job queue elements
+       int solverMode = SOLVER_INSTALL;
+       for (int i = 0; i < jobs.count; i += 2) {
+               jobs.elements[i] |= solverMode;
+//             if (cleandeps)
+//                     jobs.elements[i] |= SOLVER_CLEANDEPS;
+//             if (forcebest)
+//                     jobs.elements[i] |= SOLVER_FORCEBEST;
+       }
+
+       // create the solver and solve
+       Solver* solver = solver_create(fPool);
+       solver_set_flag(solver, SOLVER_FLAG_SPLITPROVIDES, 1);
+       solver_set_flag(solver, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
+
+       int problemCount = solver_solve(solver, &jobs);
+       solver_free(solver);
+
+// TODO: Problem support!
+       return problemCount == 0 ? B_OK : B_BAD_VALUE;
+}
+
+
+status_t
+BSolver::Implementation::_AddRepositories()
+{
+       if (fInstalledRepository == NULL)
+               return B_BAD_VALUE;
+
+       int32 repositoryCount = fRepositoryInfos.CountItems();
+       for (int32 i = 0; i < repositoryCount; i++) {
+               RepositoryInfo* repositoryInfo = fRepositoryInfos.ItemAt(i);
+               BSolverRepository* repository = repositoryInfo->Repository();
+               Repo* repo = repo_create(fPool, repository->Name());
+               repositoryInfo->SetSolvRepo(repo);
+
+               repo->priority = 256 - repository->Priority();
+               repo->appdata = (void*)repositoryInfo;
+
+               BRepositoryCache::Iterator it = repository->GetIterator();
+               while (const BPackageInfo* packageInfo = it.Next()) {
+                       repo_add_haiku_package_info(repo, *packageInfo,
+                               REPO_REUSE_REPODATA | REPO_NO_INTERNALIZE);
+               }
+
+               repo_internalize(repo);
+
+               if (repository->IsInstalled())
+                       pool_set_installed(fPool, repo);
+       }
+
+       return B_OK;
+}
+
+
+BSolver::Implementation::RepositoryInfo*
+BSolver::Implementation::_GetRepositoryInfo(BSolverRepository* repository) 
const
+{
+       int32 repositoryCount = fRepositoryInfos.CountItems();
+       for (int32 i = 0; i < repositoryCount; i++) {
+               RepositoryInfo* repositoryInfo = fRepositoryInfos.ItemAt(i);
+               if (repository == repositoryInfo->Repository())
+                       return repositoryInfo;
+       }
+
+       return NULL;
+}
+
+
+}      // namespace BPackageKit
diff --git a/src/kits/package/solver/SolverPackageSpecifier.cpp 
b/src/kits/package/solver/SolverPackageSpecifier.cpp
new file mode 100644
index 0000000..c1469d4
--- /dev/null
+++ b/src/kits/package/solver/SolverPackageSpecifier.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include <package/solver/SolverPackageSpecifier.h>
+
+
+namespace BPackageKit {
+
+
+BSolverPackageSpecifier::BSolverPackageSpecifier()
+       :
+       fRepository(NULL),
+       fExpression()
+{
+}
+
+
+BSolverPackageSpecifier::BSolverPackageSpecifier(
+       const BPackageResolvableExpression& expression)
+       :
+       fRepository(NULL),
+       fExpression(expression)
+{
+}
+
+
+BSolverPackageSpecifier::BSolverPackageSpecifier(BSolverRepository* repository,
+       const BPackageResolvableExpression& expression)
+       :
+       fRepository(repository),
+       fExpression(expression)
+{
+}
+
+
+BSolverPackageSpecifier::BSolverPackageSpecifier(
+       const BSolverPackageSpecifier& other)
+       :
+       fRepository(other.fRepository),
+       fExpression(other.fExpression)
+{
+}
+
+
+BSolverPackageSpecifier::~BSolverPackageSpecifier()
+{
+}
+
+
+BSolverRepository*
+BSolverPackageSpecifier::Repository() const
+{
+       return fRepository;
+}
+
+
+const BPackageResolvableExpression&
+BSolverPackageSpecifier::Expression() const
+{
+       return fExpression;
+}
+
+
+BSolverPackageSpecifier&
+BSolverPackageSpecifier::operator=(const BSolverPackageSpecifier& other)
+{
+       fRepository = other.fRepository;
+       fExpression = other.fExpression;
+       return *this;
+}
+
+
+}      // namespace BPackageKit
diff --git a/src/kits/package/solver/SolverPackageSpecifierList.cpp 
b/src/kits/package/solver/SolverPackageSpecifierList.cpp
new file mode 100644
index 0000000..b15c776
--- /dev/null
+++ b/src/kits/package/solver/SolverPackageSpecifierList.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include <package/solver/SolverPackageSpecifierList.h>
+
+#include <new>
+#include <vector>
+
+#include <package/solver/SolverPackageSpecifier.h>
+
+
+namespace BPackageKit {
+
+class BSolverPackageSpecifierList::Vector
+       : public std::vector<BSolverPackageSpecifier> {
+public:
+       Vector()
+               :
+               std::vector<BSolverPackageSpecifier>()
+       {
+       }
+
+       Vector(const std::vector<BSolverPackageSpecifier>& other)
+               :
+               std::vector<BSolverPackageSpecifier>(other)
+       {
+       }
+};
+
+
+BSolverPackageSpecifierList::BSolverPackageSpecifierList()
+       :
+       fSpecifiers(NULL)
+{
+}
+
+       
+BSolverPackageSpecifierList::BSolverPackageSpecifierList(
+       const BSolverPackageSpecifierList& other)
+       :
+       fSpecifiers(NULL)
+{
+       *this = other;
+}
+
+
+BSolverPackageSpecifierList::~BSolverPackageSpecifierList()
+{
+       delete fSpecifiers;
+}
+
+
+bool
+BSolverPackageSpecifierList::IsEmpty() const
+{
+       return fSpecifiers == NULL || fSpecifiers->empty();
+}
+
+
+int32
+BSolverPackageSpecifierList::CountSpecifiers() const
+{
+       return fSpecifiers != NULL ? fSpecifiers->size() : 0;
+}
+
+
+const BSolverPackageSpecifier*
+BSolverPackageSpecifierList::SpecifierAt(int32 index) const
+{
+       if (fSpecifiers == NULL || index < 0
+               || (size_t)index >= fSpecifiers->size()) {
+               return NULL;
+       }
+
+       return &(*fSpecifiers)[index];
+}
+
+
+bool
+BSolverPackageSpecifierList::AppendSpecifier(
+       const BSolverPackageSpecifier& specifier)
+{
+       try {
+               if (fSpecifiers == NULL) {
+                       fSpecifiers = new(std::nothrow) Vector;
+                       if (fSpecifiers == NULL)
+                               return false;
+               }
+
+               fSpecifiers->push_back(specifier);
+               return true;
+       } catch (std::bad_alloc&) {
+               return false;
+       }
+}
+
+
+BSolverPackageSpecifierList&
+BSolverPackageSpecifierList::operator=(const BSolverPackageSpecifierList& 
other)
+{
+       if (this == &other)
+               return *this;
+
+       delete fSpecifiers;
+       fSpecifiers = NULL;
+
+       if (other.fSpecifiers == NULL)
+               return *this;
+
+       try {
+               fSpecifiers = new(std::nothrow) Vector(*other.fSpecifiers);
+       } catch (std::bad_alloc&) {
+       }
+
+       return *this;
+}
+
+
+}      // namespace BPackageKit
diff --git a/src/kits/package/solver/SolverRepository.cpp 
b/src/kits/package/solver/SolverRepository.cpp
new file mode 100644
index 0000000..93c2f78
--- /dev/null
+++ b/src/kits/package/solver/SolverRepository.cpp
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2013, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
+ */
+
+
+#include <package/solver/SolverRepository.h>
+
+#include <package/PackageDefs.h>
+#include <package/PackageRoster.h>
+#include <package/RepositoryCache.h>
+#include <package/RepositoryConfig.h>
+
+
+namespace BPackageKit {
+
+
+BSolverRepository::BSolverRepository()
+       :
+       fName(),
+       fPriority(0),
+       fIsInstalled(false),
+       fPackages()
+{
+}
+
+
+BSolverRepository::BSolverRepository(const BString& name)
+       :
+       fName(),
+       fPriority(0),
+       fIsInstalled(false),
+       fPackages()
+{
+       SetTo(name);
+}
+
+
+BSolverRepository::BSolverRepository(BPackageInstallationLocation location)
+       :
+       fName(),
+       fPriority(0),
+       fIsInstalled(false),
+       fPackages()
+{
+       SetTo(location);
+}
+
+
+BSolverRepository::BSolverRepository(BAllInstallationLocations)
+       :
+       fName(),
+       fPriority(0),
+       fIsInstalled(false),
+       fPackages()
+{
+       SetTo(B_ALL_INSTALLATION_LOCATIONS);
+}
+
+
+BSolverRepository::BSolverRepository(const BRepositoryConfig& config)
+       :
+       fName(),
+       fPriority(0),
+       fIsInstalled(false),
+       fPackages()
+{
+       SetTo(config);
+}
+
+
+BSolverRepository::~BSolverRepository()
+{
+}
+
+
+status_t
+BSolverRepository::SetTo(const BString& name)
+{
+       Unset();
+
+       fName = name;
+       return fName.IsEmpty() ? B_BAD_VALUE : B_OK;
+}
+
+
+status_t
+BSolverRepository::SetTo(BPackageInstallationLocation location)
+{
+       Unset();
+
+       fName = "Installed";
+
+       status_t error = AddPackages(location);
+       if (error != B_OK) {
+               Unset();
+               return error;
+       }
+
+       fIsInstalled = true;
+       return B_OK;
+}
+
+
+status_t
+BSolverRepository::SetTo(BAllInstallationLocations)
+{
+       status_t error = SetTo(B_PACKAGE_INSTALLATION_LOCATION_SYSTEM);
+       if (error != B_OK)
+               return error;
+
+       error = AddPackages(B_PACKAGE_INSTALLATION_LOCATION_COMMON);
+       if (error != B_OK) {
+               Unset();
+               return error;
+       }
+
+       error = AddPackages(B_PACKAGE_INSTALLATION_LOCATION_HOME);
+       if (error != B_OK) {
+               Unset();
+               return error;
+       }
+
+       return B_OK;
+}
+
+
+status_t
+BSolverRepository::SetTo(const BRepositoryConfig& config)
+{
+       Unset();
+
+       if (config.InitCheck() != B_OK)
+               return B_BAD_VALUE;
+
+       fName = config.Name();
+       fPriority = config.Priority();
+
+       BPackageRoster roster;
+       BRepositoryCache cache;
+       status_t error = roster.GetRepositoryCache(config.Name(), &cache);
+       if (error != B_OK) {
+               Unset();
+               return error;
+       }
+
+       BRepositoryCache::Iterator it = cache.GetIterator();
+       while (const BPackageInfo* packageInfo = it.Next()) {
+               error = AddPackage(*packageInfo);
+               if (error != B_OK) {
+                       Unset();
+                       return error;
+               }
+       }
+
+       return B_OK;
+}
+
+
+void
+BSolverRepository::Unset()
+{
+       fName = BString();
+       fPriority = 0;
+       fIsInstalled = false;
+       fPackages.MakeEmpty();
+}
+
+
+status_t
+BSolverRepository::InitCheck()
+{
+       return fName.IsEmpty() ? B_NO_INIT : B_OK;
+}
+
+
+bool
+BSolverRepository::IsInstalled() const
+{
+       return fIsInstalled;
+}
+
+
+BString
+BSolverRepository::Name() const
+{
+       return fName;
+}
+
+
+uint8
+BSolverRepository::Priority() const
+{
+       return fPriority;
+}
+
+
+status_t
+BSolverRepository::AddPackage(const BPackageInfo& info)
+{
+       return fPackages.AddInfo(info);
+}
+
+
+status_t
+BSolverRepository::AddPackages(BPackageInstallationLocation location)
+{
+       BPackageRoster roster;
+       BPackageInfoSet packageInfos;
+       status_t error = roster.GetActivePackages(location, packageInfos);
+       if (error != B_OK)
+               return error;
+
+       BRepositoryCache::Iterator it = packageInfos.GetIterator();
+       while (const BPackageInfo* packageInfo = it.Next()) {
+               error = fPackages.AddInfo(*packageInfo);
+               if (error != B_OK)
+                       return error;
+       }
+
+       return B_OK;
+}
+
+
+BSolverRepository::Iterator
+BSolverRepository::GetIterator() const
+{
+       return fPackages.GetIterator();
+}
+
+
+}      // namespace BPackageKit


Other related posts:

  • » [haiku-commits] BRANCH weinhold-github.pm-flat - src/kits/package/solver headers/os/package/solver - weinhold-github . pm-flat