From ac63d37f7b47cecff503382ab40b58f10bee1c19 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 21 Mar 2008 13:08:02 +0000 Subject: [PATCH] Added initial cut of libcurl based plugin --- CMakeLists.txt | 1 + src/osgDB/Registry.cpp | 47 +++--- src/osgPlugins/CMakeLists.txt | 4 + src/osgPlugins/curl/CMakeLists.txt | 8 + src/osgPlugins/curl/ReaderWriterCURL.cpp | 177 +++++++++++++++++++++++ src/osgPlugins/net/ReaderWriterNET.cpp | 16 +- 6 files changed, 229 insertions(+), 24 deletions(-) create mode 100644 src/osgPlugins/curl/CMakeLists.txt create mode 100644 src/osgPlugins/curl/ReaderWriterCURL.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4af3320a8..9f05d5572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,6 +210,7 @@ FIND_PACKAGE(OpenVRML) FIND_PACKAGE(Performer) FIND_PACKAGE(ZLIB) FIND_PACKAGE(GDAL) +FIND_PACKAGE(CURL) SET(wxWidgets_USE_LIBS base core gl net) FIND_PACKAGE(wxWidgets) diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 5d90e8d4d..26ad9ecec 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1406,31 +1406,40 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) if (containsServerAddress(readFunctor._filename)) { - std::string serverName = getServerAddress(readFunctor._filename); - std::string serverFile = getServerFileName(readFunctor._filename); - osg::notify(osg::INFO)<<"Contains sever address : "<(readFunctor._filename); - filename = serverName+':'+serverFile; return readFunctor.doRead(*rw); } else { - return ReaderWriter::ReadResult("Warning: Could not find the .net plugin to read from server."); + ReaderWriter* rw = getReaderWriterForExtension("net"); + if (rw) + { + std::string serverName = getServerAddress(readFunctor._filename); + std::string serverFile = getServerFileName(readFunctor._filename); + osg::notify(osg::INFO)<<"Contains sever address : "<(readFunctor._filename); + filename = serverName+':'+serverFile; + return readFunctor.doRead(*rw); + } + else + { + return ReaderWriter::ReadResult("Warning: Could not find the .net plugin to read from server."); + } + return ReaderWriter::ReadResult("Warning: Could not find the .curl plugin to read from server."); } } diff --git a/src/osgPlugins/CMakeLists.txt b/src/osgPlugins/CMakeLists.txt index 663b20294..c21ebfc43 100644 --- a/src/osgPlugins/CMakeLists.txt +++ b/src/osgPlugins/CMakeLists.txt @@ -96,6 +96,10 @@ IF(GDAL_FOUND) ADD_SUBDIRECTORY(ogr) ENDIF(GDAL_FOUND) +IF(CURL_FOUND) + ADD_SUBDIRECTORY(curl) +ENDIF(CURL_FOUND) + ############################################################ # # 3rd party 3d plugins diff --git a/src/osgPlugins/curl/CMakeLists.txt b/src/osgPlugins/curl/CMakeLists.txt new file mode 100644 index 000000000..ff705897a --- /dev/null +++ b/src/osgPlugins/curl/CMakeLists.txt @@ -0,0 +1,8 @@ +#this file is automatically generated + +SET(TARGET_SRC ReaderWriterCURL.cpp ) + +SET(TARGET_EXTERNAL_LIBRARIES ${CURL_LIBRARY} ) + +#### end var setup ### +SETUP_PLUGIN(curl) diff --git a/src/osgPlugins/curl/ReaderWriterCURL.cpp b/src/osgPlugins/curl/ReaderWriterCURL.cpp new file mode 100644 index 000000000..abe068999 --- /dev/null +++ b/src/osgPlugins/curl/ReaderWriterCURL.cpp @@ -0,0 +1,177 @@ +/* -*-c++-*- VirtualPlanetBuilder - Copyright (C) 1998-2007 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application 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. +*/ + + +#include +#include +#include +#include + +#include +#include + +#include +#include + + +class ReaderWriterCURL : public osgDB::ReaderWriter +{ + public: + + static size_t StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) + { + size_t realsize = size * nmemb; + std::ostream* buffer = (std::ostream*)data; + + buffer->write((const char*)ptr, realsize); + + return realsize; + } + + + ReaderWriterCURL() + { + _curl = curl_easy_init(); + + curl_easy_setopt(_curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + curl_easy_setopt(_curl, CURLOPT_WRITEFUNCTION, StreamMemoryCallback); + } + + ~ReaderWriterCURL() + { + if (_curl) curl_easy_cleanup(_curl); + + _curl = 0; + } + + virtual const char* className() const { return "HTTP Protocol Model Reader"; } + + virtual bool acceptsExtension(const std::string& extension) const + { + return osgDB::equalCaseInsensitive(extension,"curl"); + } + + enum ObjectType + { + OBJECT, + ARCHIVE, + IMAGE, + HEIGHTFIELD, + NODE + }; + + virtual ReadResult openArchive(const std::string& fileName,ArchiveStatus status, unsigned int , const Options* options) const + { + if (status!=READ) return ReadResult(ReadResult::FILE_NOT_HANDLED); + else return readFile(ARCHIVE,fileName,options); + } + + virtual ReadResult readObject(const std::string& fileName, const Options* options) const + { + return readFile(OBJECT,fileName,options); + } + + virtual ReadResult readImage(const std::string& fileName, const Options *options) const + { + return readFile(IMAGE,fileName,options); + } + + virtual ReadResult readHeightField(const std::string& fileName, const Options *options) const + { + return readFile(HEIGHTFIELD,fileName,options); + } + + virtual ReadResult readNode(const std::string& fileName, const Options *options) const + { + return readFile(NODE,fileName,options); + } + + ReadResult readFile(ObjectType objectType, osgDB::ReaderWriter* rw, std::istream& fin, const Options *options) const + { + switch(objectType) + { + case(OBJECT): return rw->readObject(fin,options); + case(ARCHIVE): return rw->openArchive(fin,options); + case(IMAGE): return rw->readImage(fin,options); + case(HEIGHTFIELD): return rw->readHeightField(fin,options); + case(NODE): return rw->readNode(fin,options); + default: break; + } + return ReadResult::FILE_NOT_HANDLED; + } + + virtual ReadResult readFile(ObjectType objectType, const std::string& fullFileName, const Options *options) const + { + std::string fileName; + + std::string ext = osgDB::getFileExtension(fullFileName); + if (ext=="curl") + { + fileName = osgDB::getNameLessExtension(fullFileName); + } + else + { + fileName = fullFileName; + } + + osgDB::ReaderWriter *reader = + osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName)); + + if (!reader) + { + osg::notify(osg::NOTICE)<<"No ReaderWriter for file "< local_opt = const_cast(options); + if (!local_opt) local_opt = new Options; + + if (local_opt.valid() && local_opt->getDatabasePathList().empty()) + { + local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); + } + + ReadResult result = readFile(objectType, reader, buffer, local_opt.get() ); + + local_opt->getDatabasePathList().pop_front(); + + return result; + } + else + { + osg::notify(osg::NOTICE)<<"Read error res = "<tick(); - //osg::notify(osg::NOTICE) << "osgPlugin .net: start load" << inFileName << std::endl; + osg::notify(osg::NOTICE) << "osgPlugin .net: start load" << inFileName << std::endl; std::string hostname; @@ -302,10 +302,16 @@ class NetReader : public osgDB::ReaderWriter readResult = readFile(objectType, reader, in, options ); in.close(); - osg::notify(osg::DEBUG_INFO) << "osgPlugin .net: " << fileName << + osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName << " fetched from local cache." << std::endl; return readResult; } + else + { + osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName << + " could not be found in local cache." << std::endl; + } + } // Fetch from the network @@ -431,8 +437,8 @@ class NetReader : public osgDB::ReaderWriter double ms = osg::Timer::instance()->delta_m(start,osg::Timer::instance()->tick()); - osg::notify(osg::DEBUG_INFO) << "osgPlugin .net: " << fileName << - " fetched from server. in" << ms <<" ms"<< std::endl; + osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName << + " fetched from server. in " << ms <<" ms"<< std::endl; if (objectType==ARCHIVE && readResult.validArchive()) { @@ -457,7 +463,7 @@ class NetReader : public osgDB::ReaderWriter } - osg::notify(osg::DEBUG_INFO) << "osgPlugin .net: " << fileName << + osg::notify(osg::NOTICE) << "osgPlugin .net: " << fileName << " stored to local cache." << std::endl; } }