From 7075a8707b1e3a8a9fbd5c1640f4b12c0bc5ad2b Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 25 Jan 2016 18:15:48 -0600 Subject: [PATCH] Create TerraSync repo API - create an abstract API for a remote repository, based on the current SVN repository API, and update the code accordingly. --- simgear/io/AbstractRepository.cxx | 29 +++++++++++++ simgear/io/AbstractRepository.hxx | 69 +++++++++++++++++++++++++++++++ simgear/io/CMakeLists.txt | 2 + simgear/io/SVNReportParser.cxx | 18 ++++---- simgear/io/SVNRepository.cxx | 24 +++++------ simgear/io/SVNRepository.hxx | 56 ++++++++----------------- simgear/scene/tsync/terrasync.cxx | 6 +-- 7 files changed, 142 insertions(+), 62 deletions(-) create mode 100644 simgear/io/AbstractRepository.cxx create mode 100644 simgear/io/AbstractRepository.hxx diff --git a/simgear/io/AbstractRepository.cxx b/simgear/io/AbstractRepository.cxx new file mode 100644 index 00000000..0a935f34 --- /dev/null +++ b/simgear/io/AbstractRepository.cxx @@ -0,0 +1,29 @@ +// AbstractRepository.cxx -- abstract API for TerraSync remote +// +// Copyright (C) 2016 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +#include "AbstractRepository.hxx" + +namespace simgear +{ + +AbstractRepository::~AbstractRepository() +{ + +} + +} // of namespace simgear diff --git a/simgear/io/AbstractRepository.hxx b/simgear/io/AbstractRepository.hxx new file mode 100644 index 00000000..33dc3725 --- /dev/null +++ b/simgear/io/AbstractRepository.hxx @@ -0,0 +1,69 @@ +// AbstractRepository.hxx - API for terrasyc to access remote server +// +// Copyright (C) 2016 James Turner +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +#ifndef SG_IO_ABSTRACT_REPOSITORY_HXX +#define SG_IO_ABSTRACT_REPOSITORY_HXX + +#include + +#include + +namespace simgear { + + namespace HTTP { + class Client; + } + +class AbstractRepository +{ +public: + + virtual ~AbstractRepository(); + + virtual SGPath fsBase() const = 0; + + virtual void setBaseUrl(const std::string& url) =0; + virtual std::string baseUrl() const = 0;; + + virtual HTTP::Client* http() const = 0; + + virtual void update() = 0; + + virtual bool isDoingSync() const = 0; + + enum ResultCode { + REPO_NO_ERROR = 0, + REPO_ERROR_NOT_FOUND, + REPO_ERROR_SOCKET, + SVN_ERROR_XML, + SVN_ERROR_TXDELTA, + REPO_ERROR_IO, + REPO_ERROR_CHECKSUM, + REPO_ERROR_FILE_NOT_FOUND, + REPO_ERROR_HTTP + }; + + virtual ResultCode failure() const = 0; + protected: + +}; + +} // of namespace simgear + +#endif // of SG_IO_ABSTRACT_REPOSITORY_HXX diff --git a/simgear/io/CMakeLists.txt b/simgear/io/CMakeLists.txt index 25e79180..61d80ea0 100644 --- a/simgear/io/CMakeLists.txt +++ b/simgear/io/CMakeLists.txt @@ -18,6 +18,7 @@ set(HEADERS HTTPFileRequest.hxx HTTPMemoryRequest.hxx HTTPRequest.hxx + AbstractRepository.hxx DAVMultiStatus.hxx SVNRepository.hxx SVNDirectory.hxx @@ -40,6 +41,7 @@ set(SOURCES HTTPFileRequest.cxx HTTPMemoryRequest.cxx HTTPRequest.cxx + AbstractRepository.cxx DAVMultiStatus.cxx SVNRepository.cxx SVNDirectory.cxx diff --git a/simgear/io/SVNReportParser.cxx b/simgear/io/SVNReportParser.cxx index 72b61693..5ee3d63f 100644 --- a/simgear/io/SVNReportParser.cxx +++ b/simgear/io/SVNReportParser.cxx @@ -244,7 +244,7 @@ class SVNReportParser::SVNReportParserPrivate public: SVNReportParserPrivate(SVNRepository* repo) : tree(repo), - status(SVNRepository::SVN_NO_ERROR), + status(AbstractRepository::REPO_NO_ERROR), parserInited(false), currentPath(repo->fsBase()) { @@ -258,7 +258,7 @@ public: void startElement (const char * name, const char** attributes) { - if (status != SVNRepository::SVN_NO_ERROR) { + if (status != AbstractRepository::REPO_NO_ERROR) { return; } @@ -277,7 +277,7 @@ public: currentPath = filePath; if (!filePath.exists()) { - fail(SVNRepository::SVN_ERROR_FILE_NOT_FOUND); + fail(AbstractRepository::REPO_ERROR_FILE_NOT_FOUND); return; } @@ -386,7 +386,7 @@ public: void endElement (const char * name) { - if (status != SVNRepository::SVN_NO_ERROR) { + if (status != SVNRepository::REPO_NO_ERROR) { return; } @@ -420,7 +420,7 @@ public: } else if (!strcmp(name, SVN_DAV_MD5_CHECKSUM)) { // validate against (presumably) just written file if (decodedFileMd5 != md5Sum) { - fail(SVNRepository::SVN_ERROR_CHECKSUM); + fail(SVNRepository::REPO_ERROR_CHECKSUM); } } else if (!strcmp(name, SVN_OPEN_DIRECTORY_TAG)) { currentDir->updateReportComplete(); @@ -443,7 +443,7 @@ public: void data (const char * s, int length) { - if (status != SVNRepository::SVN_NO_ERROR) { + if (status != SVNRepository::REPO_NO_ERROR) { return; } @@ -544,7 +544,7 @@ SVNReportParser::~SVNReportParser() SVNRepository::ResultCode SVNReportParser::innerParseXML(const char* data, int size) { - if (_d->status != SVNRepository::SVN_NO_ERROR) { + if (_d->status != SVNRepository::REPO_NO_ERROR) { return _d->status; } @@ -568,7 +568,7 @@ SVNReportParser::innerParseXML(const char* data, int size) SVNRepository::ResultCode SVNReportParser::parseXML(const char* data, int size) { - if (_d->status != SVNRepository::SVN_NO_ERROR) { + if (_d->status != SVNRepository::REPO_NO_ERROR) { return _d->status; } @@ -586,7 +586,7 @@ SVNReportParser::parseXML(const char* data, int size) SVNRepository::ResultCode SVNReportParser::finishParse() { - if (_d->status != SVNRepository::SVN_NO_ERROR) { + if (_d->status != SVNRepository::REPO_NO_ERROR) { return _d->status; } diff --git a/simgear/io/SVNRepository.cxx b/simgear/io/SVNRepository.cxx index 88a70c7a..ea44c020 100644 --- a/simgear/io/SVNRepository.cxx +++ b/simgear/io/SVNRepository.cxx @@ -54,7 +54,7 @@ public: SVNRepoPrivate(SVNRepository* parent) : p(parent), isUpdating(false), - status(SVNRepository::SVN_NO_ERROR) + status(SVNRepository::REPO_NO_ERROR) { ; } SVNRepository* p; // link back to outer @@ -132,11 +132,11 @@ 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_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; } @@ -150,7 +150,7 @@ 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); } } } @@ -167,7 +167,7 @@ namespace { // anonmouse { HTTP::Request::onFail(); if (_repo) { - _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET); + _repo->propFindFailed(this, SVNRepository::REPO_ERROR_SOCKET); _repo = NULL; } } @@ -228,12 +228,12 @@ 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_TERRASYNC, SG_WARN, "SVN: request for:" << url() << " got HTTP status " << responseCode()); - _repo->updateFailed(this, SVNRepository::SVN_ERROR_HTTP); + _repo->updateFailed(this, SVNRepository::REPO_ERROR_HTTP); _failed = true; } } @@ -261,7 +261,7 @@ protected: { HTTP::Request::onFail(); if (_repo) { - _repo->updateFailed(this, SVNRepository::SVN_ERROR_SOCKET); + _repo->updateFailed(this, SVNRepository::REPO_ERROR_SOCKET); _repo = NULL; } } @@ -274,7 +274,7 @@ private: } // 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); @@ -322,7 +322,7 @@ bool SVNRepository::isBare() const void SVNRepository::update() { - _d->status = SVN_NO_ERROR; + _d->status = REPO_NO_ERROR; if (_d->targetRevision.empty() || _d->vccUrl.empty()) { _d->isUpdating = true; PropFindRequest* pfr = new PropFindRequest(_d.get()); @@ -344,7 +344,7 @@ void SVNRepository::update() bool SVNRepository::isDoingSync() const { - if (_d->status != SVN_NO_ERROR) { + if (_d->status != REPO_NO_ERROR) { return false; } @@ -374,7 +374,7 @@ void SVNRepoPrivate::propFindComplete(HTTP::Request* req, DAVCollection* c) void SVNRepoPrivate::propFindFailed(HTTP::Request *req, SVNRepository::ResultCode err) { - if (err != SVNRepository::SVN_ERROR_NOT_FOUND) { + if (err != SVNRepository::REPO_ERROR_NOT_FOUND) { SG_LOG(SG_TERRASYNC, SG_WARN, "PropFind failed for:" << req->url()); } diff --git a/simgear/io/SVNRepository.hxx b/simgear/io/SVNRepository.hxx index ab174dcb..561c2c0d 100644 --- a/simgear/io/SVNRepository.hxx +++ b/simgear/io/SVNRepository.hxx @@ -17,62 +17,42 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -#ifndef SG_IO_DAVMIRRORTREE_HXX -#define SG_IO_DAVMIRRORTREE_HXX +#ifndef SG_IO_SVN_REPOSITORY_HXX +#define SG_IO_SVN_REPOSITORY_HXX -#include -#include -#include - -#include +#include namespace simgear { - - namespace HTTP { - class Client; - } - -class SVNDirectory; + +class SVNDirectory; class SVNRepoPrivate; -class SVNRepository +class SVNRepository : public AbstractRepository { public: - + SVNRepository(const SGPath& root, HTTP::Client* cl); - ~SVNRepository(); + virtual ~SVNRepository(); SVNDirectory* rootDir() const; - SGPath fsBase() const; + virtual SGPath fsBase() const; - void setBaseUrl(const std::string& url); - std::string baseUrl() const; + virtual void setBaseUrl(const std::string& url); + virtual std::string baseUrl() const; - HTTP::Client* http() const; + virtual HTTP::Client* http() const; - void update(); + virtual void update(); - bool isDoingSync() const; - - enum ResultCode { - SVN_NO_ERROR = 0, - SVN_ERROR_NOT_FOUND, - SVN_ERROR_SOCKET, - SVN_ERROR_XML, - SVN_ERROR_TXDELTA, - SVN_ERROR_IO, - SVN_ERROR_CHECKSUM, - SVN_ERROR_FILE_NOT_FOUND, - SVN_ERROR_HTTP - }; - - ResultCode failure() const; + virtual bool isDoingSync() const; + + virtual ResultCode failure() const; private: bool isBare() const; - + std::auto_ptr _d; }; } // of namespace simgear -#endif // of SG_IO_DAVMIRRORTREE_HXX +#endif // of SG_IO_SVN_REPOSITORY_HXX diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index 8622fce7..952a4301 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -169,7 +169,7 @@ public: SyncItem currentItem; bool isNewDirectory; std::queue queue; - std::auto_ptr repository; + std::auto_ptr repository; SGTimeStamp stamp; bool busy; ///< is the slot working or idle @@ -617,9 +617,9 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot) // check result SVNRepository::ResultCode res = slot.repository->failure(); - if (res == SVNRepository::SVN_ERROR_NOT_FOUND) { + if (res == AbstractRepository::REPO_ERROR_NOT_FOUND) { notFound(slot.currentItem); - } else if (res != SVNRepository::SVN_NO_ERROR) { + } else if (res != AbstractRepository::REPO_NO_ERROR) { fail(slot.currentItem); } else { updated(slot.currentItem, slot.isNewDirectory);