CVC3

fdstream.h

Go to the documentation of this file.
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*/