CVC3
|
00001 /*! \file fdstream.h 00002 * @brief The following code declares classes to read from and write to 00003 * file descriptore or file handles. 00004 * 00005 * See 00006 * http://www.josuttis.com/cppcode 00007 * for details and the latest version. 00008 * 00009 * - open: 00010 * - integrating BUFSIZ on some systems? 00011 * - optimized reading of multiple characters 00012 * - stream for reading AND writing 00013 * - i18n 00014 * 00015 * (C) Copyright Nicolai M. Josuttis 2001. 00016 * Permission to copy, use, modify, sell and distribute this software 00017 * is granted provided this copyright notice appears in all copies. 00018 * This software is provided "as is" without express or implied 00019 * warranty, and with no claim as to its suitability for any purpose. 00020 * 00021 * Version: Jul 28, 2002 00022 * History: 00023 * Jul 28, 2002: bugfix memcpy() => memmove() 00024 * fdinbuf::underflow(): cast for return statements 00025 * Aug 05, 2001: first public version 00026 */ 00027 #ifndef BOOST_FDSTREAM_HPP 00028 #define BOOST_FDSTREAM_HPP 00029 00030 #include <istream> 00031 #include <ostream> 00032 #include <streambuf> 00033 // for EOF: 00034 #include <cstdio> 00035 // for memmove(): 00036 #include <cstring> 00037 00038 00039 // low-level read and write functions 00040 #ifdef _MSC_VER 00041 # include <io.h> 00042 #else 00043 # include <unistd.h> 00044 //extern "C" { 00045 // int write (int fd, const char* buf, int num); 00046 // int read (int fd, char* buf, int num); 00047 //} 00048 #endif 00049 00050 00051 // BEGIN namespace BOOST 00052 namespace std { 00053 00054 00055 /************************************************************ 00056 * fdostream 00057 * - a stream that writes on a file descriptor 00058 ************************************************************/ 00059 00060 00061 class fdoutbuf : public std::streambuf { 00062 protected: 00063 int fd; // file descriptor 00064 public: 00065 // constructor 00066 fdoutbuf (int _fd) : fd(_fd) { 00067 } 00068 protected: 00069 // write one character 00070 virtual int_type overflow (int_type c) { 00071 if (c != EOF) { 00072 char z = c; 00073 if (write (fd, &z, 1) != 1) { 00074 return EOF; 00075 } 00076 } 00077 return c; 00078 } 00079 // write multiple characters 00080 virtual 00081 std::streamsize xsputn (const char* s, 00082 std::streamsize num) { 00083 return write(fd,s,num); 00084 } 00085 }; 00086 00087 class fdostream : public std::ostream { 00088 protected: 00089 fdoutbuf buf; 00090 public: 00091 fdostream (int fd) : std::ostream(0), buf(fd) { 00092 rdbuf(&buf); 00093 } 00094 }; 00095 00096 00097 /************************************************************ 00098 * fdistream 00099 * - a stream that reads on a file descriptor 00100 ************************************************************/ 00101 00102 class fdinbuf : public std::streambuf { 00103 protected: 00104 int fd; // file descriptor 00105 protected: 00106 /* data buffer: 00107 * - at most, pbSize characters in putback area plus 00108 * - at most, bufSize characters in ordinary read buffer 00109 */ 00110 static const int pbSize = 4; // size of putback area 00111 static const int bufSize = 1024; // size of the data buffer 00112 char buffer[bufSize+pbSize]; // data buffer 00113 00114 public: 00115 /* constructor 00116 * - initialize file descriptor 00117 * - initialize empty data buffer 00118 * - no putback area 00119 * => force underflow() 00120 */ 00121 fdinbuf (int _fd) : fd(_fd) { 00122 setg (buffer+pbSize, // beginning of putback area 00123 buffer+pbSize, // read position 00124 buffer+pbSize); // end position 00125 } 00126 00127 protected: 00128 // insert new characters into the buffer 00129 virtual int_type underflow () { 00130 #ifndef _MSC_VER 00131 using std::memmove; 00132 #endif 00133 00134 // is read position before end of buffer? 00135 if (gptr() < egptr()) { 00136 return traits_type::to_int_type(*gptr()); 00137 } 00138 00139 /* process size of putback area 00140 * - use number of characters read 00141 * - but at most size of putback area 00142 */ 00143 int numPutback; 00144 numPutback = gptr() - eback(); 00145 if (numPutback > pbSize) { 00146 numPutback = pbSize; 00147 } 00148 00149 /* copy up to pbSize characters previously read into 00150 * the putback area 00151 */ 00152 memmove (buffer+(pbSize-numPutback), gptr()-numPutback, 00153 numPutback); 00154 00155 // read at most bufSize new characters 00156 int num; 00157 num = read (fd, buffer+pbSize, bufSize); 00158 if (num <= 0) { 00159 // ERROR or EOF 00160 return EOF; 00161 } 00162 00163 // reset buffer pointers 00164 setg (buffer+(pbSize-numPutback), // beginning of putback area 00165 buffer+pbSize, // read position 00166 buffer+pbSize+num); // end of buffer 00167 00168 // return next character 00169 return traits_type::to_int_type(*gptr()); 00170 } 00171 }; 00172 00173 class fdistream : public std::istream { 00174 protected: 00175 fdinbuf buf; 00176 public: 00177 fdistream (int fd) : std::istream(0), buf(fd) { 00178 rdbuf(&buf); 00179 } 00180 }; 00181 00182 00183 } // END namespace boost 00184 00185 #endif /*BOOST_FDSTREAM_HPP*/