00001 /** @file rutz/stdiobuf.h wrap posix file descriptors in c++ iostreams */ 00002 00003 /////////////////////////////////////////////////////////////////////// 00004 // 00005 // Copyright (c) 2002-2004 California Institute of Technology 00006 // Copyright (c) 2004-2007 University of Southern California 00007 // Rob Peters <rjpeters at usc dot edu> 00008 // 00009 // created: Tue Feb 25 13:27:36 2003 00010 // commit: $Id: stdiobuf.h 8249 2007-04-12 06:03:40Z rjpeters $ 00011 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/stdiobuf.h $ 00012 // 00013 // -------------------------------------------------------------------- 00014 // 00015 // This file is part of GroovX. 00016 // [http://ilab.usc.edu/rjpeters/groovx/] 00017 // 00018 // GroovX is free software; you can redistribute it and/or modify it 00019 // under the terms of the GNU General Public License as published by 00020 // the Free Software Foundation; either version 2 of the License, or 00021 // (at your option) any later version. 00022 // 00023 // GroovX is distributed in the hope that it will be useful, but 00024 // WITHOUT ANY WARRANTY; without even the implied warranty of 00025 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00026 // General Public License for more details. 00027 // 00028 // You should have received a copy of the GNU General Public License 00029 // along with GroovX; if not, write to the Free Software Foundation, 00030 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00031 // 00032 /////////////////////////////////////////////////////////////////////// 00033 00034 #ifndef GROOVX_RUTZ_STDIOBUF_H_UTC20050626084019_DEFINED 00035 #define GROOVX_RUTZ_STDIOBUF_H_UTC20050626084019_DEFINED 00036 00037 #include <cstdio> 00038 #include <streambuf> 00039 #include <istream> 00040 00041 namespace rutz 00042 { 00043 class stdiobuf; 00044 class stdiostream; 00045 } 00046 00047 /// A C++ streambuf that wraps a standard posix file descriptor. 00048 class rutz::stdiobuf : public std::streambuf 00049 { 00050 private: 00051 int m_mode; 00052 int m_filedes; 00053 00054 stdiobuf(const stdiobuf&); 00055 stdiobuf& operator=(const stdiobuf&); 00056 00057 static const int s_buf_size = 4092; 00058 static const int s_pback_size = 4; 00059 char buffer[s_buf_size]; 00060 00061 void init(int fd, int om, bool throw_exception); 00062 00063 int flushoutput(); 00064 00065 public: 00066 /// Create with a reference to a FILE object. 00067 /** The stdiobuf will NOT close the FILE on destruction, that is 00068 left up to the caller (since the caller must also have been the 00069 one to open the FILE object). */ 00070 stdiobuf(FILE* f, int om, bool throw_exception=false); 00071 00072 /// Create with a reference to a file descriptor. 00073 /** The stdiobuf will NOT close the descriptor on destruction, that 00074 is left up to the caller (since the caller must also have been 00075 the one to open the file descriptor). */ 00076 stdiobuf(int fd, int om, bool throw_exception=false); 00077 00078 /// Destructor flushes buffer, but DOES NOT CLOSE the file descriptor. 00079 ~stdiobuf() { close(); } 00080 00081 /// Check whether we have an open file descriptor. 00082 bool is_open() const { return m_filedes >= 0; } 00083 00084 /// Flushes the buffer and forgets the file descriptor, but DOESN'T CLOSE IT. 00085 /** It is assumed that the same caller who passed the open file 00086 descriptor to our constructor will also eventually close that 00087 file descriptor. */ 00088 void close(); 00089 00090 /// Get more data from the underlying file descriptor. 00091 /** Called when the streambuf's buffer has run out of data. */ 00092 virtual int underflow(); 00093 00094 /// Send more data to the underlying file descriptor. 00095 /** Called when the streambuf's buffer has become full. */ 00096 virtual int overflow(int c); 00097 00098 /// Flush the current buffer contents to the underlying file. 00099 virtual int sync(); 00100 }; 00101 00102 class rutz::stdiostream : public std::iostream 00103 { 00104 private: 00105 rutz::stdiobuf m_buf; 00106 00107 public: 00108 /// Create with a reference to a FILE object. 00109 /** The stdiobuf will NOT close the FILE on destruction, that is 00110 left up to the caller (since the caller must also have been the 00111 one to open the FILE object). */ 00112 stdiostream(FILE* f, int om, bool throw_exception=false) : 00113 std::iostream(0), 00114 m_buf(f, om, throw_exception) 00115 { 00116 rdbuf(&m_buf); 00117 } 00118 00119 /// Create with a reference to a file descriptor. 00120 /** The stdiobuf will NOT close the descriptor on destruction, that 00121 is left up to the caller (since the caller must also have been 00122 the one to open the file descriptor). */ 00123 stdiostream(int fd, int om, bool throw_exception=false) : 00124 std::iostream(0), 00125 m_buf(fd, om, throw_exception) 00126 { 00127 rdbuf(&m_buf); 00128 } 00129 00130 /// Check whether we have an open file descriptor. 00131 bool is_open() const { return m_buf.is_open(); } 00132 00133 /// Flushes the buffer and forgets the file descriptor, but DOESN'T CLOSE IT. 00134 void close() { m_buf.close(); } 00135 }; 00136 00137 static const char __attribute__((used)) vcid_groovx_rutz_stdiobuf_h_utc20050626084019[] = "$Id: stdiobuf.h 8249 2007-04-12 06:03:40Z rjpeters $ $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/rutz/stdiobuf.h $"; 00138 #endif // !GROOVX_RUTZ_STDIOBUF_H_UTC20050626084019_DEFINED