|
From: <br...@us...> - 2009-03-19 05:27:15
|
Revision: 3848
http://openvrml.svn.sourceforge.net/openvrml/?rev=3848&view=rev
Author: braden
Date: 2009-03-19 05:27:10 +0000 (Thu, 19 Mar 2009)
Log Message:
-----------
Moved bounded_buffer and plugin_streambuf to libopenvrml-control.
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/Makefile.am
trunk/src/libopenvrml-control/openvrml_control/browser.cpp
trunk/src/libopenvrml-control/openvrml_control/browser.h
Added Paths:
-----------
trunk/src/libopenvrml-control/openvrml_control/bounded_buffer.h
trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp
trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.h
Removed Paths:
-------------
trunk/src/openvrml-xembed/bounded_buffer.h
trunk/src/openvrml-xembed/plugin_streambuf.cpp
trunk/src/openvrml-xembed/plugin_streambuf.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/ChangeLog 2009-03-19 05:27:10 UTC (rev 3848)
@@ -1,5 +1,60 @@
2009-03-19 Braden McDaniel <br...@en...>
+ Moved bounded_buffer and plugin_streambuf to libopenvrml-control.
+
+ * src/Makefile.am
+ (noinst_HEADERS): Removed openvrml-xembed/bounded_buffer.h and
+ openvrml-xembed/plugin_streambuf.h.
+ (libopenvrml_control_libopenvrml_control_la_SOURCES): Added
+ libopenvrml-control/openvrml_control/plugin_streambuf.{cpp,h} and
+ libopenvrml-control/openvrml_control/bounded_buffer.h.
+ (libopenvrml_control_libopenvrml_control_la_CPPFLAGS): Don't need
+ $(top_srcdir)/src/openvrml-xembed in the include path anymore.
+ (openvrml_xembed_openvrml_xembed_CPPFLAGS): Don't need
+ $(top_srcdir)/src/openvrml-xembed in the include path anymore.
+ (openvrml_xembed_openvrml_xembed_SOURCES): Removed
+ openvrml-xembed/plugin_streambuf.cpp.
+ * src/libopenvrml-control/openvrml_control/bounded_buffer.h: Moved
+ from src/openvrml-xembed/bounded_buffer.h.
+ * src/libopenvrml-control/openvrml_control/browser.cpp
+ (openvrml_control::browser::resource_fetcher::resource_fetcher(
+ browser_host &, uninitialized_plugin_streambuf_map &,
+ plugin_streambuf_map &)): uninitialized_plugin_streambuf_map and
+ plugin_streambuf_map are now in the openvrml_control namespace.
+ (openvrml_control::browser::resource_fetcher::do_get_resource(const
+ std::string &)): plugin_streambuf is now in the openvrml_control
+ namespace.
+ (initial_stream_reader::initial_stream_reader(const
+ boost::shared_ptr<openvrml_control::plugin_streambuf> &,
+ openvrml::browser &)): plugin_streambuf is now in the
+ openvrml_control namespace.
+ (initial_stream_reader::operator()() const): plugin_streambuf is
+ now in the openvrml_control namespace.
+ (openvrml_control::browser::browser(browser_host &, bool)):
+ plugin_streambuf is now in the openvrml_control namespace.
+ (openvrml_control::browser::new_stream(uint64_t, const std::string
+ &, const std::string &)): Removed obsolete reference to
+ openvrml_xembed namespace.
+ (openvrml_control::browser::destroy_stream(uint64_t)): Removed
+ obsolete reference to openvrml_xembed namespace.
+ (openvrml_control::browser::write(uint64_t, const unsigned char *,
+ size_t)): Removed obsolete reference to openvrml_xembed namespace.
+ * src/libopenvrml-control/openvrml_control/browser.h:
+ uninitialized_plugin_streambuf_map and plugin_streambuf_map are
+ now in the openvrml_control namespace.
+ * src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp:
+ Moved from src/openvrml-xembed/plugin_streambuf.cpp.
+ * src/libopenvrml-control/openvrml_control/plugin_streambuf.h:
+ Moved from src/openvrml-xembed/plugin_streambuf.h.
+ * src/openvrml-xembed/bounded_buffer.h: Moved to
+ src/libopenvrml-control/openvrml_control/bounded_buffer.h.
+ * src/openvrml-xembed/plugin_streambuf.cpp: Moved to
+ src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp.
+ * src/openvrml-xembed/plugin_streambuf.h: Moved to
+ src/libopenvrml-control/openvrml_control/plugin_streambuf.h.
+
+2009-03-19 Braden McDaniel <br...@en...>
+
Removed crufty uses of openvrml_xembed namespace.
* src/openvrml-xembed/browser.cpp
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/Makefile.am 2009-03-19 05:27:10 UTC (rev 3848)
@@ -45,8 +45,6 @@
noinst_HEADERS = \
libopenvrml/private.h \
- openvrml-xembed/bounded_buffer.h \
- openvrml-xembed/plugin_streambuf.h \
openvrml-player/filechooserdialog.h
LIBOPENVRML_LIBRARY_VERSION = 8:8:0
@@ -732,9 +730,11 @@
endif
libopenvrml_control_libopenvrml_control_la_SOURCES = \
libopenvrml-control/openvrml_control/browser.cpp \
- libopenvrml-control/openvrml_control/browser.h
+ libopenvrml-control/openvrml_control/browser.h \
+ libopenvrml-control/openvrml_control/plugin_streambuf.cpp \
+ libopenvrml-control/openvrml_control/plugin_streambuf.h \
+ libopenvrml-control/openvrml_control/bounded_buffer.h
libopenvrml_control_libopenvrml_control_la_CPPFLAGS = \
- -I$(top_srcdir)/src/openvrml-xembed \
-I$(top_builddir)/src/libopenvrml \
-I$(top_srcdir)/src/libopenvrml
libopenvrml_control_libopenvrml_control_la_LIBADD = \
@@ -742,7 +742,6 @@
openvrml_xembed_openvrml_xembed_CPPFLAGS = \
-I$(top_builddir)/src/openvrml-xembed \
- -I$(top_srcdir)/src/openvrml-xembed \
-I$(top_srcdir)/src/libopenvrml-control \
-I$(top_builddir)/src/libopenvrml \
-I$(top_srcdir)/src/libopenvrml \
@@ -757,7 +756,6 @@
openvrml-xembed/main.cpp \
openvrml-xembed/browserfactory.cpp \
openvrml-xembed/browserfactory.h \
- openvrml-xembed/plugin_streambuf.cpp \
openvrml-xembed/browser.cpp \
openvrml-xembed/browser.h \
openvrml-xembed/streamclient.cpp \
Copied: trunk/src/libopenvrml-control/openvrml_control/bounded_buffer.h (from rev 3845, trunk/src/openvrml-xembed/bounded_buffer.h)
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/bounded_buffer.h (rev 0)
+++ trunk/src/libopenvrml-control/openvrml_control/bounded_buffer.h 2009-03-19 05:27:10 UTC (rev 3848)
@@ -0,0 +1,116 @@
+// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
+//
+// OpenVRML Control
+//
+// Copyright 2004, 2005, 2006, 2007 Braden McDaniel
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program 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. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+
+# ifndef OPENVRML_CONTROL_BOUNDED_BUFFER_H
+# define OPENVRML_CONTROL_BOUNDED_BUFFER_H
+
+# include <cassert>
+# include <string>
+# include <boost/thread/mutex.hpp>
+# include <boost/thread/condition.hpp>
+
+namespace openvrml_control {
+
+ template <typename CharT, size_t BufferSize>
+ class bounded_buffer {
+ mutable boost::mutex mutex_;
+ boost::condition buffer_not_full_, buffer_not_empty_or_eof_;
+
+ CharT buf_[BufferSize];
+ size_t begin_, end_, buffered_;
+ bool eof_;
+
+ public:
+ typedef CharT char_type;
+ typedef typename std::char_traits<char_type> traits_type;
+ typedef typename traits_type::int_type int_type;
+
+ bounded_buffer();
+ void put(const char_type & c);
+ int_type get();
+ size_t buffered() const;
+ void set_eof();
+ bool eof() const;
+ };
+
+ template <typename CharT, size_t BufferSize>
+ bounded_buffer<CharT, BufferSize>::bounded_buffer():
+ begin_(0),
+ end_(0),
+ buffered_(0),
+ eof_(false)
+ {}
+
+ template <typename CharT, size_t BufferSize>
+ void bounded_buffer<CharT, BufferSize>::put(const char_type & c)
+ {
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->buffered_ == BufferSize) {
+ this->buffer_not_full_.wait(lock);
+ }
+ this->buf_[this->end_] = c;
+ this->end_ = (this->end_ + 1) % BufferSize;
+ ++this->buffered_;
+ this->buffer_not_empty_or_eof_.notify_one();
+ }
+
+ template <typename CharT, size_t BufferSize>
+ typename bounded_buffer<CharT, BufferSize>::int_type
+ bounded_buffer<CharT, BufferSize>::get()
+ {
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->buffered_ == 0 && !this->eof_) {
+ this->buffer_not_empty_or_eof_.wait(lock);
+ }
+ if (this->buffered_ == 0 && this->eof_) {
+ return traits_type::eof();
+ }
+ const int_type c = traits_type::to_int_type(this->buf_[this->begin_]);
+ this->begin_ = (this->begin_ + 1) % BufferSize;
+ --this->buffered_;
+ this->buffer_not_full_.notify_one();
+ assert(!traits_type::eq_int_type(c, traits_type::eof()));
+ return c;
+ }
+
+ template <typename CharT, size_t BufferSize>
+ size_t bounded_buffer<CharT, BufferSize>::buffered() const
+ {
+ boost::mutex::scoped_lock lock(this->mutex_);
+ return this->buffered_;
+ }
+
+ template <typename CharT, size_t BufferSize>
+ void bounded_buffer<CharT, BufferSize>::set_eof()
+ {
+ boost::mutex::scoped_lock lock(this->mutex_);
+ this->eof_ = true;
+ this->buffer_not_empty_or_eof_.notify_one();
+ }
+
+ template <typename CharT, size_t BufferSize>
+ bool bounded_buffer<CharT, BufferSize>::eof() const
+ {
+ boost::mutex::scoped_lock lock(this->mutex_);
+ return this->eof_;
+ }
+}
+
+# endif // ifndef OPENVRML_CONTROL_BOUNDED_BUFFER_H
Property changes on: trunk/src/libopenvrml-control/openvrml_control/bounded_buffer.h
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:mergeinfo
+ /branches/0.17/src/openvrml-xembed/bounded_buffer.h:3713,3717,3719,3721,3725,3730,3732,3743,3746,3748,3750,3752,3754,3757,3759-3760,3764,3766,3824,3828,3836
/branches/local/src/openvrml-xembed/bounded_buffer.h:3677-3689
/branches/node-modules/src/openvrml-xembed/bounded_buffer.h:3622-3623,3632-3635,3637-3638,3640-3641,3643-3644,3646-3647,3649-3650,3654-3655,3657-3658,3661-3662,3664-3665,3667-3668,3670-3671,3673-3674,3684-3685,3687-3688,3736-3801
Added: svn:eol-style
+ native
Modified: trunk/src/libopenvrml-control/openvrml_control/browser.cpp
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/browser.cpp 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/libopenvrml-control/openvrml_control/browser.cpp 2009-03-19 05:27:10 UTC (rev 3848)
@@ -37,9 +37,9 @@
openvrml_control::browser::resource_fetcher::
resource_fetcher(browser_host & control_host,
- openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map &
uninitialized_plugin_streambuf_map,
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map):
+ plugin_streambuf_map & plugin_streambuf_map):
control_host_(control_host),
uninitialized_plugin_streambuf_map_(uninitialized_plugin_streambuf_map),
plugin_streambuf_map_(plugin_streambuf_map)
@@ -62,8 +62,6 @@
openvrml_control::browser::resource_fetcher::
do_get_resource(const std::string & uri)
{
- using openvrml_xembed::plugin_streambuf;
-
class plugin_resource_istream : public openvrml::resource_istream {
const boost::shared_ptr<plugin_streambuf> streambuf_;
resource_fetcher & resource_fetcher_;
@@ -145,7 +143,7 @@
struct OPENVRML_LOCAL initial_stream_reader {
initial_stream_reader(
- const boost::shared_ptr<openvrml_xembed::plugin_streambuf> &
+ const boost::shared_ptr<openvrml_control::plugin_streambuf> &
streambuf,
openvrml::browser & browser):
streambuf_(streambuf),
@@ -154,7 +152,7 @@
void operator()() const throw ()
{
- using openvrml_xembed::plugin_streambuf;
+ using openvrml_control::plugin_streambuf;
class plugin_istream : public openvrml::resource_istream {
boost::shared_ptr<plugin_streambuf> streambuf_;
@@ -191,7 +189,7 @@
}
private:
- boost::shared_ptr<openvrml_xembed::plugin_streambuf> streambuf_;
+ boost::shared_ptr<openvrml_control::plugin_streambuf> streambuf_;
openvrml::browser & browser_;
};
}
@@ -215,7 +213,6 @@
if (expect_initial_stream) {
using boost::function0;
using boost::shared_ptr;
- using openvrml_xembed::plugin_streambuf;
const shared_ptr<plugin_streambuf> initial_stream(
new plugin_streambuf(::initial_stream_uri,
@@ -252,7 +249,6 @@
const std::string & uri)
OPENVRML_THROW1(unknown_stream)
{
- using namespace openvrml_xembed;
using boost::shared_ptr;
shared_ptr<plugin_streambuf> streambuf =
@@ -274,7 +270,6 @@
void openvrml_control::browser::destroy_stream(const uint64_t stream_id)
OPENVRML_THROW1(unknown_stream)
{
- using namespace openvrml_xembed;
using boost::shared_ptr;
const shared_ptr<plugin_streambuf> streambuf =
@@ -289,7 +284,6 @@
const size_t size)
OPENVRML_THROW1(unknown_stream)
{
- using namespace openvrml_xembed;
using boost::shared_ptr;
const shared_ptr<plugin_streambuf> streambuf =
Modified: trunk/src/libopenvrml-control/openvrml_control/browser.h
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/browser.h 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/libopenvrml-control/openvrml_control/browser.h 2009-03-19 05:27:10 UTC (rev 3848)
@@ -40,17 +40,17 @@
class resource_fetcher : public openvrml::resource_fetcher {
browser_host & control_host_;
- openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map &
uninitialized_plugin_streambuf_map_;
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map_;
+ plugin_streambuf_map & plugin_streambuf_map_;
boost::thread_group thread_group_;
public:
resource_fetcher(
browser_host & control_host,
- openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map &
uninitialized_plugin_streambuf_map,
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map);
+ plugin_streambuf_map & plugin_streambuf_map);
virtual ~resource_fetcher() OPENVRML_NOTHROW;
void create_thread(const boost::function0<void> & threadfunc);
@@ -71,9 +71,9 @@
do_browser_changed(const openvrml::browser_event & event);
};
- openvrml_xembed::uninitialized_plugin_streambuf_map
+ uninitialized_plugin_streambuf_map
uninitialized_streambuf_map_;
- openvrml_xembed::plugin_streambuf_map streambuf_map_;
+ plugin_streambuf_map streambuf_map_;
resource_fetcher fetcher_;
browser_listener listener_;
openvrml::browser browser_;
Copied: trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp (from rev 3845, trunk/src/openvrml-xembed/plugin_streambuf.cpp)
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp (rev 0)
+++ trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp 2009-03-19 05:27:10 UTC (rev 3848)
@@ -0,0 +1,264 @@
+// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
+//
+// OpenVRML Control
+//
+// Copyright 2004, 2005, 2006, 2007, 2008 Braden N. McDaniel
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program 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. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+
+# include "plugin_streambuf.h"
+
+openvrml_control::plugin_streambuf::
+plugin_streambuf(const std::string & requested_url,
+ uninitialized_plugin_streambuf_map & uninitialized_map,
+ plugin_streambuf_map & map):
+ state_(requested),
+ get_url_result_(-1),
+ url_(requested_url),
+ i_(0),
+ c_('\0'),
+ uninitialized_map_(uninitialized_map),
+ map_(map)
+{
+ //
+ // This is really just here to emphasize that c_ must not be EOF.
+ //
+ this->i_ = traits_type::not_eof(this->i_);
+ this->c_ =
+ traits_type::to_char_type(
+ traits_type::not_eof(traits_type::to_int_type(this->c_)));
+
+ this->setg(&this->c_, &this->c_, &this->c_);
+}
+
+openvrml_control::plugin_streambuf::state_id
+openvrml_control::plugin_streambuf::state() const
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ return this->state_;
+}
+
+void openvrml_control::plugin_streambuf::set_get_url_result(const int result)
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ assert(this->get_url_result_ == -1);
+ this->get_url_result_ = result;
+
+ //
+ // If result is nonzero, the resource fetch failed early (i.e., before
+ // actually getting the stream. In that case, nothing else should be
+ // playing with this. Removing this streambuf from uninitialized_map_
+ // below may (and probably will) result in destruction of this instance.
+ //
+ // So, anyone waiting on received_get_url_result_ should be doing so
+ // because the fetching code is trying to do something with this streambuf
+ // because the fetch is in-progress (i.e., succeeding). If you're waiting
+ // on this condition and result could possibly indicate failure, you're
+ // doing it wrong.
+ //
+ if (result == 0) {
+ this->state_ = plugin_streambuf::uninitialized;
+ this->received_get_url_result_.notify_all();
+ } else {
+ this->uninitialized_map_.erase(*this);
+ }
+}
+
+void openvrml_control::plugin_streambuf::init(const size_t stream_id,
+ const std::string & received_url,
+ const std::string & type)
+{
+ assert(stream_id);
+ assert(!received_url.empty());
+ assert(!type.empty());
+
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->state_ != plugin_streambuf::uninitialized) {
+ this->received_get_url_result_.wait(lock);
+ }
+
+ assert(this->state_ == uninitialized);
+
+ bool succeeded = this->uninitialized_map_.erase(*this);
+ assert(succeeded);
+ this->url_ = received_url;
+ this->type_ = type;
+ this->state_ = plugin_streambuf::initialized;
+ const boost::shared_ptr<plugin_streambuf> this_ = shared_from_this();
+ succeeded = this->map_.insert(stream_id, this_);
+ assert(succeeded);
+ this->streambuf_initialized_or_failed_.notify_all();
+}
+
+void openvrml_control::plugin_streambuf::fail()
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ const bool succeeded = this->uninitialized_map_.erase(*this);
+ assert(succeeded);
+ this->buf_.set_eof();
+ this->streambuf_initialized_or_failed_.notify_all();
+}
+
+const std::string & openvrml_control::plugin_streambuf::url() const
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->state_ != plugin_streambuf::initialized) {
+ this->streambuf_initialized_or_failed_.wait(lock);
+ }
+ return this->url_;
+}
+
+const std::string & openvrml_control::plugin_streambuf::type() const
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->state_ != plugin_streambuf::initialized) {
+ this->streambuf_initialized_or_failed_.wait(lock);
+ }
+ return this->type_;
+}
+
+bool openvrml_control::plugin_streambuf::data_available() const
+{
+ //
+ // It may seem a bit counterintuitive to return true here if the stream
+ // has been destroyed; however, if we don't return true in this case,
+ // clients may never get EOF from the stream.
+ //
+ return this->buf_.buffered() > 0 || this->buf_.eof();
+}
+
+openvrml_control::plugin_streambuf::int_type
+openvrml_control::plugin_streambuf::underflow()
+{
+ boost::mutex::scoped_lock lock(this->mutex_);
+ while (this->state_ != plugin_streambuf::initialized) {
+ this->streambuf_initialized_or_failed_.wait(lock);
+ }
+
+ if (traits_type::eq_int_type(this->i_, traits_type::eof())) {
+ return traits_type::eof();
+ }
+
+ this->i_ = this->buf_.get();
+ this->c_ = traits_type::to_char_type(this->i_);
+
+ if (traits_type::eq_int_type(this->i_, traits_type::eof())) {
+ return traits_type::eof();
+ }
+
+ this->setg(&this->c_, &this->c_, &this->c_ + 1);
+ return traits_type::to_int_type(*this->gptr());
+}
+
+const boost::shared_ptr<openvrml_control::plugin_streambuf>
+openvrml_control::uninitialized_plugin_streambuf_map::
+find(const std::string & url) const
+{
+ openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
+ map_t::const_iterator pos = this->map_.find(url);
+ return pos == this->map_.end()
+ ? boost::shared_ptr<plugin_streambuf>()
+ : pos->second;
+}
+
+void
+openvrml_control::uninitialized_plugin_streambuf_map::
+insert(const std::string & url,
+ const boost::shared_ptr<plugin_streambuf> & streambuf)
+{
+ openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
+ this->map_.insert(make_pair(url, streambuf));
+}
+
+struct openvrml_control::uninitialized_plugin_streambuf_map::map_entry_matches_streambuf :
+ std::unary_function<bool, map_t::value_type> {
+
+ explicit map_entry_matches_streambuf(const plugin_streambuf * streambuf):
+ streambuf_(streambuf)
+ {}
+
+ bool operator()(const map_t::value_type & entry) const
+ {
+ return this->streambuf_ == entry.second.get();
+ }
+
+private:
+ const plugin_streambuf * const streambuf_;
+};
+
+bool
+openvrml_control::uninitialized_plugin_streambuf_map::
+erase(const plugin_streambuf & streambuf)
+{
+ openvrml::read_write_mutex::scoped_read_write_lock lock(this->mutex_);
+ const map_t::iterator pos =
+ std::find_if(this->map_.begin(), this->map_.end(),
+ map_entry_matches_streambuf(&streambuf));
+ if (pos == this->map_.end()) { return false; }
+ lock.promote();
+ this->map_.erase(pos);
+ return true;
+}
+
+size_t openvrml_control::uninitialized_plugin_streambuf_map::size() const
+{
+ openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
+ return this->map_.size();
+}
+
+bool openvrml_control::uninitialized_plugin_streambuf_map::empty() const
+{
+ openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
+ return this->map_.empty();
+}
+
+const boost::shared_ptr<openvrml_control::plugin_streambuf>
+openvrml_control::uninitialized_plugin_streambuf_map::front() const
+{
+ openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
+ assert(!this->map_.empty());
+ return this->map_.begin()->second;
+}
+
+
+const boost::shared_ptr<openvrml_control::plugin_streambuf>
+openvrml_control::plugin_streambuf_map::find(const size_t id) const
+{
+ openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
+ map_t::const_iterator pos = this->map_.find(id);
+ return pos == this->map_.end()
+ ? boost::shared_ptr<plugin_streambuf>()
+ : pos->second;
+}
+
+bool
+openvrml_control::plugin_streambuf_map::
+insert(const size_t id,
+ const boost::shared_ptr<plugin_streambuf> & streambuf)
+{
+ openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
+ return this->map_.insert(make_pair(id, streambuf)).second;
+}
+
+/**
+ * @brief Erase the entry corresponding to @p id.
+ *
+ * @return @c true if an entry was removed; @c false otherwise.
+ */
+bool openvrml_control::plugin_streambuf_map::erase(const size_t id)
+{
+ openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
+ return this->map_.erase(id) > 0;
+}
Property changes on: trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.cpp
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:mergeinfo
+ /branches/0.17/src/openvrml-xembed/plugin_streambuf.cpp:3713,3717,3719,3721,3725,3730,3732,3743,3746,3748,3750,3752,3754,3757,3759-3760,3764,3766,3824,3828,3836
/branches/local/src/openvrml-xembed/plugin_streambuf.cpp:3677-3689
/branches/node-modules/src/openvrml-xembed/plugin_streambuf.cpp:3622-3623,3632-3635,3637-3638,3640-3641,3643-3644,3646-3647,3649-3650,3654-3655,3657-3658,3661-3662,3664-3665,3667-3668,3670-3671,3673-3674,3684-3685,3687-3688,3736-3801
Added: svn:eol-style
+ native
Copied: trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.h (from rev 3846, trunk/src/openvrml-xembed/plugin_streambuf.h)
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.h (rev 0)
+++ trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.h 2009-03-19 05:27:10 UTC (rev 3848)
@@ -0,0 +1,163 @@
+// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
+//
+// OpenVRML Control
+//
+// Copyright 2004, 2005, 2006, 2007, 2008 Braden N. McDaniel
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program 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. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+
+# ifndef OPENVRML_CONTROL_PLUGIN_STREAMBUF_H
+# define OPENVRML_CONTROL_PLUGIN_STREAMBUF_H
+
+# include <map>
+# include <streambuf>
+# include <boost/noncopyable.hpp>
+# include <boost/shared_ptr.hpp>
+# include <boost/enable_shared_from_this.hpp>
+# include <openvrml/read_write_mutex.h>
+# include "bounded_buffer.h"
+
+namespace openvrml_control {
+
+ //
+ // plugin_streambuf Life Cycle
+ //
+ // A plugin_streambuf is first created in GtkVrmlBrowser's
+ // resource_fetcher::do_get_resource implementation (which is
+ // called whenever libopenvrml needs to load a stream).
+ //
+ // Step 1: Requested plugin_streambuf
+ //
+ // Upon creation, the plugin_streambuf is inserted into the
+ // unintialized_plugin_streambuf_map with an initial
+ // plugin_streambuf::state of requested. do_get_resource does not
+ // complete until the result of asking the host application to resolve the
+ // URL is known; i.e., plugin_streambuf::get_url_result. get_url_result
+ // blocks until the response is received from the host application; i.e.,
+ // until plugin_streambuf::set_get_url_result has been called.
+ //
+ // Step 2: Uninitialized plugin_streambuf
+ //
+ // If plugin_streambuf::set_get_url_result is given a result code
+ // indicating success (i.e., 0), the plugin_streambuf::state is changed to
+ // uninitialized (otherwise, the stream is removed from the
+ // uninitialized_plugin_streambuf_map and we're done). When
+ // openvrml_xembed_stream_client_new_stream is called on the
+ // GtkVrmlBrowser, a plugin_streambuf matching that URL is gotten from the
+ // uninitialized_plugin_streambuf_map and plugin_streambuf::init is called
+ // on it. init removes the plugin_streambuf from the
+ // uninitialized_plugin_streambuf_map_ and inserts it in the
+ // plugin_streambuf_map with a plugin_streambuf::state of initialized.
+ //
+ // Step 3: Initialized plugin_streambuf (plugin_streambuf_map)
+ //
+ // The plugin_streambuf_map comprises plugin_streambufs that are being
+ // written to in response to openvrml_xembed_stream_client_write calls and
+ // read from by stream readers in libopenvrml. Once the host is done
+ // calling openvrml_xembed_stream_client_write for a stream, it is
+ // expected that it will call
+ // openvrml_xembed_stream_client_destroy_stream. In response to this
+ // call, bounded_buffer<>::set_eof is called on the plugin_streambuf's
+ // underlying bounded_buffer<> and the plugin_streambuf is removed from
+ // the plugin_streambuf_map.
+ //
+ // Once the last reference to the resource_istream corresponding
+ // to the plugin_streambuf is removed, the plugin_streambuf is
+ // deleted.
+ //
+
+ class browser;
+
+ class uninitialized_plugin_streambuf_map;
+ class plugin_streambuf_map;
+
+ class plugin_streambuf :
+ public boost::enable_shared_from_this<plugin_streambuf>,
+ public std::streambuf {
+
+ friend class openvrml_control::browser;
+
+ public:
+ enum state_id {
+ requested,
+ uninitialized,
+ initialized
+ };
+
+ private:
+ state_id state_;
+ mutable boost::mutex mutex_;
+ int get_url_result_;
+ mutable boost::condition received_get_url_result_;
+ mutable boost::condition streambuf_initialized_or_failed_;
+ std::string url_;
+ std::string type_;
+ bounded_buffer<char_type, 16384> buf_;
+ int_type i_;
+ char_type c_;
+ uninitialized_plugin_streambuf_map & uninitialized_map_;
+ plugin_streambuf_map & map_;
+
+ protected:
+ virtual int_type underflow();
+
+ public:
+ plugin_streambuf(const std::string & requested_url,
+ uninitialized_plugin_streambuf_map & uninitialized_map,
+ plugin_streambuf_map & map);
+ state_id state() const;
+ void set_get_url_result(int result);
+ void init(size_t stream_id,
+ const std::string & received_url,
+ const std::string & type);
+ void fail();
+ const std::string & url() const;
+ const std::string & type() const;
+ bool data_available() const;
+ };
+
+ class uninitialized_plugin_streambuf_map : boost::noncopyable {
+ struct map_entry_matches_streambuf;
+
+ mutable openvrml::read_write_mutex mutex_;
+ typedef std::multimap<std::string, boost::shared_ptr<plugin_streambuf> >
+ map_t;
+ map_t map_;
+
+ public:
+ const boost::shared_ptr<plugin_streambuf>
+ find(const std::string & url) const;
+ void insert(const std::string & url,
+ const boost::shared_ptr<plugin_streambuf> & streambuf);
+ bool erase(const plugin_streambuf & streambuf);
+ size_t size() const;
+ bool empty() const;
+ const boost::shared_ptr<plugin_streambuf> front() const;
+ };
+
+ class plugin_streambuf_map : boost::noncopyable {
+ mutable openvrml::read_write_mutex mutex_;
+ typedef std::map<size_t, boost::shared_ptr<plugin_streambuf> > map_t;
+ map_t map_;
+
+ public:
+ const boost::shared_ptr<plugin_streambuf> find(size_t id) const;
+ bool insert(size_t id,
+ const boost::shared_ptr<plugin_streambuf> & streambuf);
+ bool erase(size_t id);
+ };
+}
+
+# endif // ifndef OPENVRML_CONTROL_PLUGIN_STREAMBUF_H
Property changes on: trunk/src/libopenvrml-control/openvrml_control/plugin_streambuf.h
___________________________________________________________________
Added: svn:keywords
+ Author Date Id Revision
Added: svn:mergeinfo
+
Added: svn:eol-style
+ native
Deleted: trunk/src/openvrml-xembed/bounded_buffer.h
===================================================================
--- trunk/src/openvrml-xembed/bounded_buffer.h 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/openvrml-xembed/bounded_buffer.h 2009-03-19 05:27:10 UTC (rev 3848)
@@ -1,116 +0,0 @@
-// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
-//
-// OpenVRML XEmbed Control
-//
-// Copyright 2004, 2005, 2006, 2007 Braden McDaniel
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program 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. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; if not, see <http://www.gnu.org/licenses/>.
-//
-
-# ifndef OPENVRML_XEMBED_BOUNDED_BUFFER_H
-# define OPENVRML_XEMBED_BOUNDED_BUFFER_H
-
-# include <cassert>
-# include <string>
-# include <boost/thread/mutex.hpp>
-# include <boost/thread/condition.hpp>
-
-namespace openvrml_xembed {
-
- template <typename CharT, size_t BufferSize>
- class bounded_buffer {
- mutable boost::mutex mutex_;
- boost::condition buffer_not_full_, buffer_not_empty_or_eof_;
-
- CharT buf_[BufferSize];
- size_t begin_, end_, buffered_;
- bool eof_;
-
- public:
- typedef CharT char_type;
- typedef typename std::char_traits<char_type> traits_type;
- typedef typename traits_type::int_type int_type;
-
- bounded_buffer();
- void put(const char_type & c);
- int_type get();
- size_t buffered() const;
- void set_eof();
- bool eof() const;
- };
-
- template <typename CharT, size_t BufferSize>
- bounded_buffer<CharT, BufferSize>::bounded_buffer():
- begin_(0),
- end_(0),
- buffered_(0),
- eof_(false)
- {}
-
- template <typename CharT, size_t BufferSize>
- void bounded_buffer<CharT, BufferSize>::put(const char_type & c)
- {
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->buffered_ == BufferSize) {
- this->buffer_not_full_.wait(lock);
- }
- this->buf_[this->end_] = c;
- this->end_ = (this->end_ + 1) % BufferSize;
- ++this->buffered_;
- this->buffer_not_empty_or_eof_.notify_one();
- }
-
- template <typename CharT, size_t BufferSize>
- typename bounded_buffer<CharT, BufferSize>::int_type
- bounded_buffer<CharT, BufferSize>::get()
- {
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->buffered_ == 0 && !this->eof_) {
- this->buffer_not_empty_or_eof_.wait(lock);
- }
- if (this->buffered_ == 0 && this->eof_) {
- return traits_type::eof();
- }
- const int_type c = traits_type::to_int_type(this->buf_[this->begin_]);
- this->begin_ = (this->begin_ + 1) % BufferSize;
- --this->buffered_;
- this->buffer_not_full_.notify_one();
- assert(!traits_type::eq_int_type(c, traits_type::eof()));
- return c;
- }
-
- template <typename CharT, size_t BufferSize>
- size_t bounded_buffer<CharT, BufferSize>::buffered() const
- {
- boost::mutex::scoped_lock lock(this->mutex_);
- return this->buffered_;
- }
-
- template <typename CharT, size_t BufferSize>
- void bounded_buffer<CharT, BufferSize>::set_eof()
- {
- boost::mutex::scoped_lock lock(this->mutex_);
- this->eof_ = true;
- this->buffer_not_empty_or_eof_.notify_one();
- }
-
- template <typename CharT, size_t BufferSize>
- bool bounded_buffer<CharT, BufferSize>::eof() const
- {
- boost::mutex::scoped_lock lock(this->mutex_);
- return this->eof_;
- }
-}
-
-# endif // ifndef OPENVRML_XEMBED_BOUNDED_BUFFER_H
Deleted: trunk/src/openvrml-xembed/plugin_streambuf.cpp
===================================================================
--- trunk/src/openvrml-xembed/plugin_streambuf.cpp 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/openvrml-xembed/plugin_streambuf.cpp 2009-03-19 05:27:10 UTC (rev 3848)
@@ -1,265 +0,0 @@
-// -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
-//
-// OpenVRML XEmbed Control
-//
-// Copyright 2004, 2005, 2006, 2007, 2008 Braden N. McDaniel
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program 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. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; if not, see <http://www.gnu.org/licenses/>.
-//
-
-# include <glib.h>
-# include "plugin_streambuf.h"
-
-openvrml_xembed::plugin_streambuf::
-plugin_streambuf(const std::string & requested_url,
- uninitialized_plugin_streambuf_map & uninitialized_map,
- plugin_streambuf_map & map):
- state_(requested),
- get_url_result_(-1),
- url_(requested_url),
- i_(0),
- c_('\0'),
- uninitialized_map_(uninitialized_map),
- map_(map)
-{
- //
- // This is really just here to emphasize that c_ must not be EOF.
- //
- this->i_ = traits_type::not_eof(this->i_);
- this->c_ =
- traits_type::to_char_type(
- traits_type::not_eof(traits_type::to_int_type(this->c_)));
-
- this->setg(&this->c_, &this->c_, &this->c_);
-}
-
-openvrml_xembed::plugin_streambuf::state_id
-openvrml_xembed::plugin_streambuf::state() const
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- return this->state_;
-}
-
-void openvrml_xembed::plugin_streambuf::set_get_url_result(const int result)
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- g_assert(this->get_url_result_ == -1);
- this->get_url_result_ = result;
-
- //
- // If result is nonzero, the resource fetch failed early (i.e., before
- // actually getting the stream. In that case, nothing else should be
- // playing with this. Removing this streambuf from uninitialized_map_
- // below may (and probably will) result in destruction of this instance.
- //
- // So, anyone waiting on received_get_url_result_ should be doing so
- // because the fetching code is trying to do something with this streambuf
- // because the fetch is in-progress (i.e., succeeding). If you're waiting
- // on this condition and result could possibly indicate failure, you're
- // doing it wrong.
- //
- if (result == 0) {
- this->state_ = plugin_streambuf::uninitialized;
- this->received_get_url_result_.notify_all();
- } else {
- this->uninitialized_map_.erase(*this);
- }
-}
-
-void openvrml_xembed::plugin_streambuf::init(const size_t stream_id,
- const std::string & received_url,
- const std::string & type)
-{
- g_assert(stream_id);
- g_assert(!received_url.empty());
- g_assert(!type.empty());
-
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->state_ != plugin_streambuf::uninitialized) {
- this->received_get_url_result_.wait(lock);
- }
-
- g_assert(this->state_ == uninitialized);
-
- bool succeeded = this->uninitialized_map_.erase(*this);
- g_assert(succeeded);
- this->url_ = received_url;
- this->type_ = type;
- this->state_ = plugin_streambuf::initialized;
- const boost::shared_ptr<plugin_streambuf> this_ = shared_from_this();
- succeeded = this->map_.insert(stream_id, this_);
- g_assert(succeeded);
- this->streambuf_initialized_or_failed_.notify_all();
-}
-
-void openvrml_xembed::plugin_streambuf::fail()
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- const bool succeeded = this->uninitialized_map_.erase(*this);
- g_assert(succeeded);
- this->buf_.set_eof();
- this->streambuf_initialized_or_failed_.notify_all();
-}
-
-const std::string & openvrml_xembed::plugin_streambuf::url() const
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->state_ != plugin_streambuf::initialized) {
- this->streambuf_initialized_or_failed_.wait(lock);
- }
- return this->url_;
-}
-
-const std::string & openvrml_xembed::plugin_streambuf::type() const
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->state_ != plugin_streambuf::initialized) {
- this->streambuf_initialized_or_failed_.wait(lock);
- }
- return this->type_;
-}
-
-bool openvrml_xembed::plugin_streambuf::data_available() const
-{
- //
- // It may seem a bit counterintuitive to return true here if the stream
- // has been destroyed; however, if we don't return true in this case,
- // clients may never get EOF from the stream.
- //
- return this->buf_.buffered() > 0 || this->buf_.eof();
-}
-
-openvrml_xembed::plugin_streambuf::int_type
-openvrml_xembed::plugin_streambuf::underflow()
-{
- boost::mutex::scoped_lock lock(this->mutex_);
- while (this->state_ != plugin_streambuf::initialized) {
- this->streambuf_initialized_or_failed_.wait(lock);
- }
-
- if (traits_type::eq_int_type(this->i_, traits_type::eof())) {
- return traits_type::eof();
- }
-
- this->i_ = this->buf_.get();
- this->c_ = traits_type::to_char_type(this->i_);
-
- if (traits_type::eq_int_type(this->i_, traits_type::eof())) {
- return traits_type::eof();
- }
-
- this->setg(&this->c_, &this->c_, &this->c_ + 1);
- return traits_type::to_int_type(*this->gptr());
-}
-
-const boost::shared_ptr<openvrml_xembed::plugin_streambuf>
-openvrml_xembed::uninitialized_plugin_streambuf_map::
-find(const std::string & url) const
-{
- openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
- map_t::const_iterator pos = this->map_.find(url);
- return pos == this->map_.end()
- ? boost::shared_ptr<plugin_streambuf>()
- : pos->second;
-}
-
-void
-openvrml_xembed::uninitialized_plugin_streambuf_map::
-insert(const std::string & url,
- const boost::shared_ptr<plugin_streambuf> & streambuf)
-{
- openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
- this->map_.insert(make_pair(url, streambuf));
-}
-
-struct openvrml_xembed::uninitialized_plugin_streambuf_map::map_entry_matches_streambuf :
- std::unary_function<bool, map_t::value_type> {
-
- explicit map_entry_matches_streambuf(const plugin_streambuf * streambuf):
- streambuf_(streambuf)
- {}
-
- bool operator()(const map_t::value_type & entry) const
- {
- return this->streambuf_ == entry.second.get();
- }
-
-private:
- const plugin_streambuf * const streambuf_;
-};
-
-bool
-openvrml_xembed::uninitialized_plugin_streambuf_map::
-erase(const plugin_streambuf & streambuf)
-{
- openvrml::read_write_mutex::scoped_read_write_lock lock(this->mutex_);
- const map_t::iterator pos =
- std::find_if(this->map_.begin(), this->map_.end(),
- map_entry_matches_streambuf(&streambuf));
- if (pos == this->map_.end()) { return false; }
- lock.promote();
- this->map_.erase(pos);
- return true;
-}
-
-size_t openvrml_xembed::uninitialized_plugin_streambuf_map::size() const
-{
- openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
- return this->map_.size();
-}
-
-bool openvrml_xembed::uninitialized_plugin_streambuf_map::empty() const
-{
- openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
- return this->map_.empty();
-}
-
-const boost::shared_ptr<openvrml_xembed::plugin_streambuf>
-openvrml_xembed::uninitialized_plugin_streambuf_map::front() const
-{
- openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
- g_assert(!this->map_.empty());
- return this->map_.begin()->second;
-}
-
-
-const boost::shared_ptr<openvrml_xembed::plugin_streambuf>
-openvrml_xembed::plugin_streambuf_map::find(const size_t id) const
-{
- openvrml::read_write_mutex::scoped_read_lock lock(this->mutex_);
- map_t::const_iterator pos = this->map_.find(id);
- return pos == this->map_.end()
- ? boost::shared_ptr<plugin_streambuf>()
- : pos->second;
-}
-
-bool
-openvrml_xembed::plugin_streambuf_map::
-insert(const size_t id,
- const boost::shared_ptr<plugin_streambuf> & streambuf)
-{
- openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
- return this->map_.insert(make_pair(id, streambuf)).second;
-}
-
-/**
- * @brief Erase the entry corresponding to @p id.
- *
- * @return @c true if an entry was removed; @c false otherwise.
- */
-bool openvrml_xembed::plugin_streambuf_map::erase(const size_t id)
-{
- openvrml::read_write_mutex::scoped_write_lock lock(this->mutex_);
- return this->map_.erase(id) > 0;
-}
Deleted: trunk/src/openvrml-xembed/plugin_streambuf.h
===================================================================
--- trunk/src/openvrml-xembed/plugin_streambuf.h 2009-03-19 04:53:28 UTC (rev 3847)
+++ trunk/src/openvrml-xembed/plugin_streambuf.h 2009-03-19 05:27:10 UTC (rev 3848)
@@ -1,165 +0,0 @@
-// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
-//
-// OpenVRML XEmbed Control
-//
-// Copyright 2004, 2005, 2006, 2007, 2008 Braden N. McDaniel
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 3 of the License, or (at your option)
-// any later version.
-//
-// This program 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. See the GNU General Public License for
-// more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this library; if not, see <http://www.gnu.org/licenses/>.
-//
-
-# ifndef OPENVRML_XEMBED_PLUGIN_STREAMBUF_H
-# define OPENVRML_XEMBED_PLUGIN_STREAMBUF_H
-
-# include <map>
-# include <streambuf>
-# include <boost/noncopyable.hpp>
-# include <boost/shared_ptr.hpp>
-# include <boost/enable_shared_from_this.hpp>
-# include <openvrml/read_write_mutex.h>
-# include "bounded_buffer.h"
-
-namespace openvrml_control {
- class browser;
-}
-
-namespace openvrml_xembed {
-
- //
- // plugin_streambuf Life Cycle
- //
- // A plugin_streambuf is first created in GtkVrmlBrowser's
- // resource_fetcher::do_get_resource implementation (which is
- // called whenever libopenvrml needs to load a stream).
- //
- // Step 1: Requested plugin_streambuf
- //
- // Upon creation, the plugin_streambuf is inserted into the
- // unintialized_plugin_streambuf_map with an initial
- // plugin_streambuf::state of requested. do_get_resource does not
- // complete until the result of asking the host application to resolve the
- // URL is known; i.e., plugin_streambuf::get_url_result. get_url_result
- // blocks until the response is received from the host application; i.e.,
- // until plugin_streambuf::set_get_url_result has been called.
- //
- // Step 2: Uninitialized plugin_streambuf
- //
- // If plugin_streambuf::set_get_url_result is given a result code
- // indicating success (i.e., 0), the plugin_streambuf::state is changed to
- // uninitialized (otherwise, the stream is removed from the
- // uninitialized_plugin_streambuf_map and we're done). When
- // openvrml_xembed_stream_client_new_stream is called on the
- // GtkVrmlBrowser, a plugin_streambuf matching that URL is gotten from the
- // uninitialized_plugin_streambuf_map and plugin_streambuf::init is called
- // on it. init removes the plugin_streambuf from the
- // uninitialized_plugin_streambuf_map_ and inserts it in the
- // plugin_streambuf_map with a plugin_streambuf::state of initialized.
- //
- // Step 3: Initialized plugin_streambuf (plugin_streambuf_map)
- //
- // The plugin_streambuf_map comprises plugin_streambufs that are being
- // written to in response to openvrml_xembed_stream_client_write calls and
- // read from by stream readers in libopenvrml. Once the host is done
- // calling openvrml_xembed_stream_client_write for a stream, it is
- // expected that it will call
- // openvrml_xembed_stream_client_destroy_stream. In response to this
- // call, bounded_buffer<>::set_eof is called on the plugin_streambuf's
- // underlying bounded_buffer<> and the plugin_streambuf is removed from
- // the plugin_streambuf_map.
- //
- // Once the last reference to the resource_istream corresponding
- // to the plugin_streambuf is removed, the plugin_streambuf is
- // deleted.
- //
-
- class uninitialized_plugin_streambuf_map;
- class plugin_streambuf_map;
-
- class plugin_streambuf :
- public boost::enable_shared_from_this<plugin_streambuf>,
- public std::streambuf {
-
- friend class openvrml_control::browser;
-
- public:
- enum state_id {
- requested,
- uninitialized,
- initialized
- };
-
- private:
- state_id state_;
- mutable boost::mutex mutex_;
- int get_url_result_;
- mutable boost::condition received_get_url_result_;
- mutable boost::condition streambuf_initialized_or_failed_;
- std::string url_;
- std::string type_;
- bounded_buffer<char_type, 16384> buf_;
- int_type i_;
- char_type c_;
- uninitialized_plugin_streambuf_map & uninitialized_map_;
- plugin_streambuf_map & map_;
-
- protected:
- virtual int_type underflow();
-
- public:
- plugin_streambuf(const std::string & requested_url,
- uninitialized_plugin_streambuf_map & uninitialized_map,
- plugin_streambuf_map & map);
- state_id state() const;
- void set_get_url_result(int result);
- void init(size_t stream_id,
- const std::string & received_url,
- const std::string & type);
- void fail();
- const std::string & url() const;
- const std::string & type() const;
- bool data_available() const;
- };
-
- class uninitialized_plugin_streambuf_map : boost::noncopyable {
- struct map_entry_matches_streambuf;
-
- mutable openvrml::read_write_mutex mutex_;
- typedef std::multimap<std::string, boost::shared_ptr<plugin_streambuf> >
- map_t;
- map_t map_;
-
- public:
- const boost::shared_ptr<plugin_streambuf>
- find(const std::string & url) const;
- void insert(const std::string & url,
- const boost::shared_ptr<plugin_streambuf> & streambuf);
- bool erase(const plugin_streambuf & streambuf);
- size_t size() const;
- bool empty() const;
- const boost::shared_ptr<plugin_streambuf> front() const;
- };
-
- class plugin_streambuf_map : boost::noncopyable {
- mutable openvrml::read_write_mutex mutex_;
- typedef std::map<size_t, boost::shared_ptr<plugin_streambuf> > map_t;
- map_t map_;
-
- public:
- const boost::shared_ptr<plugin_streambuf> find(size_t id) const;
- bool insert(size_t id,
- const boost::shared_ptr<plugin_streambuf> & streambuf);
- bool erase(size_t id);
- };
-}
-
-# endif // ifndef OPENVRML_XEMBED_PLUGIN_STREAMBUF_H
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|