Home | Download | Screen shots | Discussion | Documentation
--- | --- | --- | --- | ---

# 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_istream > | get_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