Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

mostream.hh

00001 /*===========================================================================*\
00002  *                                                                           *
00003  *                               OpenMesh                                    *
00004  *      Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen      *
00005  *                           www.openmesh.org                                *
00006  *                                                                           *
00007  *---------------------------------------------------------------------------* 
00008  *                                                                           *
00009  *                                License                                    *
00010  *                                                                           *
00011  *  This library is free software; you can redistribute it and/or modify it  *
00012  *  under the terms of the GNU Library General Public License as published   *
00013  *  by the Free Software Foundation, version 2.                              *
00014  *                                                                           *
00015  *  This library is distributed in the hope that it will be useful, but      *
00016  *  WITHOUT ANY WARRANTY; without even the implied warranty of               *
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
00018  *  Library General Public License for more details.                         *
00019  *                                                                           *
00020  *  You should have received a copy of the GNU Library General Public        *
00021  *  License along with this library; if not, write to the Free Software      *
00022  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                *
00023  *                                                                           *
00024 \*===========================================================================*/
00025 
00026 //=============================================================================
00027 //
00028 //  multiplex streams & ultilities
00029 //
00030 //=============================================================================
00031 
00032 #ifndef OPENMESH_MOSTREAM_HH
00033 #define OPENMESH_MOSTREAM_HH
00034 
00035 
00036 //== INCLUDES =================================================================
00037 
00038 #include <OpenMesh/Core/System/config.hh>
00039 #include <iostream>
00040 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00041 #  include <streambuf.h>
00042 #else
00043 #  include <streambuf>
00044 #endif
00045 #include <vector>
00046 #include <map>
00047 #include <string>
00048 #include <algorithm>
00049 
00050 
00051 //== NAMESPACES ===============================================================
00052 
00053 namespace OpenMesh {
00054 #ifndef DOXY_IGNORE_THIS
00055 
00056 
00057 //== CLASS DEFINITION =========================================================
00058 
00059 
00060 class basic_multiplex_target
00061 {
00062 public:
00063   virtual ~basic_multiplex_target() {}
00064   virtual void operator<<(const std::string& _s) = 0;
00065 };
00066 
00067 
00068 template <class T>
00069 class multiplex_target : public basic_multiplex_target
00070 {
00071 public:
00072   multiplex_target(T& _t) : target_(_t) {}
00073   virtual void operator<<(const std::string& _s) { target_ << _s; }
00074 private:
00075   T& target_;
00076 };
00077 
00078 
00079 
00080 //== CLASS DEFINITION =========================================================
00081 
00082 
00083 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00084 #  define STREAMBUF   streambuf
00085 #  define INT_TYPE    int
00086 #  define TRAITS_TYPE 
00087 #else
00088 #  define STREAMBUF std::basic_streambuf<char>
00089 #endif
00090 
00091 class multiplex_streambuf : public STREAMBUF
00092 {
00093 public:
00094 
00095   typedef STREAMBUF                   base_type;
00096 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00097   typedef int                         int_type;
00098   struct traits_type
00099   {
00100     static int_type eof() { return -1; }
00101     static char to_char_type(int_type c) { return char(c); }
00102   };
00103 #else
00104   typedef base_type::int_type         int_type;
00105   typedef base_type::traits_type      traits_type;
00106 #endif
00107 
00108   // Constructor
00109   multiplex_streambuf() : enabled_(true) { buffer_.reserve(100); }
00110 
00111   // Destructor
00112   ~multiplex_streambuf()
00113   {
00114     tmap_iter t_it(target_map_.begin()), t_end(target_map_.end());
00115     for (; t_it!=t_end; ++t_it)
00116       delete t_it->second;
00117   }
00118 
00119 
00120   // buffer enable/disable
00121   bool is_enabled() const { return enabled_; }
00122   void enable() { enabled_ = true; }
00123   void disable() { enabled_ = false; }
00124 
00125 
00126   // construct multiplex_target<T> and add it to targets
00127   template <class T> bool connect(T& _target) 
00128   {
00129     void* key = (void*) &_target;
00130 
00131     if (target_map_.find(key) != target_map_.end())
00132       return false;
00133 
00134     target_type*  mtarget = new multiplex_target<T>(_target);
00135     target_map_[key] = mtarget;
00136 
00137     __connect(mtarget); 
00138     return true;
00139   }
00140 
00141 
00142   // disconnect target from multiplexer
00143   template <class T> bool disconnect(T& _target) 
00144   {
00145     void*      key  = (void*) &_target;
00146     tmap_iter  t_it = target_map_.find(key);
00147 
00148     if (t_it != target_map_.end())
00149     {
00150       __disconnect(t_it->second);
00151       target_map_.erase(t_it);
00152       return true;
00153     }
00154 
00155     return false;
00156   }
00157 
00158 
00159 protected:
00160 
00161   // output what's in buffer_
00162   virtual int sync() 
00163   {
00164     if (!buffer_.empty())
00165     {
00166       if (enabled_) multiplex();
00167 #if defined(OM_CC_GCC) || OM_CC_VERSION < 30000
00168       buffer_ = ""; // member clear() not available!
00169 #else
00170       buffer_.clear();
00171 #endif
00172     }
00173     return base_type::sync();
00174   }
00175 
00176 
00177   // take on char and add it to buffer_
00178   // if '\n' is encountered, trigger a sync()
00179   virtual 
00180   int_type overflow(int_type _c = multiplex_streambuf::traits_type::eof())
00181   {
00182     char c = traits_type::to_char_type(_c);
00183     buffer_.push_back(c);
00184     if (c == '\n') sync();
00185     return 0;
00186   }
00187 
00188 
00189 private:
00190 
00191   typedef basic_multiplex_target          target_type;
00192   typedef std::vector<target_type*>       target_list;
00193   typedef target_list::iterator           tlist_iter;
00194   typedef std::map<void*, target_type*>   target_map;
00195   typedef target_map::iterator            tmap_iter;
00196 
00197 
00198   // add _target to list of multiplex targets
00199   void __connect(target_type* _target) { targets_.push_back(_target); }
00200 
00201 
00202   // remove _target from list of multiplex targets
00203   void __disconnect(target_type* _target) { 
00204     targets_.erase(std::find(targets_.begin(), targets_.end(), _target));
00205   }
00206 
00207 
00208   // multiplex output of buffer_ to all targets
00209   void multiplex()
00210   {
00211     tlist_iter t_it(targets_.begin()), t_end(targets_.end());
00212     for (; t_it!=t_end; ++t_it)
00213       **t_it << buffer_;
00214   }
00215 
00216 
00217 private:
00218 
00219   target_list  targets_;
00220   target_map   target_map_;
00221   std::string  buffer_;
00222   bool         enabled_;
00223 };
00224 
00225 #undef STREAMBUF
00226 
00227 
00228 //== CLASS DEFINITION =========================================================
00229 
00230 
00240 class mostream : public std::ostream
00241 {
00242 public:
00243 
00245   explicit mostream() : std::ostream(NULL) { init(&streambuffer_); }
00246 
00247 
00249   template <class T> bool connect(T& _target) 
00250   { 
00251     return streambuffer_.connect(_target); 
00252   }
00253 
00254 
00256   template <class T> bool disconnect(T& _target) 
00257   {
00258     return streambuffer_.disconnect(_target);
00259   }
00260 
00261 
00263   bool is_enabled() const { return streambuffer_.is_enabled(); }
00264 
00266   void enable() { streambuffer_.enable(); }
00267 
00269   void disable() { streambuffer_.disable(); }
00270 
00271 
00272 private:
00273   multiplex_streambuf  streambuffer_;
00274 };
00275 
00276 
00277 //=============================================================================
00278 #endif
00279 } // namespace OpenMesh
00280 //=============================================================================
00281 #endif // OPENMESH_MOSTREAM_HH defined
00282 //=============================================================================

acg pic Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .