source: trunk/yat/utility/StreamRedirect.h @ 2048

Last change on this file since 2048 was 2048, checked in by Peter, 12 years ago

adding bool parameter in constructors and fixed some docs typos

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.5 KB
Line 
1#ifndef _theplu_yat_utility_stream_readirect_
2#define _theplu_yat_utility_stream_readirect_
3
4// $Id: StreamRedirect.h 2048 2009-09-04 14:47:18Z peter $
5
6/*
7  Copyright (C) 2009 Peter Johansson
8
9  This file is part of the yat library, http://dev.thep.lu.se/yat
10
11  The yat library is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 3 of the
14  License, or (at your option) any later version.
15
16  The yat library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with yat. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include "yat_assert.h"
26
27#include <istream>
28#include <ostream>
29#include <streambuf>
30
31namespace theplu {
32namespace yat {
33namespace utility {
34
35  /**
36     \brief Redirect a stream to another stream.
37
38     
39
40     \note It is important that an instance of this class is
41     deallocated before the stream it holds (see
42     BasicStreamRedirect::~BasicStreamRedirect).
43
44     \see StreamRedirect and wStreamRedirect
45
46     \since New in yat 0.6
47   */
48  template<class charT, class traits = std::char_traits<charT> >
49  class BasicStreamRedirect
50  {
51  public:
52    /**
53       Constructor for ostream
54
55       \a is1 is redirected to get its input from the buffer of \a is2
56       (rather than its own buffer). A reference to \a is1 and its
57       buffer is stored, so \a is1 can be restored in the destructor.
58
59       If \a active is false, the class does nothing.
60     */
61    BasicStreamRedirect(std::basic_istream<charT, traits>& is1, 
62                        std::basic_istream<charT, traits>& is2,
63                        bool active=true);
64   
65    /**
66       Constructor for istream
67
68       \a os1 is redirected to send its output to the buffer of \a os2
69       (rather than its own buffer). A reference to \a os1 and its
70       buffer is stored, so \a os1 can be restored in the destructor.
71
72       If \a active is false, the class does nothing.
73    */
74    BasicStreamRedirect(std::basic_ostream<charT, traits>& os1, 
75                        std::basic_ostream<charT, traits>& os2,
76                        bool active=true);
77   
78    /**
79       \brief Destructor - resets the redirect
80
81       The stream (first argument in constructor) is restored to use
82       its original buffer.
83
84       \note It is important that the stream held is not deallocated
85       before this object is destroyed. 1) The behavior of this
86       destructor is undefined. 2) The stream destroys the streambuf
87       in its destructor, so if the stream is destroyed before it is
88       restored, the streambuf will likely be deallocated twice. In
89       addition, the original streambuf of the stream will not be
90       closed and deallocated; hence a memory and resource leak.
91    */
92    ~BasicStreamRedirect(void);
93   
94  private:
95    // no copying
96    BasicStreamRedirect(const BasicStreamRedirect&);
97    BasicStreamRedirect& operator=(const BasicStreamRedirect&);
98   
99    void init(std::basic_ios<charT, traits>& ios1, 
100              std::basic_ios<charT, traits>& ios2,
101              bool active);
102   
103    std::basic_ios<charT, traits>* ios_;
104    std::basic_streambuf<charT, traits>* buf_;
105  };
106 
107  /**
108     \since New in yat 0.6
109  */
110  typedef BasicStreamRedirect<char> StreamRedirect;
111 
112  /**
113     \since New in yat 0.6
114  */
115  typedef BasicStreamRedirect<wchar_t> wStreamRedirect;
116 
117 
118  // template implementations
119 
120  template<class charT, class traits>
121  BasicStreamRedirect<charT, traits>::
122  BasicStreamRedirect(std::basic_istream<charT, traits>& is1, 
123                      std::basic_istream<charT, traits>& is2, bool active)
124  {
125    init(is1, is2, active);
126  }
127 
128 
129  template<class charT, class traits>
130  BasicStreamRedirect<charT, traits>::
131  BasicStreamRedirect(std::basic_ostream<charT, traits>& os1, 
132                      std::basic_ostream<charT, traits>& os2, bool active)
133  {
134    init(os1, os2, active);
135  }
136 
137 
138  template<class charT, class traits>
139  BasicStreamRedirect<charT, traits>::
140  ~BasicStreamRedirect(void)
141  {
142    // only restore stream if active is true
143    if (ios_) {
144      ios_->rdbuf(buf_);
145    }
146  }
147 
148 
149  template<class charT, class traits>
150  void 
151  BasicStreamRedirect<charT, traits>::init(std::basic_ios<charT, traits>& s1, 
152                                           std::basic_ios<charT, traits>& s2,
153                                           bool active)
154  {
155    if (active) {
156      ios_ = &s1;
157      // save the buffer
158      buf_ = ios_->rdbuf();
159      // redirect os1 to os2
160      ios_->rdbuf(s2.rdbuf());
161    }
162    else {
163      ios_ = NULL;
164      buf_ = NULL;
165    }
166  }
167 
168}}} // of namespace utility, yat, and theplu
169
170#endif
Note: See TracBrowser for help on using the repository browser.