fdstream.hpp

Go to the documentation of this file.
00001 /* 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  * Aug 05, 2001
00021  */
00022 #ifndef BOOST_FDSTREAM_HPP
00023 #define BOOST_FDSTREAM_HPP
00024 
00025 #include <istream>
00026 #include <ostream>
00027 #include <streambuf>
00028 // for EOF:
00029 #include <cstdio>
00030 // for memcpy():
00031 #include <cstring>
00032 
00033 
00034 // low-level read and write functions
00035 #ifdef _MSC_VER
00036 # include <io.h>
00037 #else
00038 # include <unistd.h>
00039 //extern "C" {
00040 //    int write (int fd, const char* buf, int num);
00041 //    int read (int fd, char* buf, int num);
00042 //}
00043 #endif
00044 
00045 
00046 // BEGIN namespace BOOST
00047 namespace boost {
00048 
00049 
00050 /************************************************************
00051  * fdostream
00052  * - a stream that writes on a file descriptor
00053  ************************************************************/
00054 
00055 
00056 class fdoutbuf : public std::streambuf {
00057   protected:
00058     int fd;    // file descriptor
00059   public:
00060     // constructor
00061     fdoutbuf (int _fd) : fd(_fd) {
00062     }
00063   protected:
00064     // write one character
00065     virtual int_type overflow (int_type c) {
00066         if (c != EOF) {
00067             char z = c;
00068 #ifdef _MSC_VER
00069             if (_write (fd, &z, 1) != 1) {
00070 #else
00071             if (write (fd, &z, 1) != 1) {
00072 #endif
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 #ifdef _MSC_VER
00083         return _write(fd,s,num);
00084 #else
00085         return write(fd,s,num);
00086 #endif
00087     }
00088 };
00089 
00090 class fdostream : public std::ostream {
00091   protected:
00092     fdoutbuf buf;
00093   public:
00094     fdostream (int fd) : std::ostream(0), buf(fd) {
00095         rdbuf(&buf);
00096     }
00097 };
00098 
00099 
00100 /************************************************************
00101  * fdistream
00102  * - a stream that writes on a file descriptor
00103  ************************************************************/
00104 
00105 class fdinbuf : public std::streambuf {
00106   protected:
00107     int fd;    // file descriptor
00108   protected:
00109     /* data buffer:
00110      * - at most, pbSize characters in putback area plus
00111      * - at most, bufSize characters in ordinary read buffer
00112      */
00113     static const int pbSize = 4;        // size of putback area
00114     static const int bufSize = 1024;    // size of the data buffer
00115     char buffer[bufSize+pbSize];        // data buffer
00116 
00117   public:
00118     /* constructor
00119      * - initialize file descriptor
00120      * - initialize empty data buffer
00121      * - no putback area
00122      * => force underflow()
00123      */
00124     fdinbuf (int _fd) : fd(_fd) {
00125         setg (buffer+pbSize,     // beginning of putback area
00126               buffer+pbSize,     // read position
00127               buffer+pbSize);    // end position
00128     }
00129 
00130   protected:
00131     // insert new characters into the buffer
00132     virtual int_type underflow () {
00133 #ifndef _MSC_VER
00134 using std::memcpy;
00135 #endif
00136 
00137         // is read position before end of buffer?
00138         if (gptr() < egptr()) {
00139             return *gptr();
00140         }
00141 
00142         /* process size of putback area
00143          * - use number of characters read
00144          * - but at most size of putback area
00145          */
00146         int numPutback;
00147         numPutback = gptr() - eback();
00148         if (numPutback > pbSize) {
00149             numPutback = pbSize;
00150         }
00151 
00152         /* copy up to pbSize characters previously read into
00153          * the putback area
00154          */
00155         memcpy (buffer+(pbSize-numPutback), gptr()-numPutback,
00156                 numPutback);
00157 
00158         // read at most bufSize new characters
00159         int num;
00160 #ifdef _MSC_VER
00161         num = _read (fd, buffer+pbSize, bufSize);
00162 #else
00163         num = read (fd, buffer+pbSize, bufSize);
00164 #endif
00165         if (num <= 0) {
00166             // ERROR or EOF
00167             return EOF;
00168         }
00169 
00170         // reset buffer pointers
00171         setg (buffer+(pbSize-numPutback),   // beginning of putback area
00172               buffer+pbSize,                // read position
00173               buffer+pbSize+num);           // end of buffer
00174 
00175         // return next character
00176         return *gptr();
00177     }
00178 };
00179 
00180 class fdistream : public std::istream {
00181   protected:
00182     fdinbuf buf;
00183   public:
00184     fdistream (int fd) : std::istream(0), buf(fd) {
00185         rdbuf(&buf);
00186     }
00187 };
00188 
00189 
00190 } // END namespace boost
00191 
00192 #endif /*BOOST_FDSTREAM_HPP*/

Generated on Wed Nov 23 19:00:11 2011 for FreeCAD by  doxygen 1.6.1