Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tee.cpp
Go to the documentation of this file.
1 #include <xstream/tee.h>
2 
3 #include <iostream>
4 #include <map>
5 
6 #include "debug.h"
7 
8 namespace xstream
9 {
10  namespace tee
11  {
12 
13  static const int eof = std::streambuf::traits_type::eof();
14 
15  void ostreambuf::add( std::streambuf* sb) {
16  LOG("tee::ostreambuf::add (streambuf*)");
17  destinations.insert(sb);
18  }
19 
20  void ostreambuf::add( std::ostream& os) {
21  LOG("tee::ostreambuf::add (ostream&)");
22  destinations.insert(os.rdbuf());
23  }
24 
25  void ostreambuf::remove( std::streambuf* sb) {
26  LOG("tee::ostreambuf::remove (streambuf*)");
27  destinations.erase(sb);
28  }
29 
30  void ostreambuf::remove( std::ostream& os) {
31  LOG("tee::ostreambuf::remove (ostream&)");
32  destinations.erase(os.rdbuf());
33  }
34 
36  LOG("tee::ostreambuf::sync");
37  if (0 == destinations.size()) {
38  return eof;
39  }
40 
41  std::map<std::streambuf*, int> return_code;
42 
43  std::set<std::streambuf*>::iterator it = destinations.begin();
44  for (; it != destinations.end(); it++) {
45  int ret = (*it)->pubsync();
46  return_code[*it] = ret;
47  }
48 
49  //remove streambufs with errors
50  //second go
51 
52  it = destinations.begin();
53  for (;it != destinations.end(); it++) {
54  if (eof == return_code[*it]) {
55  destinations.erase(it);
56  }
57  }
58 
59  if (0 == destinations.size()) {
60  return eof;
61  }
62 
63  return 0;
64  }
65 
67  LOG("tee::ostreambuf::overflow " << c);
68 
69  if (0 == destinations.size()) {
70  return eof;
71  }
72 
73  std::map<std::streambuf*, int> return_code;
74 
75  std::set<std::streambuf*>::iterator it = destinations.begin();
76  for (;it != destinations.end(); it++) {
77  int ret = (*it)->sputc(c);
78  return_code[*it] = ret;
79  }
80 
81  //remove streambufs with errors
82  //second go
83 
84  it = destinations.begin();
85  for (;it != destinations.end(); it++) {
86  if (eof==return_code[*it]) {
87  destinations.erase(it);
88  }
89  }
90 
91  if (0 == destinations.size()) {
92  return eof;
93  }
94 
95  return c;
96  }
97 
98  std::streamsize ostreambuf::xsputn(const char *buffer, std::streamsize n) {
99  LOG("tee::ostreambuf::xsputn " << buffer);
100 
101  if (0 == destinations.size()) {
102  return eof;
103  }
104 
105  std::map<std::streambuf*, int> return_code;
106 
107  std::set<std::streambuf*>::iterator it = destinations.begin();
108  for (;it != destinations.end(); it++) {
109  int ret = (*it)->sputn(buffer,n);
110  return_code[*it] = ret;
111  }
112 
113  //remove streambufs with errors
114  //second go
115 
116  it = destinations.begin();
117  for (;it != destinations.end(); it++) {
118  if (0 > return_code[*it]) {
119  destinations.erase(it);
120  }
121  }
122 
123  if (0 == destinations.size()) {
124  return eof;
125  }
126 
127  return n;
128  }
129 
131  //no need to delete anything
132  }
133 
134  } //namespace fork
135 } //namespace xstream
std::set< std::streambuf * > destinations
Definition: tee.h:40
debugging/logging support
#define c
int sync()
flush as much data as possible (overloaded from streambuf)
Definition: tee.cpp:35
C++ streambuf to fork output data written to it is also written to several other streambufs.
~ostreambuf()
closes the streambuf stream
Definition: tee.cpp:130
static const int eof
Definition: tee.cpp:13
void add(std::streambuf *sb)
add an output streembuf to write to
Definition: tee.cpp:15
void remove(std::streambuf *sb)
remove a streambuf to write to
Definition: tee.cpp:25
static const int eof
Definition: base64.cpp:14
std::streamsize xsputn(const char *buffer, std::streamsize n)
write an entire buffer (overloaded from streambuf)
Definition: tee.cpp:98
buffer management
Definition: common.h:46
int overflow(int c)
write a character that supasses buffer end (overloaded from streambuf)
Definition: tee.cpp:66
#define LOG(s)
Definition: debug.h:30