Sierra Toolkit  Version of the Day
TeeStreambuf.hpp
1 /*------------------------------------------------------------------------*/
2 /* Copyright 2010 Sandia Corporation. */
3 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */
4 /* license for use of this work by or on behalf of the U.S. Government. */
5 /* Export of this program may require a license from the */
6 /* United States Government. */
7 /*------------------------------------------------------------------------*/
8 
9 #ifndef STK_UTIL_UTIL_TEESTREAMBUF_HPP
10 #define STK_UTIL_UTIL_TEESTREAMBUF_HPP
11 
12 #include <string>
13 #include <streambuf>
14 #include <ostream>
15 #include <set>
16 #include <map>
17 
18 namespace stk_classic {
19 
27 template<class Ch, class Tr = std::char_traits<Ch> >
28 class basic_tee_streambuf : public std::basic_streambuf<Ch, Tr>
29 {
30  typedef std::set<std::ostream *> StreamSet;
31  typedef std::map<std::ostream *, int> StreamErrorMap;
32 
33 public:
39  {}
40 
46  explicit basic_tee_streambuf(std::basic_ostream<Ch, Tr> *os) {
47  add(os);
48  }
49 
55  {}
56 
62  int eof() {
63  return std::basic_streambuf<Ch, Tr>::traits_type::eof();
64  }
65 
72  void add(std::ostream *os) {
73  m_destinations.insert(os);
74  }
75 
83  void remove(std::ostream *os) {
84  m_destinations.erase(os);
85  }
86 
91  void clear() {
92  m_destinations.clear();
93  }
94 
95 private:
101  virtual int sync() {
102  if (m_destinations.empty())
103  return 1;
104 
105  StreamErrorMap return_code;
106 
107  for (StreamSet::const_iterator it = m_destinations.begin(); it != m_destinations.end(); ++it) {
108  if ((*it)->rdbuf() != this) {
109  int ret = (*it)->rdbuf()->pubsync();
110  return_code[*it] = ret;
111  }
112  }
113 
114  // Remove streambufs with errors
115  for (StreamSet::iterator it = m_destinations.begin(); it != m_destinations.end(); ++it)
116  if (return_code[*it] == eof())
117  m_destinations.erase(it);
118 
119  if (m_destinations.empty())
120  return 1;
121 
122  return 1;
123  }
124 
133  virtual typename std::basic_streambuf<Ch, Tr>::int_type overflow(const int c) {
134  if (m_destinations.empty())
135  return 1;
136 
137  StreamErrorMap return_code;
138 
139  for (StreamSet::const_iterator it = m_destinations.begin(); it != m_destinations.end(); ++it) {
140  int ret = (*it)->rdbuf()->sputc(c);
141  return_code[*it] = ret;
142  }
143 
144  // Remove streambufs with errors
145  for (StreamSet::iterator it = m_destinations.begin(); it != m_destinations.end(); ++it)
146  if (return_code[*it] == eof())
147  m_destinations.erase(it);
148 
149  if (m_destinations.empty())
150  return 1;
151 
152  return 1;
153  }
154 
164  virtual std::streamsize xsputn(char const *buffer, std::streamsize n) {
165  if (m_destinations.empty())
166  return n;
167 
168  StreamErrorMap return_code;
169 
170  for (StreamSet::const_iterator it = m_destinations.begin(); it != m_destinations.end(); ++it) {
171  std::ostream *os = (*it);
172  int ret = os->rdbuf()->sputn(buffer,n);
173  return_code[*it] = ret;
174  }
175 
176  // Remove ostreams with errors
177  for (StreamSet::iterator it = m_destinations.begin(); it != m_destinations.end(); ++it) {
178  if (return_code[*it] < 0) {
179  m_destinations.erase(it);
180  }
181  }
182 
183  if (m_destinations.empty())
184  return n;
185 
186  return n;
187  }
188 
189 private:
190  StreamSet m_destinations;
191 };
192 
194 
195 } // namespace stk_classic
196 
197 #endif // STK_UTIL_UTIL_TEESTREAMBUF_HPP
stk_classic::basic_tee_streambuf< char, std::char_traits< char > > tee_streambuf
Tee stream buffer for char.
Definition: OutputLog.hpp:20
Class basic_tee_streambuf maintains a list of destination output stream buffers to send written chara...
Definition: OutputLog.hpp:20
void clear()
Member function clear removes are destination output stream buffers.
int eof()
Member function eof returns the current end-of-file status.
Sierra Toolkit.
void add(std::ostream *os)
Member function add adds the specified destination output stream buffer.
basic_tee_streambuf(std::basic_ostream< Ch, Tr > *os)