From 26e7d134ce36b50fe2808fc65306cc68923bb388 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 3 Mar 2013 15:03:25 +0000 Subject: [PATCH] Package management tweaks. --- simgear/package/Catalog.cxx | 16 +++- simgear/package/Install.cxx | 2 +- simgear/package/Root.cxx | 158 +++++++++++++++++++++++------------- simgear/package/Root.hxx | 39 ++++----- 4 files changed, 131 insertions(+), 84 deletions(-) diff --git a/simgear/package/Catalog.cxx b/simgear/package/Catalog.cxx index 9a7a71f1..67b4eb19 100644 --- a/simgear/package/Catalog.cxx +++ b/simgear/package/Catalog.cxx @@ -80,7 +80,7 @@ protected: } std::string ver(m_owner->root()->catalogVersion()); - if (props->getStringValue("version") != ver) { + if (!checkVersion(ver, props)) { SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t" << props->getStringValue("version") << " vs required " << ver); m_owner->refreshComplete(Delegate::FAIL_VERSION); @@ -101,6 +101,16 @@ protected: } private: + bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps) + { + BOOST_FOREACH(SGPropertyNode* v, aProps->getChildren("version")) { + if (v->getStringValue() == aVersion) { + return true; + } + } + return false; + } + Catalog* m_owner; std::string m_buffer; }; @@ -129,7 +139,7 @@ Catalog* Catalog::createFromUrl(Root* aRoot, const std::string& aUrl) { Catalog* c = new Catalog(aRoot); Downloader* dl = new Downloader(c, aUrl); - aRoot->getHTTPClient()->makeRequest(dl); + aRoot->makeHTTPRequest(dl); return c; } @@ -195,7 +205,7 @@ Catalog::packagesNeedingUpdate() const void Catalog::refresh() { Downloader* dl = new Downloader(this, url()); - m_root->getHTTPClient()->makeRequest(dl); + m_root->makeHTTPRequest(dl); m_root->catalogRefreshBegin(this); } diff --git a/simgear/package/Install.cxx b/simgear/package/Install.cxx index a702b0ef..93b77999 100644 --- a/simgear/package/Install.cxx +++ b/simgear/package/Install.cxx @@ -306,7 +306,7 @@ void Install::startUpdate() } m_download = new PackageArchiveDownloader(this); - m_package->catalog()->root()->getHTTPClient()->makeRequest(m_download); + m_package->catalog()->root()->makeHTTPRequest(m_download); m_package->catalog()->root()->startInstall(this); } diff --git a/simgear/package/Root.cxx b/simgear/package/Root.cxx index c9171913..75eef3bb 100644 --- a/simgear/package/Root.cxx +++ b/simgear/package/Root.cxx @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include #include @@ -34,42 +37,81 @@ namespace simgear { namespace pkg { +typedef std::map CatalogDict; + +class Root::RootPrivate +{ +public: + RootPrivate() : + http(NULL), + maxAgeSeconds(60 * 60 * 24), + delegate(NULL) + { + + } + + SGPath path; + std::string locale; + HTTP::Client* http; + CatalogDict catalogs; + unsigned int maxAgeSeconds; + Delegate* delegate; + std::string version; + + std::set refreshing; + std::deque updateDeque; + std::deque httpPendingRequests; +}; + +SGPath Root::path() const +{ + return d->path; +} + void Root::setMaxAgeSeconds(int seconds) { - m_maxAgeSeconds = seconds; + d->maxAgeSeconds = seconds; } void Root::setHTTPClient(HTTP::Client* aHTTP) { - m_http = aHTTP; + d->http = aHTTP; + BOOST_FOREACH(HTTP::Request_ptr req, d->httpPendingRequests) { + d->http->makeRequest(req); + } + + d->httpPendingRequests.clear(); } -HTTP::Client* Root::getHTTPClient() const +void Root::makeHTTPRequest(HTTP::Request *req) { - return m_http; + if (d->http) { + d->http->makeRequest(req); + return; + } + + d->httpPendingRequests.push_back(req); } - + Root::Root(const SGPath& aPath, const std::string& aVersion) : - m_path(aPath), - m_http(NULL), - m_maxAgeSeconds(60 * 60 * 24), - m_delegate(NULL), - m_version(aVersion) + d(new RootPrivate) { + d->path = aPath; + d->version = aVersion; if (getenv("LOCALE")) { - m_locale = getenv("LOCALE"); + d->locale = getenv("LOCALE"); } - Dir d(aPath); - if (!d.exists()) { - d.create(0755); + Dir dir(aPath); + if (!dir.exists()) { + dir.create(0755); return; } - BOOST_FOREACH(SGPath c, d.children(Dir::TYPE_DIR)) { + BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR)) { Catalog* cat = Catalog::createFromPath(this, c); if (cat) { - m_catalogs[cat->id()] = cat; + d->catalogs[cat->id()] = cat; } } // of child directories iteration } @@ -81,13 +123,13 @@ Root::~Root() std::string Root::catalogVersion() const { - return m_version; + return d->version; } Catalog* Root::getCatalogById(const std::string& aId) const { - CatalogDict::const_iterator it = m_catalogs.find(aId); - if (it == m_catalogs.end()) { + CatalogDict::const_iterator it = d->catalogs.find(aId); + if (it == d->catalogs.end()) { return NULL; } @@ -101,8 +143,8 @@ Package* Root::getPackageById(const std::string& aName) const Package* pkg = NULL; if (lastDot == std::string::npos) { // naked package ID - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { pkg = it->second->getPackageById(aName); if (pkg) { return pkg; @@ -125,8 +167,8 @@ Package* Root::getPackageById(const std::string& aName) const CatalogList Root::catalogs() const { CatalogList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { r.push_back(it->second); } @@ -138,8 +180,8 @@ Root::packagesMatching(const SGPropertyNode* aFilter) const { PackageList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { PackageList r2(it->second->packagesMatching(aFilter)); r.insert(r.end(), r2.begin(), r2.end()); } @@ -152,8 +194,8 @@ Root::packagesNeedingUpdate() const { PackageList r; - CatalogDict::const_iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { + CatalogDict::const_iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { PackageList r2(it->second->packagesNeedingUpdate()); r.insert(r.end(), r2.begin(), r2.end()); } @@ -163,9 +205,9 @@ Root::packagesNeedingUpdate() const void Root::refresh(bool aForce) { - CatalogDict::iterator it = m_catalogs.begin(); - for (; it != m_catalogs.end(); ++it) { - if (aForce || (it->second->ageInSeconds() > m_maxAgeSeconds)) { + CatalogDict::iterator it = d->catalogs.begin(); + for (; it != d->catalogs.end(); ++it) { + if (aForce || (it->second->ageInSeconds() > d->maxAgeSeconds)) { it->second->refresh(); } } @@ -173,17 +215,17 @@ void Root::refresh(bool aForce) void Root::setDelegate(simgear::pkg::Delegate *aDelegate) { - m_delegate = aDelegate; + d->delegate = aDelegate; } void Root::setLocale(const std::string& aLocale) { - m_locale = aLocale; + d->locale = aLocale; } std::string Root::getLocale() const { - return m_locale; + return d->locale; } void Root::scheduleToUpdate(Install* aInstall) @@ -199,8 +241,8 @@ void Root::scheduleToUpdate(Install* aInstall) dep->install(); } - bool wasEmpty = m_updateDeque.empty(); - m_updateDeque.push_back(aInstall); + bool wasEmpty = d->updateDeque.empty(); + d->updateDeque.push_back(aInstall); if (wasEmpty) { aInstall->startUpdate(); @@ -209,35 +251,35 @@ void Root::scheduleToUpdate(Install* aInstall) void Root::startInstall(Install* aInstall) { - if (m_delegate) { - m_delegate->startInstall(aInstall); + if (d->delegate) { + d->delegate->startInstall(aInstall); } } void Root::installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal) { - if (m_delegate) { - m_delegate->installProgress(aInstall, aBytes, aTotal); + if (d->delegate) { + d->delegate->installProgress(aInstall, aBytes, aTotal); } } void Root::startNext(Install* aCurrent) { - if (m_updateDeque.front() != aCurrent) { + if (d->updateDeque.front() != aCurrent) { SG_LOG(SG_GENERAL, SG_ALERT, "current install of package not head of the deque"); } else { - m_updateDeque.pop_front(); + d->updateDeque.pop_front(); } - if (!m_updateDeque.empty()) { - m_updateDeque.front()->startUpdate(); + if (!d->updateDeque.empty()) { + d->updateDeque.front()->startUpdate(); } } void Root::finishInstall(Install* aInstall) { - if (m_delegate) { - m_delegate->finishInstall(aInstall); + if (d->delegate) { + d->delegate->finishInstall(aInstall); } startNext(aInstall); @@ -247,8 +289,8 @@ void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason) { SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" << aInstall->package()->id() << ":" << aReason); - if (m_delegate) { - m_delegate->failedInstall(aInstall, aReason); + if (d->delegate) { + d->delegate->failedInstall(aInstall, aReason); } startNext(aInstall); @@ -256,15 +298,15 @@ void Root::failedInstall(Install* aInstall, Delegate::FailureCode aReason) void Root::catalogRefreshBegin(Catalog* aCat) { - m_refreshing.insert(aCat); + d->refreshing.insert(aCat); } void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason) { - CatalogDict::iterator catIt = m_catalogs.find(aCat->id()); + CatalogDict::iterator catIt = d->catalogs.find(aCat->id()); if (aReason != Delegate::FAIL_SUCCESS) { - if (m_delegate) { - m_delegate->failedRefresh(aCat, aReason); + if (d->delegate) { + d->delegate->failedRefresh(aCat, aReason); } // if the failure is permanent, delete the catalog from our @@ -272,17 +314,17 @@ void Root::catalogRefreshComplete(Catalog* aCat, Delegate::FailureCode aReason) bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION); if (isPermanentFailure) { SG_LOG(SG_GENERAL, SG_WARN, "permanent failure for catalog:" << aCat->id()); - m_catalogs.erase(catIt); + d->catalogs.erase(catIt); } - } else if (catIt == m_catalogs.end()) { + } else if (catIt == d->catalogs.end()) { // first fresh, add to our storage now - m_catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat)); + d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat)); } - m_refreshing.erase(aCat); - if (m_refreshing.empty()) { - if (m_delegate) { - m_delegate->refreshComplete(); + d->refreshing.erase(aCat); + if (d->refreshing.empty()) { + if (d->delegate) { + d->delegate->refreshComplete(); } } } diff --git a/simgear/package/Root.hxx b/simgear/package/Root.hxx index ef232187..cc38df77 100644 --- a/simgear/package/Root.hxx +++ b/simgear/package/Root.hxx @@ -19,9 +19,7 @@ #define SG_PACKAGE_ROOT_HXX #include -#include -#include -#include +#include // for auto_ptr #include #include @@ -31,7 +29,10 @@ class SGPropertyNode; namespace simgear { -namespace HTTP { class Client; } +namespace HTTP { + class Client; + class Request; +} namespace pkg { @@ -44,16 +45,13 @@ class Install; typedef std::vector PackageList; typedef std::vector CatalogList; -typedef std::map CatalogDict; - class Root { public: Root(const SGPath& aPath, const std::string& aVersion); virtual ~Root(); - SGPath path() const - { return m_path; } + SGPath path() const; void setLocale(const std::string& aLocale); @@ -67,8 +65,13 @@ public: void setHTTPClient(HTTP::Client* aHTTP); - HTTP::Client* getHTTPClient() const; - + /** + * Submit an HTTP request. The Root may delay or queue requests if it needs + * too, for example during startup when the HTTP engine may not have been + * set yet. + */ + void makeHTTPRequest(HTTP::Request* req); + /** * the version string of the root. Catalogs must match this version, * or they will be ignored / rejected. @@ -112,18 +115,10 @@ private: void installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal); void finishInstall(Install* aInstall); void failedInstall(Install* aInstall, Delegate::FailureCode aReason); - - SGPath m_path; - std::string m_locale; - HTTP::Client* m_http; - CatalogDict m_catalogs; - unsigned int m_maxAgeSeconds; - Delegate* m_delegate; - std::string m_version; - - std::set m_refreshing; - std::deque m_updateDeque; -}; + + class RootPrivate; + std::auto_ptr d; +}; } // of namespace pkg -- 2.39.5