From 22868bce4fdbca9d4b11f06d099fff1bcb50efa9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 7 Dec 2012 19:05:47 +0000 Subject: [PATCH] From Stephan Huber, "attached you'll find a zip containing some bug-fixes and some refactored + new code. * ZeroConfDevice does now return FILE_NOT_HANDLED instead of FILE_NOT_FOUND * present3D supports multiple devices per env-var P3D_DEVICE, separate multiple device with a space I refactored parts the p3d-plugin, the curl-plugin and parts of Registry and ReaderWriter. Currently the p3d-plugin tries to open all remote files with the help of the curl-plugin. I added a new method to Registry called getReaderWriterForProtocolAndExtension. which will return a ReaderWriter which is capable in handling the remote file for the given protocol and extension. If no readerwriter is found for the given extension, a list is built of all readerwriters supporting the given protocol and this list is checked for support of wildcards (extension = "*"). If anything matches it get returned. I added this principle also to the Registry, so now it's possible to register a generic ReaderWriter which can handle all filetypes for a given protocol, similar what curl is doing. All you have to do is to load the plugin at startup. The curl-fallback is still in place. With these changes it is now possible to reference a movie inside a presentation without a server-address, read the presentation (with curl) and stream the movie with the correct plugin (e.g. QTKit) " --- applications/present3D/present3D.cpp | 8 +++- include/osgDB/ReaderWriter | 2 + include/osgDB/Registry | 5 +++ src/osgDB/ReaderWriter.cpp | 9 ++-- src/osgDB/Registry.cpp | 41 +++++++++++++++++-- .../ReaderWriterZeroConfDevice.cpp | 2 +- src/osgPlugins/curl/ReaderWriterCURL.cpp | 4 ++ src/osgPlugins/curl/ReaderWriterCURL.h | 5 --- src/osgPlugins/p3d/ReaderWriterP3D.cpp | 7 +++- 9 files changed, 68 insertions(+), 15 deletions(-) diff --git a/applications/present3D/present3D.cpp b/applications/present3D/present3D.cpp index 4d2b186ac..838a3731d 100644 --- a/applications/present3D/present3D.cpp +++ b/applications/present3D/present3D.cpp @@ -453,8 +453,12 @@ int main( int argc, char **argv ) const char* p3dDevice = getenv("P3D_DEVICE"); if (p3dDevice) { - addDeviceTo(viewer, p3dDevice); - + osgDB::StringList devices; + osgDB::split(p3dDevice, devices); + for(osgDB::StringList::iterator i = devices.begin(); i != devices.end(); ++i) + { + addDeviceTo(viewer, *i); + } } diff --git a/include/osgDB/ReaderWriter b/include/osgDB/ReaderWriter index c1d07c196..44e06a297 100644 --- a/include/osgDB/ReaderWriter +++ b/include/osgDB/ReaderWriter @@ -64,6 +64,8 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object /** Return true if ReaderWriter accepts specified file extension.*/ virtual bool acceptsExtension(const std::string& /*extension*/) const; + + virtual bool acceptsProtocol(const std::string& protocol) const; /// Bit mask for setting up which feature types are available for read and/or write enum Features diff --git a/include/osgDB/Registry b/include/osgDB/Registry index bfdd491fb..6023b3205 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -128,6 +128,11 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** get const list of all registered ReaderWriters.*/ const ReaderWriterList& getReaderWriterList() const { return _rwList; } + + /** get a list of registered ReaderWriters which can handle given protocol */ + void getReaderWriterListForProtocol(const std::string& protocol, ReaderWriterList& results) const; + + ReaderWriter* getReaderWriterForProtocolAndExtension(const std::string& protocol, const std::string& extension); typedef std::vector< osg::ref_ptr > ImageProcessorList; diff --git a/src/osgDB/ReaderWriter.cpp b/src/osgDB/ReaderWriter.cpp index ec48fd874..e219ab9e9 100644 --- a/src/osgDB/ReaderWriter.cpp +++ b/src/osgDB/ReaderWriter.cpp @@ -41,10 +41,13 @@ bool ReaderWriter::acceptsExtension(const std::string& extension) const { // check for an exact match std::string lowercase_ext = convertToLowerCase(extension); - if (_supportedExtensions.count(lowercase_ext)!=0) return true; + return (_supportedExtensions.count(lowercase_ext)!=0); +} - // if plugin supports wildcard extension then passthrough all types - return (_supportedExtensions.count("*")!=0); +bool ReaderWriter::acceptsProtocol(const std::string& protocol) const +{ + std::string lowercase_protocol = convertToLowerCase(protocol); + return (_supportedProtocols.count(lowercase_protocol)!=0); } void ReaderWriter::supportsProtocol(const std::string& fmt, const std::string& description) diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 32c73719e..abcffb577 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1224,11 +1224,15 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) } } - //If the filename contains a server address and wasn't loaded by any of the plugins, try to use the CURL plugin - //to download the file and use the stream reading functionality of the plugins to load the file + //If the filename contains a server address and wasn't loaded by any of the plugins, try to find a plugin which supports the server + //protocol and supports wildcards. If not successfully use curl as a last fallback if (containsServerAddress(readFunctor._filename)) { - ReaderWriter* rw = getReaderWriterForExtension("curl"); + ReaderWriter* rw = getReaderWriterForProtocolAndExtension( + osgDB::getServerProtocol(readFunctor._filename), + osgDB::getFileExtension(readFunctor._filename) + ); + if (rw) { return readFunctor.doRead(*rw); @@ -1777,3 +1781,34 @@ bool Registry::isProtocolRegistered(const std::string& protocol) return (_registeredProtocols.find( convertToLowerCase(protocol) ) != _registeredProtocols.end()); } +void Registry::getReaderWriterListForProtocol(const std::string& protocol, ReaderWriterList& results) const +{ + for(ReaderWriterList::const_iterator i = _rwList.begin(); i != _rwList.end(); ++i) + { if ((*i)->acceptsProtocol(protocol)) + results.push_back(*i); + } +} + + +ReaderWriter* Registry::getReaderWriterForProtocolAndExtension(const std::string& protocol, const std::string& extension) +{ + // try first the registered ReaderWriter + ReaderWriter* result = getReaderWriterForExtension(extension); + if (result->acceptsProtocol(protocol)) + return result; + + result = NULL; + ReaderWriterList results; + getReaderWriterListForProtocol(protocol, results); + + for(ReaderWriterList::const_iterator i = results.begin(); i != results.end(); ++i) + { + // if we have a readerwriter which supports wildcards, save it as a fallback + if ((*i)->acceptsExtension("*")) + result = *i; + else if ((*i)->acceptsExtension(extension)) + return *i; + } + + return result ? result : getReaderWriterForExtension("curl"); +} diff --git a/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp b/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp index 09d2a06e7..de9e6cc77 100755 --- a/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp +++ b/src/osgPlugins/ZeroConfDevice/ReaderWriterZeroConfDevice.cpp @@ -176,7 +176,7 @@ class ReaderWriterZeroConf : public osgDB::ReaderWriter } } - return ReadResult::FILE_NOT_FOUND; + return ReadResult::FILE_NOT_HANDLED; } private: diff --git a/src/osgPlugins/curl/ReaderWriterCURL.cpp b/src/osgPlugins/curl/ReaderWriterCURL.cpp index 7d9e3815c..ac38ea8db 100644 --- a/src/osgPlugins/curl/ReaderWriterCURL.cpp +++ b/src/osgPlugins/curl/ReaderWriterCURL.cpp @@ -375,6 +375,10 @@ osgDB::ReaderWriter::ReadResult EasyCurl::processResponse(CURLcode res, const st ReaderWriterCURL::ReaderWriterCURL() { supportsProtocol("http","Read from http port using libcurl."); + supportsProtocol("https","Read from https port using libcurl."); + supportsProtocol("ftp","Read from ftp port using libcurl."); + supportsProtocol("ftps","Read from ftps port using libcurl."); + supportsExtension("curl","Psuedo file extension, used to select curl plugin."); supportsExtension("*","Passes all read files to other plugins to handle actual model loading."); supportsOption("OSG_CURL_PROXY","Specify the http proxy."); diff --git a/src/osgPlugins/curl/ReaderWriterCURL.h b/src/osgPlugins/curl/ReaderWriterCURL.h index 61ab9441c..ad65786c7 100644 --- a/src/osgPlugins/curl/ReaderWriterCURL.h +++ b/src/osgPlugins/curl/ReaderWriterCURL.h @@ -104,11 +104,6 @@ class ReaderWriterCURL : public osgDB::ReaderWriter virtual const char* className() const { return "HTTP Protocol Model Reader"; } - virtual bool acceptsExtension(const std::string& extension) const - { - return osgDB::equalCaseInsensitive(extension,"curl"); - } - virtual bool fileExists(const std::string& filename, const osgDB::Options* options) const; virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index bb08cdb17..ff1755512 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -2142,7 +2142,12 @@ class MyReadFileCallback : public virtual osgDB::ReadFileCallback OSG_INFO<<"Trying server file "<getReaderWriterForExtension("curl"); + + // get a specific readerwriter capable of handling the protocol and extension, will return a registered fallback readerwriter for extension '*' + osgDB::ReaderWriter* rw = osgDB::Registry::instance()->getReaderWriterForProtocolAndExtension( + osgDB::getServerProtocol(filename), + osgDB::getFileExtension(filename)); + if (!rw) return osgDB::ReaderWriter::ReadResult::FILE_NOT_HANDLED; switch(type)