]> git.mxchange.org Git - simgear.git/blobdiff - simgear/package/Catalog.cxx
HTTP request cancellation
[simgear.git] / simgear / package / Catalog.cxx
index 87e2a3921369391c5dde2d082fe1c7b42bd3a2d3..c9c6565836ae0a4d970fb8c76671e8477fbef496 100644 (file)
@@ -31,6 +31,7 @@
 #include <simgear/package/Package.hxx>
 #include <simgear/package/Root.hxx>
 #include <simgear/package/Install.hxx>
+#include <simgear/misc/strutils.hxx>
 
 namespace simgear {
 
@@ -40,18 +41,32 @@ bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
 {
     BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
         std::string s(v->getStringValue());
-        if (s== aVersion) {
+        if (s == aVersion) {
             return true;
         }
 
-        // allow 3.5.* to match any of 3.5.0, 3.5.1rc1, 3.5.11 or so on
-        if (strutils::ends_with(s, ".*")) {
-            size_t lastDot = aVersion.rfind('.');
-            std::string ver = aVersion.substr(0, lastDot);
-            if (ver == s.substr(0, s.length() - 2)) {
-                return true;
+        // examine each dot-seperated component in turn, supporting a wildcard
+        // in the versions from the catalog.
+        string_list appVersionParts = simgear::strutils::split(aVersion, ".");
+        string_list catVersionParts = simgear::strutils::split(s, ".");
+
+        size_t partCount = appVersionParts.size();
+        if (partCount != catVersionParts.size()) {
+            continue;
+        }
+
+        bool ok = true;
+        for (unsigned int p=0; p < partCount; ++p) {
+            if (catVersionParts[p] == "*") {
+                // always passes
+            } else if (appVersionParts[p] != catVersionParts[p]) {
+                ok = false;
             }
         }
+
+        if (ok) {
+            return true;
+        }
     }
     return false;
 }
@@ -63,7 +78,7 @@ std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_pt
             return v->getStringValue("url");
         }
     }
-    
+
     return std::string();
 }
 
@@ -196,22 +211,13 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
         return NULL;
     }
 
-    if (!checkVersion(aRoot->applicationVersion(), props)) {
-        std::string redirect = redirectUrlForVersion(aRoot->applicationVersion(), props);
-        if (!redirect.empty()) {
-            SG_LOG(SG_GENERAL, SG_WARN, "catalog at " << aPath << ", version mismatch:\n\t"
-                   << "redirecting to alternate URL:" << redirect);
-            CatalogRef c = Catalog::createFromUrl(aRoot, redirect);
-            c->m_installRoot = aPath;
-            return c;
-        } else {
-            SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
-               << props->getStringValue("version") << " vs required " << aRoot->catalogVersion());
-            return NULL;
-        }
+    bool versionCheckOk = checkVersion(aRoot->applicationVersion(), props);
 
+    if (!versionCheckOk) {
+        SG_LOG(SG_GENERAL, SG_INFO, "catalog at:" << aPath << " failed version check: need" << aRoot->applicationVersion());
+        // keep the catalog but mark it as needing an update
     } else {
-        SG_LOG(SG_GENERAL, SG_INFO, "creating catalog from:" << aPath);
+        SG_LOG(SG_GENERAL, SG_DEBUG, "creating catalog from:" << aPath);
     }
 
     CatalogRef c = new Catalog(aRoot);
@@ -219,8 +225,12 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
     c->parseProps(props);
     c->parseTimestamp();
 
-    // parsed XML ok, mark status as valid
-    c->changeStatus(Delegate::STATUS_SUCCESS);
+    if (versionCheckOk) {
+        // parsed XML ok, mark status as valid
+        c->changeStatus(Delegate::STATUS_SUCCESS);
+    } else {
+        c->changeStatus(Delegate::FAIL_VERSION);
+    }
 
     return c;
 }
@@ -229,7 +239,7 @@ bool Catalog::uninstall()
 {
     bool ok;
     bool atLeastOneFailure = false;
-    
+
     BOOST_FOREACH(PackageRef p, installedPackages()) {
         ok = p->existingInstall()->uninstall();
         if (!ok) {
@@ -246,7 +256,7 @@ bool Catalog::uninstall()
     if (!ok) {
         atLeastOneFailure = true;
     }
-    
+
     changeStatus(atLeastOneFailure ? Delegate::FAIL_FILESYSTEM
                                    : Delegate::STATUS_SUCCESS);
     return ok;
@@ -314,15 +324,15 @@ void Catalog::refresh()
 struct FindById
 {
     FindById(const std::string &id) : m_id(id) {}
-    
+
     bool operator()(const PackageRef& ref) const
     {
         return ref->id() == m_id;
     }
-    
+
     std::string m_id;
 };
-    
+
 void Catalog::parseProps(const SGPropertyNode* aProps)
 {
     // copy everything except package children?
@@ -338,7 +348,7 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
         if (strcmp(pkgProps->getName(), "package") == 0) {
             // can't use getPackageById here becuase the variant dict isn't
             // built yet. Instead we need to look at m_packages directly.
-            
+
             PackageList::iterator pit = std::find_if(m_packages.begin(), m_packages.end(),
                                                   FindById(pkgProps->getStringValue("id")));
             PackageRef p;
@@ -428,6 +438,11 @@ std::string Catalog::url() const
     return m_url;
 }
 
+std::string Catalog::name() const
+{
+    return getLocalisedString(m_props, "name");
+}
+
 std::string Catalog::description() const
 {
     return getLocalisedString(m_props, "description");
@@ -464,6 +479,11 @@ unsigned int Catalog::ageInSeconds() const
 
 bool Catalog::needsRefresh() const
 {
+    // always refresh in these cases
+    if ((m_status == Delegate::FAIL_VERSION) || (m_status == Delegate::FAIL_DOWNLOAD)) {
+        return true;
+    }
+
     unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds());
     return (ageInSeconds() > maxAge);
 }
@@ -473,7 +493,7 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
     if (!aRoot) {
         return std::string();
     }
-    
+
     if (aRoot->hasChild(m_root->getLocale())) {
         const SGPropertyNode* localeRoot = aRoot->getChild(m_root->getLocale().c_str());
         if (localeRoot->hasChild(aName)) {
@@ -495,7 +515,7 @@ void Catalog::changeStatus(Delegate::StatusCode newStatus)
     if (m_status == newStatus) {
         return;
     }
-    
+
     m_status = newStatus;
     m_root->catalogRefreshStatus(this, newStatus);
     m_statusCallbacks(this);