namespace pkg {
-bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
+bool checkVersionString(const std::string& aVersion, const std::string& aCandidate)
{
- BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
- std::string s(v->getStringValue());
- if (s == aVersion) {
- return true;
- }
+ if (aCandidate == aVersion) {
+ 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, ".");
+ // 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(aCandidate, ".");
- size_t partCount = appVersionParts.size();
- if (partCount != catVersionParts.size()) {
- continue;
+ size_t partCount = appVersionParts.size();
+ bool previousCandidatePartWasWildcard = false;
+
+ for (unsigned int p=0; p < partCount; ++p) {
+ // candidate string is too short, can match if it ended with wildcard
+ // part. This allows candidate '2016.*' to match '2016.1.2' and so on
+ if (catVersionParts.size() <= p) {
+ return previousCandidatePartWasWildcard;
}
- 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 (catVersionParts[p] == "*") {
+ // always passes
+ previousCandidatePartWasWildcard = true;
+ } else if (appVersionParts[p] != catVersionParts[p]) {
+ return false;
}
+ }
- if (ok) {
+ return true;
+}
+
+bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
+{
+ BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
+ std::string s(v->getStringValue());
+ if (checkVersionString(aVersion, s)) {
return true;
}
}
std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_ptr props)
{
BOOST_FOREACH(SGPropertyNode* v, props->getChildren("alternate-version")) {
- if (v->getStringValue("version") == aVersion) {
- return v->getStringValue("url");
+ std::string s(v->getStringValue("version"));
+ if (checkVersionString(aVersion, s)) {
+ return v->getStringValue("url");;
}
}
return;
}
- SGPropertyNode* props = new SGPropertyNode;
+ SGPropertyNode_ptr props = new SGPropertyNode;
try {
readProperties(m_buffer.data(), m_buffer.size(), props);
return;
}
- if (m_owner->root()->catalogVersion() != props->getIntValue("catalog-version")) {
- SG_LOG(SG_GENERAL, SG_WARN, "catalog:" << m_owner->url() << " is not version "
- << m_owner->root()->catalogVersion());
- m_owner->refreshComplete(Delegate::FAIL_VERSION);
- return;
- }
-
-
std::string ver(m_owner->root()->applicationVersion());
if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version required " << ver);
" to \n\t" << url);
// update the URL and kick off a new request
- m_owner->m_url = url;
+ m_owner->setUrl(url);
Downloader* dl = new Downloader(m_owner, url);
m_owner->root()->makeHTTPRequest(dl);
} else {
}
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
return m_url;
}
+void Catalog::setUrl(const std::string &url)
+{
+ m_url = url;
+ if (m_status == Delegate::FAIL_NOT_FOUND) {
+ m_status = Delegate::FAIL_UNKNOWN;
+ }
+}
+
std::string Catalog::name() const
{
return getLocalisedString(m_props, "name");
void Catalog::refreshComplete(Delegate::StatusCode aReason)
{
- changeStatus(aReason);
m_refreshRequest.reset();
+ changeStatus(aReason);
}
void Catalog::changeStatus(Delegate::StatusCode newStatus)