File indexing completed on 2024-05-19 15:27:49
0001 /* The following code declares classes to read from and write to 0002 * file descriptore or file handles. 0003 * 0004 * See 0005 * http://www.josuttis.com/cppcode 0006 * for details and the latest version. 0007 * 0008 * - open: 0009 * - integrating BUFSIZ on some systems? 0010 * - optimized reading of multiple characters 0011 * - stream for reading AND writing 0012 * - i18n 0013 * 0014 * (C) Copyright Nicolai M. Josuttis 2001. 0015 * Permission to copy, use, modify, sell and distribute this software 0016 * is granted provided this copyright notice appears in all copies. 0017 * This software is provided "as is" without express or implied 0018 * warranty, and with no claim as to its suitability for any purpose. 0019 * 0020 * Version: Jul 28, 2002 0021 * History: 0022 * Jul 28, 2002: bugfix memcpy() => memmove() 0023 * fdinbuf::underflow(): cast for return statements 0024 * Aug 05, 2001: first public version 0025 */ 0026 #ifndef BOOST_FDSTREAM_HPP 0027 #define BOOST_FDSTREAM_HPP 0028 0029 #include <istream> 0030 #include <ostream> 0031 #include <streambuf> 0032 // for EOF: 0033 #include <cstdio> 0034 // for memmove(): 0035 #include <cstring> 0036 0037 0038 // low-level read and write functions 0039 #ifdef _MSC_VER 0040 # include <io.h> 0041 #else 0042 # include <unistd.h> 0043 //extern "C" { 0044 // int write (int fd, const char* buf, int num); 0045 // int read (int fd, char* buf, int num); 0046 //} 0047 #endif 0048 0049 0050 // BEGIN namespace BOOST 0051 namespace boost { 0052 0053 0054 /************************************************************ 0055 * fdostream 0056 * - a stream that writes on a file descriptor 0057 ************************************************************/ 0058 0059 0060 class fdoutbuf : public std::streambuf { 0061 protected: 0062 int fd; // file descriptor 0063 public: 0064 // constructor 0065 fdoutbuf (int _fd) : fd(_fd) { 0066 } 0067 protected: 0068 // write one character 0069 virtual int_type overflow (int_type c) { 0070 if (c != EOF) { 0071 char z = c; 0072 if (write (fd, &z, 1) != 1) { 0073 return EOF; 0074 } 0075 } 0076 return c; 0077 } 0078 // write multiple characters 0079 virtual 0080 std::streamsize xsputn (const char* s, 0081 std::streamsize num) { 0082 return write(fd,s,num); 0083 } 0084 }; 0085 0086 class fdostream : public std::ostream { 0087 protected: 0088 fdoutbuf buf; 0089 public: 0090 fdostream (int fd) : std::ostream(0), buf(fd) { 0091 rdbuf(&buf); 0092 } 0093 }; 0094 0095 0096 /************************************************************ 0097 * fdistream 0098 * - a stream that reads on a file descriptor 0099 ************************************************************/ 0100 0101 class fdinbuf : public std::streambuf { 0102 protected: 0103 int fd; // file descriptor 0104 protected: 0105 /* data buffer: 0106 * - at most, pbSize characters in putback area plus 0107 * - at most, bufSize characters in ordinary read buffer 0108 */ 0109 static const int pbSize = 4; // size of putback area 0110 static const int bufSize = 1024; // size of the data buffer 0111 char buffer[bufSize+pbSize]; // data buffer 0112 0113 public: 0114 /* constructor 0115 * - initialize file descriptor 0116 * - initialize empty data buffer 0117 * - no putback area 0118 * => force underflow() 0119 */ 0120 fdinbuf (int _fd) : fd(_fd) { 0121 setg (buffer+pbSize, // beginning of putback area 0122 buffer+pbSize, // read position 0123 buffer+pbSize); // end position 0124 } 0125 0126 protected: 0127 // insert new characters into the buffer 0128 virtual int_type underflow () { 0129 #ifndef _MSC_VER 0130 using std::memmove; 0131 #endif 0132 0133 // is read position before end of buffer? 0134 if (gptr() < egptr()) { 0135 return traits_type::to_int_type(*gptr()); 0136 } 0137 0138 /* process size of putback area 0139 * - use number of characters read 0140 * - but at most size of putback area 0141 */ 0142 int numPutback; 0143 numPutback = gptr() - eback(); 0144 if (numPutback > pbSize) { 0145 numPutback = pbSize; 0146 } 0147 0148 /* copy up to pbSize characters previously read into 0149 * the putback area 0150 */ 0151 memmove (buffer+(pbSize-numPutback), gptr()-numPutback, 0152 numPutback); 0153 0154 // read at most bufSize new characters 0155 int num; 0156 num = read (fd, buffer+pbSize, bufSize); 0157 if (num <= 0) { 0158 // ERROR or EOF 0159 return EOF; 0160 } 0161 0162 // reset buffer pointers 0163 setg (buffer+(pbSize-numPutback), // beginning of putback area 0164 buffer+pbSize, // read position 0165 buffer+pbSize+num); // end of buffer 0166 0167 // return next character 0168 return traits_type::to_int_type(*gptr()); 0169 } 0170 }; 0171 0172 class fdistream : public std::istream { 0173 protected: 0174 fdinbuf buf; 0175 public: 0176 fdistream (int fd) : std::istream(0), buf(fd) { 0177 rdbuf(&buf); 0178 } 0179 }; 0180 0181 0182 } // END namespace boost 0183 0184 #endif /*BOOST_FDSTREAM_HPP*/