openvrml::resource_fetcher Class Reference

An abstract factory for resource_istreams. More...

List of all members.


Public Member Functions

virtual ~resource_fetcher ()=0 throw ()
 Destroy.
std::auto_ptr< resource_istreamget_resource (const std::string &uri)
 Fetch a network resource.

Private Member Functions

virtual std::auto_ptr
< resource_istream
do_get_resource (const std::string &uri)=0
 Fetch a network resource.

Detailed Description

An abstract factory for resource_istreams.

A concrete implementation of this interface must be passed to browser's constructor.

See also:
openvrml::browser

Constructor & Destructor Documentation

openvrml::resource_fetcher::~resource_fetcher (  )  throw () [pure virtual]

Destroy.


Member Function Documentation

std::auto_ptr< openvrml::resource_istream > openvrml::resource_fetcher::get_resource ( const std::string &  uri  ) 

Fetch a network resource.

Parameters:
[in] uri a Uniform Resource Identifier.
This function delegates to resource_fetcher::do_get_resource.

Returns:
the requested resource as a stream.
Exceptions:
std::invalid_argument if uri is malformed or in an unsupported format.

std::auto_ptr< openvrml::resource_istream > openvrml::resource_fetcher::do_get_resource ( const std::string &  uri  )  [private, pure virtual]

Fetch a network resource.

Called by get_resource, clients of OpenVRML are required to provide an implementation for this function. OpenVRML depends on the implementation of this function for all of its input needs. As such, what kinds of resources OpenVRML is capable of resolving are entirely dependent on code provided by the application.

Implementations should throw std::invalid_argument if uri is malformed or in an format that is not supported by the implementation.

A trivial implementation designed to handle only file resources can use std::filebuf:

 std::auto_ptr<openvrml::resource_istream>
 my_resource_fetcher::do_get_resource(const std::string & uri)
 {
     using std::auto_ptr;
     using std::invalid_argument;
     using std::string;
     using openvrml::resource_istream;

     class file_resource_istream : public resource_istream {
         std::string url_;
         std::filebuf buf_;

     public:
         explicit file_resource_istream(const std::string & path):
             resource_istream(&this->buf_)
         {
             //
             // Note that the failbit is set in the constructor if no data
             // can be read from the stream.  This is important.  If the
             // failbit is not set on such a stream, OpenVRML will attempt
             // to read data from a stream that cannot provide it.
             //
             if (!this->buf_.open(path.c_str(),
                                  ios_base::in | ios_base::binary)) {
                 this->setstate(ios_base::badbit);
             }
         }

         void url(const std::string & str)
         {
             this->url_ = str;
         }

     private:
         virtual const std::string url() const
         {
             return this->url_;
         }

         virtual const std::string type() const
         {
             //
             // A real application should use OS facilities for this;
             // however, that is beyond the scope of this example (which
             // is intended to be portable and stupid).
             //
             using std::find;
             using std::string;
             using boost::algorithm::iequals;
             using boost::next;
             string media_type = "application/octet-stream";
             const string::const_reverse_iterator dot_pos =
                 find(this->url_.rbegin(), this->url_.rend(), '.');
             if (dot_pos == this->url_.rend()
                 || next(dot_pos.base()) == this->url_.end()) {
                 return media_type;
             }
             const string::const_iterator hash_pos =
                 find(next(dot_pos.base()), this->url_.end(), '#');
             const string ext(dot_pos.base(), hash_pos);
             if (iequals(ext, "wrl")) {
                 media_type = "model/vrml";
             } else if (iequals(ext, "png")) {
                 media_type = "image/png";
             } else if (iequals(ext, "jpg") || iequals(ext, "jpeg")) {
                 media_type = "image/jpeg";
             }
             return media_type;
         }

         virtual bool data_available() const
         {
             return !!(*this);
         }
     };

     const string scheme = uri.substr(0, uri.find_first_of(':'));
     if (scheme != "file") {
         throw invalid_argument('\"' + scheme + "\" URI scheme not "
                                "supported");
     }
     //
     // file://
     //        ^
     // 01234567
     //
     string path = uri.substr(uri.find_first_of('/', 7));

     auto_ptr<resource_istream> in(new file_resource_istream(path));
     static_cast<file_resource_istream *>(in.get())->url(uri);

     return in;
 }

The uri parameter is provided by OpenVRML and can be assumed to be an absolute URI. As such, it will always have a scheme through which the client code can choose a resolution mechanism. For more information on URI syntax, see Internet STD 66.

Parameters:
[in] uri an absolute Uniform Resource Identifier.
Returns:
the requested resource as a stream.
Exceptions:
std::invalid_argument if uri is malformed or in an unsupported format.
See also:
ftp://ftp.rfc-editor.org/in-notes/std/std66.txt