fdstream.h

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

Generated on Thu Apr 13 16:57:31 2006 for CVC Lite by  doxygen 1.4.4