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
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #ifndef OPENMESH_MOSTREAM_HH
00049 #define OPENMESH_MOSTREAM_HH
00050
00051
00052
00053
00054 #include <OpenMesh/Core/System/config.h>
00055 #include <iostream>
00056 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00057 # include <streambuf.h>
00058 #else
00059 # include <streambuf>
00060 #endif
00061 #include <vector>
00062 #include <map>
00063 #include <string>
00064 #include <algorithm>
00065
00066
00067
00068
00069 namespace OpenMesh {
00070 #ifndef DOXY_IGNORE_THIS
00071
00072
00073
00074
00075
00076 class basic_multiplex_target
00077 {
00078 public:
00079 virtual ~basic_multiplex_target() {}
00080 virtual void operator<<(const std::string& _s) = 0;
00081 };
00082
00083
00084 template <class T>
00085 class multiplex_target : public basic_multiplex_target
00086 {
00087 public:
00088 multiplex_target(T& _t) : target_(_t) {}
00089 virtual void operator<<(const std::string& _s) { target_ << _s; }
00090 private:
00091 T& target_;
00092 };
00093
00094
00095
00096
00097
00098
00099 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00100 # define STREAMBUF streambuf
00101 # define INT_TYPE int
00102 # define TRAITS_TYPE
00103 #else
00104 # define STREAMBUF std::basic_streambuf<char>
00105 #endif
00106
00107 class multiplex_streambuf : public STREAMBUF
00108 {
00109 public:
00110
00111 typedef STREAMBUF base_type;
00112 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00113 typedef int int_type;
00114 struct traits_type
00115 {
00116 static int_type eof() { return -1; }
00117 static char to_char_type(int_type c) { return char(c); }
00118 };
00119 #else
00120 typedef base_type::int_type int_type;
00121 typedef base_type::traits_type traits_type;
00122 #endif
00123
00124
00125 multiplex_streambuf() : enabled_(true) { buffer_.reserve(100); }
00126
00127
00128 ~multiplex_streambuf()
00129 {
00130 tmap_iter t_it(target_map_.begin()), t_end(target_map_.end());
00131 for (; t_it!=t_end; ++t_it)
00132 delete t_it->second;
00133 }
00134
00135
00136
00137 bool is_enabled() const { return enabled_; }
00138 void enable() { enabled_ = true; }
00139 void disable() { enabled_ = false; }
00140
00141
00142
00143 template <class T> bool connect(T& _target)
00144 {
00145 void* key = (void*) &_target;
00146
00147 if (target_map_.find(key) != target_map_.end())
00148 return false;
00149
00150 target_type* mtarget = new multiplex_target<T>(_target);
00151 target_map_[key] = mtarget;
00152
00153 __connect(mtarget);
00154 return true;
00155 }
00156
00157
00158
00159 template <class T> bool disconnect(T& _target)
00160 {
00161 void* key = (void*) &_target;
00162 tmap_iter t_it = target_map_.find(key);
00163
00164 if (t_it != target_map_.end())
00165 {
00166 __disconnect(t_it->second);
00167 target_map_.erase(t_it);
00168 return true;
00169 }
00170
00171 return false;
00172 }
00173
00174
00175 protected:
00176
00177
00178 virtual int sync()
00179 {
00180 if (!buffer_.empty())
00181 {
00182 if (enabled_) multiplex();
00183 #if defined( OM_CC_GCC ) && OM_CC_VERSION < 30000
00184 buffer_ = "";
00185 #else
00186 buffer_.clear();
00187 #endif
00188 }
00189 return base_type::sync();
00190 }
00191
00192
00193
00194
00195 virtual
00196 int_type overflow(int_type _c = multiplex_streambuf::traits_type::eof())
00197 {
00198 char c = traits_type::to_char_type(_c);
00199 buffer_.push_back(c);
00200 if (c == '\n') sync();
00201 return 0;
00202 }
00203
00204
00205 private:
00206
00207 typedef basic_multiplex_target target_type;
00208 typedef std::vector<target_type*> target_list;
00209 typedef target_list::iterator tlist_iter;
00210 typedef std::map<void*, target_type*> target_map;
00211 typedef target_map::iterator tmap_iter;
00212
00213
00214
00215 void __connect(target_type* _target) { targets_.push_back(_target); }
00216
00217
00218
00219 void __disconnect(target_type* _target) {
00220 targets_.erase(std::find(targets_.begin(), targets_.end(), _target));
00221 }
00222
00223
00224
00225 void multiplex()
00226 {
00227 tlist_iter t_it(targets_.begin()), t_end(targets_.end());
00228 for (; t_it!=t_end; ++t_it)
00229 **t_it << buffer_;
00230 }
00231
00232
00233 private:
00234
00235 target_list targets_;
00236 target_map target_map_;
00237 std::string buffer_;
00238 bool enabled_;
00239 };
00240
00241 #undef STREAMBUF
00242
00243
00244
00245
00246
00256 class mostream : public std::ostream
00257 {
00258 public:
00259
00261 explicit mostream() : std::ostream(NULL) { init(&streambuffer_); }
00262
00263
00265 template <class T> bool connect(T& _target)
00266 {
00267 return streambuffer_.connect(_target);
00268 }
00269
00270
00272 template <class T> bool disconnect(T& _target)
00273 {
00274 return streambuffer_.disconnect(_target);
00275 }
00276
00277
00279 bool is_enabled() const { return streambuffer_.is_enabled(); }
00280
00282 void enable() { streambuffer_.enable(); }
00283
00285 void disable() { streambuffer_.disable(); }
00286
00287
00288 private:
00289 multiplex_streambuf streambuffer_;
00290 };
00291
00292
00293
00294 #endif
00295 }
00296
00297 #endif // OPENMESH_MOSTREAM_HH defined
00298