charon-core  0.3.1
SplitStream.cpp
Go to the documentation of this file.
1 /* This file is part of Charon.
2 
3  Charon is free software: you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as published by
5  the Free Software Foundation, either version 3 of the License, or
6  (at your option) any later version.
7 
8  Charon is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU Lesser General Public License for more details.
12 
13  You should have received a copy of the GNU Lesser General Public License
14  along with Charon. If not, see <http://www.gnu.org/licenses/>.
15 */
23 #include <cassert>
24 #include <climits>
25 #include <cstdio>
26 #include <limits>
27 #include <stdexcept>
28 #include <sstream>
29 
30 SplitStreamBuf::SplitStreamBuf(const std::vector<std::streambuf*>& buffers) {
31  if (buffers.size() < 1) {
32  std::ostringstream msg;
33  msg << __FILE__ << ":" << __LINE__ << "\n\t";
34  msg << "Buffer must be initialized with at least one streambuf!";
35  throw std::invalid_argument(msg.str().c_str());
36  }
37  _buffers = buffers;
38 }
39 
40 SplitStreamBuf::~SplitStreamBuf() {
41 }
42 
44  if (c != EOF){
45  bool over = false;
46  char const cchar = traits_type::to_char_type(c);
47  for (unsigned int i=0; i < _buffers.size(); i++)
48  over = over || (_buffers[i]->sputc(cchar) == EOF);
49  if (over)
50  return EOF;
51  }
52  return traits_type::not_eof(c);
53 }
54 
55 std::streamsize SplitStreamBuf::xsputn(char const* str, std::streamsize size) {
56  std::streamsize min = std::numeric_limits<std::streamsize>::max();
57  for(unsigned int i=0; i < _buffers.size(); i++) {
58  std::streamsize temp = _buffers[i]->sputn(str, size);
59  if (temp < min)
60  min = temp;
61  }
62  return min;
63 }
64 
66  bool fail = false;
67  for (unsigned int i=0; i<_buffers.size(); i++) {
68  bool temp = ( _buffers[i]->pubsync() == -1 );
69  fail = fail || temp;
70  }
71 
72  if (fail)
73  return -1;
74  return 0;
75 }
76 
78 #ifdef UNIX
79  std::ostream(std::cout.rdbuf()),
80 #else
81  std::ostream(std::_Uninitialized()),
82 #endif
83  _buffers(0)
84 {
85 }
86 
87 SplitStream::SplitStream(std::ostream& stream) :
88  std::ostream(stream.rdbuf()) {
89  _buffers.push_back(stream.rdbuf());
90  assert(_buffers.size() == 1);
92  rdbuf(_buffer);
93  assert(rdbuf() == _buffer);
94 }
95 
96 SplitStream::SplitStream(std::ostream& stream1, std::ostream& stream2) :
97  std::ostream(std::cout.rdbuf()) {
98  _buffers.push_back(stream1.rdbuf());
99  _buffers.push_back(stream2.rdbuf());
100  assert(_buffers.size() == 2);
102  rdbuf(_buffer);
103  assert(rdbuf() == _buffer);
104 }
105 
106 SplitStream::SplitStream(std::vector<std::ostream*>& streamList) :
107  std::ostream(std::cout.rdbuf()) {
108  for(unsigned int i=0; i<streamList.size();i++)
109  _buffers.push_back(streamList[i]->rdbuf());
110  assert(_buffers.size() == streamList.size());
112  rdbuf(_buffer);
113  assert(rdbuf() == _buffer);
114 }
115 
117  if (_buffer) {
118  delete _buffer;
119  }
120 }
121 
122 void SplitStream::updateBuf(std::vector<std::streambuf*> buffers){
123  SplitStreamBuf* temp = new SplitStreamBuf(buffers);
124  rdbuf(temp);
125  if (_buffer) {
126  delete _buffer;
127  }
128  _buffer = temp;
129  assert(rdbuf() == _buffer);
130 }
131 
132 void SplitStream::assign(std::ostream& stream){
133  _buffers.clear();
134  init(stream.rdbuf());
135  _buffers.push_back(stream.rdbuf());
136  assert(_buffers.size() == 1);
137 }
138 
139 void SplitStream::assign(std::ostream& stream1, std::ostream &stream2){
140  _buffers.clear();
141  init(stream1.rdbuf());
142  _buffers.push_back(stream1.rdbuf());
143  _buffers.push_back(stream2.rdbuf());
144  assert(_buffers.size() == 2);
146 }
147 
148 void SplitStream::assign(std::vector<std::ostream*>& streamList){
149  _buffers.clear();
150  if (streamList.size() < 1) {
151  std::ostringstream msg;
152  msg << __FILE__ << ":" << __LINE__ << "\n\t";
153  msg << "You have to assign at least one output stream!";
154  throw std::invalid_argument(msg.str().c_str());
155  }
156  init(streamList[0]->rdbuf());
157  for(unsigned int i=0; i<streamList.size();i++)
158  _buffers.push_back(streamList[i]->rdbuf());
159  assert(_buffers.size() == streamList.size());
161 }
162 
SplitStreamBuf * _buffer
pointer to output stream buffer
Definition: SplitStream.h:105
This class wraps a list of output streams and pipes output made to a splitstream instance to all of t...
Definition: SplitStream.h:69
virtual ~SplitStream()
Default destructor.
SplitStream sout
Dummy instance for usage in other files (for interface too).
int sync()
Sync stream buffers.
Definition: SplitStream.cpp:65
void charon_core_LOCAL updateBuf(std::vector< std::streambuf * > buffers)
Set new buffers.
Buffer to split output on several streams.
Definition: SplitStream.h:32
charon_core_LOCAL SplitStreamBuf(const SplitStreamBuf &)
forbid copying
SplitStream()
Default constructor.
Definition: SplitStream.cpp:77
std::streamsize xsputn(char const *str, std::streamsize size)
Write sequence of characters.
Definition: SplitStream.cpp:55
int overflow(int c)
Write character in the case of overflow.
Definition: SplitStream.cpp:43
std::vector< std::streambuf * > _buffers
pointer to stream buffers
Definition: SplitStream.h:35
Declaration of class SplitStream.
std::vector< std::streambuf * > _buffers
buffer array
Definition: SplitStream.h:104