00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef OPENMESH_MOSTREAM_HH
00033 #define OPENMESH_MOSTREAM_HH
00034
00035
00036
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
00052
00053 namespace OpenMesh {
00054 #ifndef DOXY_IGNORE_THIS
00055
00056
00057
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
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
00109 multiplex_streambuf() : enabled_(true) { buffer_.reserve(100); }
00110
00111
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
00121 bool is_enabled() const { return enabled_; }
00122 void enable() { enabled_ = true; }
00123 void disable() { enabled_ = false; }
00124
00125
00126
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
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
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_ = "";
00169 #else
00170 buffer_.clear();
00171 #endif
00172 }
00173 return base_type::sync();
00174 }
00175
00176
00177
00178
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
00199 void __connect(target_type* _target) { targets_.push_back(_target); }
00200
00201
00202
00203 void __disconnect(target_type* _target) {
00204 targets_.erase(std::find(targets_.begin(), targets_.end(), _target));
00205 }
00206
00207
00208
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
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 }
00280
00281 #endif // OPENMESH_MOSTREAM_HH defined
00282