]> git.mxchange.org Git - simgear.git/blobdiff - simgear/io/SVNRepository.cxx
Expose total bytes to download / remaining
[simgear.git] / simgear / io / SVNRepository.cxx
index 822f639100501ff5f2d042eed9788ae8f9bb996c..033fa9efcc189ffae808c9895bfee06e226bc5b0 100644 (file)
@@ -26,6 +26,7 @@
 #include <map>
 #include <set>
 #include <fstream>
+#include <memory>
 
 #include <boost/foreach.hpp>
 
@@ -51,12 +52,12 @@ typedef std::vector<HTTP::Request_ptr> RequestVector;
 class SVNRepoPrivate
 {
 public:
-    SVNRepoPrivate(SVNRepository* parent) : 
-        p(parent), 
+    SVNRepoPrivate(SVNRepository* parent) :
+        p(parent),
         isUpdating(false),
-        status(SVNRepository::SVN_NO_ERROR)
+        status(SVNRepository::REPO_NO_ERROR)
     { ; }
-    
+
     SVNRepository* p; // link back to outer
     SVNDirectory* rootCollection;
     HTTP::Client* http;
@@ -65,42 +66,42 @@ public:
     std::string targetRevision;
     bool isUpdating;
     SVNRepository::ResultCode status;
-    
+
     void svnUpdateDone()
     {
         isUpdating = false;
     }
-    
+
     void updateFailed(HTTP::Request* req, SVNRepository::ResultCode err)
     {
-        SG_LOG(SG_IO, SG_WARN, "SVN: failed to update from:" << req->url()
+        SG_LOG(SG_TERRASYNC, SG_WARN, "SVN: failed to update from:" << req->url()
             << "\n(repository:" << p->baseUrl() << ")");
         isUpdating = false;
         status = err;
     }
-      
+
     void propFindComplete(HTTP::Request* req, DAVCollection* col);
     void propFindFailed(HTTP::Request* req, SVNRepository::ResultCode err);
 };
 
 
 namespace { // anonmouse
-    
+
     string makeAbsoluteUrl(const string& url, const string& base)
     {
       if (strutils::starts_with(url, "http://"))
         return url; // already absolute
-  
+
       assert(strutils::starts_with(base, "http://"));
       int schemeEnd = base.find("://");
       int hostEnd = base.find('/', schemeEnd + 3);
       if (hostEnd < 0) {
         return url;
       }
-  
+
       return base.substr(0, hostEnd) + url;
     }
-    
+
     // keep the responses small by only requesting the properties we actually
     // care about; the ETag, length and MD5-sum
     const char* PROPFIND_REQUEST_BODY =
@@ -120,6 +121,7 @@ namespace { // anonmouse
         Request(repo->baseUrl, "PROPFIND"),
         _repo(repo)
       {
+        assert(repo);
         requestHeader("Depth") = "0";
         setBodyData( PROPFIND_REQUEST_BODY,
                      "application/xml; charset=\"utf-8\"" );
@@ -131,15 +133,17 @@ namespace { // anonmouse
         if (responseCode() == 207) {
             // fine
         } else if (responseCode() == 404) {
-            _repo->propFindFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
+            _repo->propFindFailed(this, SVNRepository::REPO_ERROR_NOT_FOUND);
         } else {
-            SG_LOG(SG_IO, SG_WARN, "request for:" << url() << 
+            SG_LOG(SG_TERRASYNC, SG_WARN, "request for:" << url() <<
                 " return code " << responseCode());
-            _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+            _repo->propFindFailed(this, SVNRepository::REPO_ERROR_SOCKET);
             _repo = NULL;
         }
+
+        Request::responseHeadersComplete();
       }
-  
+
       virtual void onDone()
       {
         if (responseCode() == 207) {
@@ -147,11 +151,11 @@ namespace { // anonmouse
           if (_davStatus.isValid()) {
               _repo->propFindComplete(this, (DAVCollection*) _davStatus.resource());
           } else {
-              _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+              _repo->propFindFailed(this, SVNRepository::REPO_ERROR_SOCKET);
           }
         }
       }
-  
+
       virtual void gotBodyData(const char* s, int n)
       {
         if (responseCode() != 207) {
@@ -159,16 +163,16 @@ namespace { // anonmouse
         }
         _davStatus.parseXML(s, n);
       }
-        
+
         virtual void onFail()
         {
             HTTP::Request::onFail();
                        if (_repo) {
-                               _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+                               _repo->propFindFailed(this, SVNRepository::REPO_ERROR_SOCKET);
                                _repo = NULL;
                        }
         }
-        
+
     private:
       SVNRepoPrivate* _repo;
       DAVMultiStatus _davStatus;
@@ -178,14 +182,14 @@ class UpdateReportRequest:
   public HTTP::Request
 {
 public:
-  UpdateReportRequest(SVNRepoPrivate* repo, 
+  UpdateReportRequest(SVNRepoPrivate* repo,
       const std::string& aVersionName,
       bool startEmpty) :
     HTTP::Request("", "REPORT"),
     _parser(repo->p),
     _repo(repo),
     _failed(false)
-  {       
+  {
     setUrl(repo->vccUrl);
     std::string request =
     "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
@@ -215,7 +219,7 @@ protected:
       if (_failed) {
           return;
       }
-      
+
     if (responseCode() == 200) {
           SVNRepository::ResultCode err = _parser.finishParse();
           if (err) {
@@ -225,30 +229,30 @@ protected:
               _repo->svnUpdateDone();
           }
     } else if (responseCode() == 404) {
-        _repo->updateFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
+        _repo->updateFailed(this, SVNRepository::REPO_ERROR_NOT_FOUND);
         _failed = true;
     } else {
-        SG_LOG(SG_IO, SG_WARN, "SVN: request for:" << url() <<
-        " return code " << responseCode());
-        _repo->updateFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+        SG_LOG(SG_TERRASYNC, SG_WARN, "SVN: request for:" << url() <<
+        " got HTTP status " << responseCode());
+        _repo->updateFailed(this, SVNRepository::REPO_ERROR_HTTP);
         _failed = true;
     }
   }
 
   virtual void gotBodyData(const char* s, int n)
-  {    
+  {
       if (_failed) {
           return;
       }
-      
+
     if (responseCode() != 200) {
         return;
     }
-    
+
     SVNRepository::ResultCode err = _parser.parseXML(s, n);
     if (err) {
         _failed = true;
-        SG_LOG(SG_IO, SG_WARN, _repo->p << ": SVN: request for:" << url() << " failed:" << err);
+        SG_LOG(SG_IO, SG_WARN, this << ": SVN: request for:" << url() << " failed:" << err);
         _repo->updateFailed(this, err);
         _repo = NULL;
     }
@@ -258,7 +262,7 @@ protected:
     {
         HTTP::Request::onFail();
         if (_repo) {
-            _repo->updateFailed(this, SVNRepository::SVN_ERROR_SOCKET);
+            _repo->updateFailed(this, SVNRepository::REPO_ERROR_SOCKET);
             _repo = NULL;
         }
     }
@@ -267,15 +271,15 @@ private:
   SVNRepoPrivate* _repo;
   bool _failed;
 };
-        
-} // anonymous 
+
+} // anonymous
 
 SVNRepository::SVNRepository(const SGPath& base, HTTP::Client *cl) :
-  _d(new SVNRepoPrivate(this))
+    _d(new SVNRepoPrivate(this))
 {
   _d->http = cl;
   _d->rootCollection = new SVNDirectory(this, base);
-  _d->baseUrl = _d->rootCollection->url();  
+  _d->baseUrl = _d->rootCollection->url();
 }
 
 SVNRepository::~SVNRepository()
@@ -309,42 +313,42 @@ bool SVNRepository::isBare() const
     if (!fsBase().exists() || Dir(fsBase()).isEmpty()) {
         return true;
     }
-    
+
     if (_d->vccUrl.empty()) {
         return true;
     }
-    
+
     return false;
 }
 
 void SVNRepository::update()
-{  
-    _d->status = SVN_NO_ERROR;
-    if (_d->targetRevision.empty() || _d->vccUrl.empty()) {        
-        _d->isUpdating = true;        
+{
+    _d->status = REPO_NO_ERROR;
+    if (_d->targetRevision.empty() || _d->vccUrl.empty()) {
+        _d->isUpdating = true;
         PropFindRequest* pfr = new PropFindRequest(_d.get());
         http()->makeRequest(pfr);
         return;
     }
-        
+
     if (_d->targetRevision == rootDir()->cachedRevision()) {
-        SG_LOG(SG_IO, SG_DEBUG, baseUrl() << " in sync at version " << _d->targetRevision);
+        SG_LOG(SG_TERRASYNC, SG_DEBUG, baseUrl() << " in sync at version " << _d->targetRevision);
         _d->isUpdating = false;
         return;
     }
-    
+
     _d->isUpdating = true;
-    UpdateReportRequest* urr = new UpdateReportRequest(_d.get(), 
+    UpdateReportRequest* urr = new UpdateReportRequest(_d.get(),
         _d->targetRevision, isBare());
     http()->makeRequest(urr);
 }
-  
+
 bool SVNRepository::isDoingSync() const
 {
-    if (_d->status != SVN_NO_ERROR) {
+    if (_d->status != REPO_NO_ERROR) {
         return false;
     }
-    
+
     return _d->isUpdating || _d->rootCollection->isDoingSync();
 }
 
@@ -365,16 +369,16 @@ void SVNRepoPrivate::propFindComplete(HTTP::Request* req, DAVCollection* c)
 {
     targetRevision = c->versionName();
     vccUrl = makeAbsoluteUrl(c->versionControlledConfiguration(), baseUrl);
-    rootCollection->collection()->setVersionControlledConfiguration(vccUrl);    
+    rootCollection->collection()->setVersionControlledConfiguration(vccUrl);
     p->update();
 }
-  
+
 void SVNRepoPrivate::propFindFailed(HTTP::Request *req, SVNRepository::ResultCode err)
 {
-    if (err != SVNRepository::SVN_ERROR_NOT_FOUND) {
-        SG_LOG(SG_IO, SG_WARN, "PropFind failed for:" << req->url());
+    if (err != SVNRepository::REPO_ERROR_NOT_FOUND) {
+        SG_LOG(SG_TERRASYNC, SG_WARN, "PropFind failed for:" << req->url());
     }
-    
+
     isUpdating = false;
     status = err;
 }