From b5a15fb5b4f2d6fdbc0def180f6eeb97c18b7dff Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 10 Mar 2009 12:21:13 +0000 Subject: [PATCH] From Stephan Huber, "Attached you'll find a proposal for using different protocols. The idea behind the new code is: 1.) plugins/apps register protocols which they can handle. This is done via osgDB::Registry::registerProtocol(aProtocolName). Plugins register supported protocols as usual via ReaderWriter::supportsProtocol(..), the Registry is updated accordingly. 2.) osgDB::containsServerAddress checks first for an appearance of "://" in the filename and then checks the protocol against the set of registered protocols via Registry::isProtocolRegistered(aProtocollName) 3.) the other getServer*-functions changed as well, there's even a getServerProtocol-function With these changes filenames/Urls get routed to loaded plugins even with different protocols than 'http'." --- include/osgDB/FileNameUtils | 1 + include/osgDB/Registry | 12 +++++++++++- src/osgDB/FileNameUtils.cpp | 38 +++++++++++++++++++++++++++---------- src/osgDB/ReaderWriter.cpp | 1 + src/osgDB/Registry.cpp | 15 +++++++++++++++ 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/include/osgDB/FileNameUtils b/include/osgDB/FileNameUtils index 234bec22f..7f9310cb0 100644 --- a/include/osgDB/FileNameUtils +++ b/include/osgDB/FileNameUtils @@ -40,6 +40,7 @@ extern OSGDB_EXPORT bool equalCaseInsensitive(const std::string& lhs,const std:: extern OSGDB_EXPORT bool equalCaseInsensitive(const std::string& lhs,const char* rhs); extern OSGDB_EXPORT bool containsServerAddress(const std::string& filename); +extern OSGDB_EXPORT std::string getServerProtocol(const std::string& filename); extern OSGDB_EXPORT std::string getServerAddress(const std::string& filename); extern OSGDB_EXPORT std::string getServerFileName(const std::string& filename); diff --git a/include/osgDB/Registry b/include/osgDB/Registry index e79a727ee..b4e98a654 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -478,7 +478,13 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** Add an Archive extension.*/ void addArchiveExtension(const std::string ext); - + + /** registers a protocol */ + void registerProtocol(const std::string& protocol); + + /** returns true, if named protocol is registered */ + bool isProtocolRegistered(const std::string& protocol); + protected: virtual ~Registry(); @@ -491,6 +497,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced typedef std::pair, double > ObjectTimeStampPair; typedef std::map ObjectCache; typedef std::map > ArchiveCache; + + typedef std::set RegisteredProtocolsSet; /** constructor is private, as its a singleton, preventing construction other than via the instance() method and @@ -508,6 +516,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced osg::ref_ptr _authenticationMap; bool _createNodeFromImage; + + RegisteredProtocolsSet _registeredProtocols; osg::Object* readObject(DotOsgWrapperMap& dowMap,Input& fr); diff --git a/src/osgDB/FileNameUtils.cpp b/src/osgDB/FileNameUtils.cpp index 605fc94dc..99af0f249 100644 --- a/src/osgDB/FileNameUtils.cpp +++ b/src/osgDB/FileNameUtils.cpp @@ -179,26 +179,42 @@ bool osgDB::equalCaseInsensitive(const std::string& lhs,const char* rhs) return true; } + + bool osgDB::containsServerAddress(const std::string& filename) { - // need to check for http:// - if (filename.size()<7) return false; - if (filename.compare(0,7,"http://")==0) return true; - return false; + // need to check for :// + std::string::size_type pos(filename.find_first_of("://")); + if (pos == std::string::npos) + return false; + std::string proto(filename.substr(0, pos)); + + return Registry::instance()->isProtocolRegistered(proto); +} + +std::string osgDB::getServerProtocol(const std::string& filename) +{ + std::string::size_type pos(filename.find_first_of("://")); + if (pos != std::string::npos) + return filename.substr(0,pos); + + return ""; } std::string osgDB::getServerAddress(const std::string& filename) { - if (filename.size()>=7 && filename.compare(0,7,"http://")==0) + std::string::size_type pos(filename.find_first_of("://")); + + if (pos != std::string::npos) { - std::string::size_type pos_slash = filename.find_first_of('/',7); + std::string::size_type pos_slash = filename.find_first_of('/',pos+3); if (pos_slash!=std::string::npos) { - return filename.substr(7,pos_slash-7); + return filename.substr(pos+3,pos_slash-pos-3); } else { - return filename.substr(7,std::string::npos); + return filename.substr(pos+3,std::string::npos); } } return ""; @@ -206,9 +222,11 @@ std::string osgDB::getServerAddress(const std::string& filename) std::string osgDB::getServerFileName(const std::string& filename) { - if (filename.size()>=7 && filename.compare(0,7,"http://")==0) + std::string::size_type pos(filename.find_first_of("://")); + + if (pos != std::string::npos) { - std::string::size_type pos_slash = filename.find_first_of('/',7); + std::string::size_type pos_slash = filename.find_first_of('/',pos+3); if (pos_slash!=std::string::npos) { return filename.substr(pos_slash+1,std::string::npos); diff --git a/src/osgDB/ReaderWriter.cpp b/src/osgDB/ReaderWriter.cpp index 105e955f8..ac1705309 100644 --- a/src/osgDB/ReaderWriter.cpp +++ b/src/osgDB/ReaderWriter.cpp @@ -47,6 +47,7 @@ bool ReaderWriter::acceptsExtension(const std::string& extension) const void ReaderWriter::supportsProtocol(const std::string& fmt, const std::string& description) { + Registry::instance()->registerProtocol(fmt); _supportedProtocols[convertToLowerCase(fmt)] = description; } diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 8376e58ca..b41c618af 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -331,6 +331,9 @@ Registry::Registry() addFileExtensionAlias("pgm", "pnm"); addFileExtensionAlias("ppm", "pnm"); + // register http-protocol, so the curl can handle it, if necessary + registerProtocol("http"); + } @@ -2092,3 +2095,15 @@ SharedStateManager* Registry::getOrCreateSharedStateManager() return _sharedStateManager.get(); } + + +void Registry::registerProtocol(const std::string& protocol) +{ + _registeredProtocols.insert( convertToLowerCase(protocol) ); +} + +bool Registry::isProtocolRegistered(const std::string& protocol) +{ + return (_registeredProtocols.find( convertToLowerCase(protocol) ) != _registeredProtocols.end()); +} +