Main MRPT website > C++ reference
MRPT logo
CConsoleRedirector.h
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | The Mobile Robot Programming Toolkit (MRPT) C++ library |
3  | |
4  | http://www.mrpt.org/ |
5  | |
6  | Copyright (C) 2005-2012 University of Malaga |
7  | |
8  | This software was written by the Machine Perception and Intelligent |
9  | Robotics Lab, University of Malaga (Spain). |
10  | Contact: Jose-Luis Blanco <jlblanco@ctima.uma.es> |
11  | |
12  | This file is part of the MRPT project. |
13  | |
14  | MRPT is free software: you can redistribute it and/or modify |
15  | it under the terms of the GNU General Public License as published by |
16  | the Free Software Foundation, either version 3 of the License, or |
17  | (at your option) any later version. |
18  | |
19  | MRPT is distributed in the hope that it will be useful, |
20  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
21  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22  | GNU General Public License for more details. |
23  | |
24  | You should have received a copy of the GNU General Public License |
25  | along with MRPT. If not, see <http://www.gnu.org/licenses/>. |
26  | |
27  +---------------------------------------------------------------------------+ */
28 #ifndef CConsoleRedirector_H
29 #define CConsoleRedirector_H
30 
31 #include <streambuf>
32 #include <iostream>
33 
34 
35 namespace mrpt
36 {
37  namespace utils
38  {
39  /** By creating an object of this class, all the output to std::cout (and std::cerr) will be redirected to a text file, and optionally also shown on the console.
40  * Based on code from http://www.devmaster.net/forums/showthread.php?t=7037
41  * \ingroup mrpt_base_grp
42  */
43  class CConsoleRedirector : public std::streambuf
44  {
45  protected:
46  std::ofstream m_of; //!< The text output file stream.
47  std::streambuf *sbOld; //!< The "old" std::cout
48  std::streambuf *sbOld_cerr; //!< The "old" std::cout
51 
52  public:
53  /** Constructor
54  * \param out_file The file to create / append
55  * \param also_to_console Whether to redirect data to file *and* also dump data to the console as usual.
56  * \param append_file If set to false the file will be truncated on open
57  * \param bufferSize It's recommended to buffer the data instead of writing characters one by one.
58  * \param also_cerr Whether to redirect the output to std::cerr in addition to std::cout.
59  * \exception std::exception If the file cannot be opened.
60  */
62  const std::string &out_file,
63  bool also_to_console=true,
64  bool also_cerr = true,
65  bool append_file = false,
66  int bufferSize = 1000 ) : m_of(), sbOld(NULL),sbOld_cerr(NULL),m_also_to_console(also_to_console), m_cs()
67  {
68  // Open the file:
69  std::ios_base::openmode openMode = std::ios_base::binary | std::ios_base::out;
70  if ( append_file ) openMode |= std::ios_base::app;
71  m_of.open(out_file.c_str(), openMode );
72  if (!m_of.is_open()) THROW_EXCEPTION_CUSTOM_MSG1("Error opening file: %s",out_file.c_str())
73 
74  if (bufferSize)
75  {
76  char *ptr = new char[bufferSize];
77  setp(ptr, ptr + bufferSize);
78  }
79  else
80  setp(0, 0);
81 
82  // Redirect:
83  sbOld = std::cout.rdbuf();
84  std::cout.rdbuf( this );
85 
86  if (also_cerr)
87  {
88  sbOld_cerr = std::cerr.rdbuf();
89  std::cerr.rdbuf( this );
90  }
91  }
92 
94  {
95  sync();
96  // Restore normal output:
97  std::cout.rdbuf(sbOld);
98  if (sbOld_cerr!=NULL) std::cerr.rdbuf( sbOld_cerr );
99  if (pbase()) delete[] pbase();
100  }
101 
102  void flush()
103  {
104  sync();
105  }
106 
107  virtual void writeString(const std::string &str)
108  {
109  if (m_also_to_console) sbOld->sputn(str.c_str(),str.size());
110  m_of << str;
111  }
112 
113  private:
114  int overflow(int c)
115  {
116  sync();
117 
118  m_cs.enter();
119  if (c != EOF)
120  {
121  if (pbase() == epptr())
122  {
123  std::string temp;
124  temp += char(c);
125  writeString(temp);
126  }
127  else
128  sputc(c);
129  }
130 
131  m_cs.leave();
132  return 0;
133  }
134 
135  int sync()
136  {
137  m_cs.enter();
138  if (pbase() != pptr())
139  {
140  int len = int(pptr() - pbase());
141  std::string temp(pbase(), len);
142  writeString(temp);
143  setp(pbase(), epptr());
144  }
145  m_cs.leave();
146  return 0;
147  }
148  };
149 
150  } // end namespace
151 } // end namespace
152 
153 #endif



Page generated by Doxygen 1.8.3 for MRPT 0.9.6 SVN: at Fri Feb 15 22:05:02 EST 2013