Added two options to the .net loader:
hostname=<hostname> - Specify the host to connect to to retreive files
server_prefix=<directory> - Specify a prefix to each file indicating
a directory for the server to look into
Also, the .net server now does not require a file to have the .net
suffix. ALl this together now means that you can do this:
osgviewer -e net -O "hostname=openscenegraph.org server_prefix=BlueMarble" earth.ive
And view the whole earth streamed from a server.
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
#include <osg/Notify>
|
||||
|
||||
#include <osgDB/Input>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
@@ -13,14 +14,27 @@
|
||||
|
||||
#include "sockinet.h"
|
||||
|
||||
extern bool goGetTheFile(const std::string &host, const std::string & file, const std::string &saveDir );
|
||||
/*
|
||||
* Semantics:
|
||||
* Two methods for using the .net loader.
|
||||
* 1) Add a hostname prefix and a '.net' suffix on a model when passing
|
||||
* to osgDB::readNodeFile()
|
||||
* e.g: osgDB::readNodeFile( "openscenegraph.org:cow.osg.net" );
|
||||
*
|
||||
* 2) Explicitely load the .net plugin and pass the plugin options including
|
||||
* hostname=<hostname>
|
||||
*
|
||||
* Method #1 takes precedence. SO, if the hostname option is passed the
|
||||
* plugin, but the name also contains a hostname prefix, the hostname
|
||||
* prefix on the file name will override the option
|
||||
*/
|
||||
|
||||
class NetReader : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
NetReader() {}
|
||||
|
||||
virtual const char* className() { return "Network Reader"; }
|
||||
virtual const char* className() { return "HTTP Protocol Model Reader"; }
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
@@ -30,39 +44,144 @@ class NetReader : public osgDB::ReaderWriter
|
||||
virtual ReadResult readObject(const std::string& fileName, const Options* opt)
|
||||
{ return readNode(fileName,opt); }
|
||||
|
||||
virtual ReadResult readNode(const std::string& fileName, const Options* )
|
||||
virtual ReadResult readNode(const std::string& inFileName, const Options *options )
|
||||
{
|
||||
std::string ext = osgDB::getFileExtension(fileName);
|
||||
std::string hostname;
|
||||
std::string server_prefix;
|
||||
int port = 80;
|
||||
|
||||
if (options)
|
||||
{
|
||||
std::istringstream iss(options->getOptionString());
|
||||
std::string opt;
|
||||
while (iss >> opt)
|
||||
{
|
||||
int index = opt.find( "=" );
|
||||
if( opt.substr( 0, index ) == "hostname" ||
|
||||
opt.substr( 0, index ) == "HOSTNAME" )
|
||||
{
|
||||
hostname = opt.substr( index+1 );
|
||||
}
|
||||
else if( opt.substr( 0, index ) == "port" ||
|
||||
opt.substr( 0, index ) == "PORT" )
|
||||
{
|
||||
port = atoi( opt.substr(index+1).c_str() );
|
||||
}
|
||||
else if( opt.substr( 0, index ) == "server_prefix" ||
|
||||
opt.substr( 0, index ) == "server_prefix" )
|
||||
{
|
||||
server_prefix = opt.substr(index+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* * we accept all extensions
|
||||
std::string ext = osgDB::getFileExtension(inFileName);
|
||||
if (!acceptsExtension(ext))
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
*/
|
||||
|
||||
int index = fileName.find(":");
|
||||
if( index == -1 )
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
std::string fileName;
|
||||
int index = inFileName.find(":");
|
||||
// If we haven't been given a hostname as an option
|
||||
// and it hasn't been prefixed to the name, we fail
|
||||
if( index != -1 )
|
||||
{
|
||||
hostname = inFileName.substr( 0, index);
|
||||
// need to strip the inFileName of the hostname prefix
|
||||
fileName = inFileName.substr( index+1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hostname.empty() )
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
else
|
||||
fileName = inFileName;
|
||||
}
|
||||
|
||||
std::string host = fileName.substr( 0, index);
|
||||
int rindex = fileName.rfind( "." );
|
||||
std::string file = fileName.substr( index+1, rindex-index-1 );
|
||||
// Let's also strip the possible .net extension
|
||||
if( osgDB::getFileExtension( fileName ) == "net" )
|
||||
{
|
||||
int rindex = fileName.rfind( "." );
|
||||
fileName = fileName.substr( 0, rindex );
|
||||
}
|
||||
|
||||
iosockinet sio (sockbuf::sock_stream);
|
||||
sio->connect( host.c_str(), 80 );
|
||||
|
||||
sio << "GET /" << file << " HTTP/1.1\n" << "Host:\n\n";
|
||||
try {
|
||||
sio->connect( hostname.c_str(), port );
|
||||
}
|
||||
catch( sockerr e )
|
||||
{
|
||||
osg::notify(osg::WARN) << "osgPlugin .net reader: Unable to connect to host " << hostname << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
if( !server_prefix.empty() )
|
||||
fileName = server_prefix + '/' + fileName;
|
||||
|
||||
sio << "GET /" << fileName << " HTTP/1.1\n" << "Host:\n\n";
|
||||
sio.flush();
|
||||
|
||||
char linebuff[256];
|
||||
do
|
||||
{
|
||||
sio.getline( linebuff, sizeof( linebuff ));
|
||||
|
||||
std::istringstream iss(linebuff);
|
||||
std::string directive;
|
||||
iss >> directive;
|
||||
if( directive.substr(0,4) == "HTTP" )
|
||||
{
|
||||
iss >> directive;
|
||||
// Code 200. We be ok.
|
||||
if( directive == "200" )
|
||||
;
|
||||
// Code 400 Bad Request
|
||||
else if( directive == "400" )
|
||||
{
|
||||
osg::notify(osg::WARN) <<
|
||||
"osgPluing .net: http server response 400 - Bad Request" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
// Code 401 Bad Request
|
||||
else if( directive == "401" )
|
||||
{
|
||||
osg::notify(osg::WARN) <<
|
||||
"osgPluing .net: http server response 401 - Unauthorized Access" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
// Code 403 Bad Request
|
||||
else if( directive == "403" )
|
||||
{
|
||||
osg::notify(osg::WARN) <<
|
||||
"osgPluing .net: http server response 403 - Access Forbidden" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
// Code 404 File not found
|
||||
else if( directive == "404" )
|
||||
{
|
||||
osg::notify(osg::WARN) <<
|
||||
"osgPluing .net: http server response 404 - File Not Found" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
// Code 405 Method not allowed
|
||||
else if( directive == "405" )
|
||||
{
|
||||
osg::notify(osg::WARN) <<
|
||||
"osgPluing .net: http server response 405 - Method Not Allowed" << std::endl;
|
||||
return ReadResult::FILE_NOT_FOUND;
|
||||
}
|
||||
// There's more....
|
||||
}
|
||||
|
||||
} while( linebuff[0] != '\r' );
|
||||
|
||||
|
||||
// Invoke the reader corresponding to the extension
|
||||
osgDB::ReaderWriter *reader =
|
||||
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(file));
|
||||
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));
|
||||
|
||||
ReadResult readResult = ReadResult::FILE_NOT_HANDLED;
|
||||
if( reader == 0L )
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
else
|
||||
if( reader != 0L )
|
||||
readResult = reader->readNode( sio );
|
||||
|
||||
return readResult;
|
||||
|
||||
Reference in New Issue
Block a user