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

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

closes #520 and refs #521. Implements the interface defined in #520 which should be extended to also include the interface discussed in #521

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.1 KB
Line 
1#ifndef _theplu_yat_utility_stream_readirect_
2#define _theplu_yat_utility_stream_readirect_
3
4// $Id: StreamRedirect.h 2047 2009-09-04 00:16:03Z 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 (se StreamSwitcher~).
42
43     \see StreamSwitcher and wStreamSwitcher
44
45     \since New in yat 0.6
46   */
47  template<class charT, class traits = std::char_traits<charT> >
48  class BasicStreamRedirect
49  {
50  public:
51    /**
52       Constructor for ostream
53
54       \a is1 is redirected to get its input from the buffer of \a is2
55       (rather than its own buffer). A reference to \a is1 and its
56       buffer is stored, so \a is1 can be restored in the destructor.
57     */
58    BasicStreamRedirect(std::basic_istream<charT, traits>& is1, 
59                        std::basic_istream<charT, traits>& is2);
60   
61    /**
62       Constructor for istream
63
64       \a os1 is redirected to send its output to the buffer of \a os2
65       (rather than its own buffer). A reference to \a os1 and its
66       buffer is stored, so \a os1 can be restored in the destructor.
67    */
68    BasicStreamRedirect(std::basic_ostream<charT, traits>& os1, 
69                        std::basic_ostream<charT, traits>& os2);
70   
71    /**
72       \brief Destructor - resets the switch
73
74       The stream (first argument in constructor) is restored to use
75       its original buffer.
76
77       \note It is important that the stream held is not deallocated
78       before this object is destroyed. 1) The behavior of this
79       destructor is undefined. 2) The stream destroys the streambuf
80       in its destructor, so if the stream is destroyed before it is
81       restored, the streambuf will likely be deallocated twice. In
82       addition, the original streambuf of the stream will not be
83       closed and deallocated; hence a memory and resource leak.
84    */
85    ~BasicStreamRedirect(void);
86   
87  private:
88    // no copying
89    BasicStreamRedirect(const BasicStreamRedirect&);
90    BasicStreamRedirect& operator=(const BasicStreamRedirect&);
91   
92    void init(std::basic_ios<charT, traits>& ios1, 
93              std::basic_ios<charT, traits>& ios2);
94   
95    std::basic_ios<charT, traits>* ios_;
96    std::basic_streambuf<charT, traits>* buf_;
97  };
98 
99  /**
100     \since New in yat 0.6
101  */
102  typedef BasicStreamRedirect<char> StreamRedirect;
103 
104  /**
105     \since New in yat 0.6
106  */
107  typedef BasicStreamRedirect<wchar_t> wStreamRedirect;
108 
109 
110  // template implementations
111 
112  template<class charT, class traits>
113  BasicStreamRedirect<charT, traits>::
114  BasicStreamRedirect(std::basic_istream<charT, traits>& is1, 
115                      std::basic_istream<charT, traits>& is2)
116  {
117    init(is1, is2);
118  }
119 
120 
121  template<class charT, class traits>
122  BasicStreamRedirect<charT, traits>::
123  BasicStreamRedirect(std::basic_ostream<charT, traits>& os1, 
124                      std::basic_ostream<charT, traits>& os2)
125  {
126    init(os1, os2);
127  }
128 
129 
130  template<class charT, class traits>
131  BasicStreamRedirect<charT, traits>::
132  ~BasicStreamRedirect(void)
133  {
134    YAT_ASSERT(ios_);
135    ios_->rdbuf(buf_);
136  }
137 
138 
139  template<class charT, class traits>
140  void 
141  BasicStreamRedirect<charT, traits>::init(std::basic_ios<charT, traits>& s1, 
142                                           std::basic_ios<charT, traits>& s2)
143  {
144    ios_ = &s1;
145   
146    // save the buffer
147    buf_ = ios_->rdbuf();
148   
149    // redirect os1 to os2
150    ios_->rdbuf(s2.rdbuf());
151  }
152 
153}}} // of namespace utility, yat, and theplu
154
155#endif
Note: See TracBrowser for help on using the repository browser.