Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

FdStream.H

Go to the documentation of this file.
00001 // Copyright (C) 2004, Kenneth C. Schalk
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 #ifndef _FDSTREAM_H_
00020 #define _FDSTREAM_H_
00021 
00022 #include <sys/types.h>
00023 #include <iosfwd>
00024 #include <iostream>
00025 
00026 namespace FS
00027 {
00028   // streambuf class for reading from/writing to a file descriptor.
00029   // Does all the real work.  Analogous to filebuf.
00030 
00031   class FdStreambuf : public std::streambuf
00032   {
00033   public:
00034 #if defined(__GNUC__) && (__GNUC__ < 3)
00035     typedef streampos stream_pos_t;
00036     typedef streamoff stream_off_t;
00037     typedef ios::seek_dir stream_seek_t;
00038     typedef int stream_mode_t;
00039 #else
00040     typedef std::streambuf::pos_type stream_pos_t;
00041     typedef std::streambuf::off_type stream_off_t;
00042     typedef std::ios_base::seekdir stream_seek_t;
00043     typedef std::ios_base::openmode stream_mode_t;
00044 #endif
00045   protected:
00046     int _fd;
00047 
00048     // Should we close the file descriptor when this object is
00049     // destroyed?
00050     bool should_close;
00051 
00052     // Buffers used for the get and put areas.
00053     char *buffer;
00054     unsigned int buf_size;
00055     stream_mode_t mode;
00056 
00057     // If we've read through part of a get area, seek the file
00058     // descriptor to the same position.  Reset the get area in any case.
00059     bool get_pos_to_fd_pos();
00060 
00061   public:
00062 
00063     FdStreambuf()
00064       : _fd(-1), should_close(false), buffer(0), buf_size(0)
00065     { }
00066     FdStreambuf(int fd);
00067     FdStreambuf(const char *filename, stream_mode_t mode,
00068                 mode_t prot = 0644,
00069                 bool create = true, bool replace = true);
00070 
00071     ~FdStreambuf();
00072 
00073     FdStreambuf* attach(int fd);
00074 
00075     FdStreambuf* open(const char *filename, stream_mode_t mode,
00076                       mode_t prot = 0644,
00077                       bool create = true, bool replace = true);
00078     inline bool is_open() const { return this->_fd >= 0; }
00079     inline int fd() const { return is_open() ? this->_fd : -1; }
00080     FdStreambuf* close();
00081     virtual stream_pos_t seekoff(stream_off_t offset,
00082                                  stream_seek_t way,
00083                                  // NOTE: mode ignored!
00084                                  stream_mode_t mode=(std::ios::in|
00085                                                      std::ios::out));
00086     stream_pos_t seekpos(stream_pos_t pos, 
00087                          // NOTE: mode ignored!
00088                          stream_mode_t mode=(std::ios::in|
00089                                              std::ios::out));
00090 
00091   protected:
00092     int underflow();
00093     std::streamsize xsgetn(char* s, std::streamsize n);
00094     int overflow(int c = EOF);
00095     std::streamsize xsputn(const char* s, std::streamsize n);
00096     int sync();
00097   };
00098 
00099   // Base class for FdStream classes below.  Analogous to fstreambase.
00100 
00101   class FdStreamBase : virtual public std::ios
00102   {
00103   protected:
00104     FdStreambuf my_fdbuf;
00105   public:
00106     FdStreamBase()
00107       : my_fdbuf()
00108     {
00109       init(&my_fdbuf);
00110     }
00111     FdStreamBase(int fd)
00112       : my_fdbuf(fd)
00113     {
00114       init(&my_fdbuf);
00115       // Bad file descriptor?
00116       if(!is_open())
00117         clear(std::ios::badbit); // set badbit
00118       else
00119         clear(std::ios::goodbit); // all is well
00120     }
00121     FdStreamBase(const char *filename, FdStreambuf::stream_mode_t mode,
00122                  mode_t prot = 0644,
00123                  bool create = true, bool replace = true)
00124       : my_fdbuf(filename, mode, prot, create, replace)
00125     {
00126       init(&my_fdbuf);
00127       // Open failed?
00128       if(!is_open())
00129         clear(std::ios::badbit); // set badbit
00130       else
00131         clear(std::ios::goodbit); // all is well
00132     }
00133 
00134     FdStreambuf *rdbuf() { return &my_fdbuf; }
00135     void close()
00136     {
00137       if(my_fdbuf.close() != &my_fdbuf)
00138         clear(std::ios::badbit); // set badbit
00139     }
00140     bool is_open() const { return my_fdbuf.is_open(); }
00141     int fd() const { return my_fdbuf.fd(); }
00142     void attach(int fd)
00143     {
00144       if(my_fdbuf.attach(fd) != &my_fdbuf)
00145         clear(std::ios::badbit); // set badbit
00146       else
00147         clear(std::ios::goodbit); // all is well
00148     }
00149 
00150     void open(const char *filename, FdStreambuf::stream_mode_t mode,
00151               mode_t prot = 0644,
00152               bool create = true, bool replace = true)
00153     {
00154       if(my_fdbuf.open(filename, mode, prot, create, replace) != &my_fdbuf)
00155         clear(std::ios::badbit); // set badbit
00156       else
00157         clear(std::ios::goodbit); // all is well
00158     }
00159   };
00160 
00161   // Input fd stream.  Analogous to ifstream.
00162 
00163   class IFdStream : public FdStreamBase, public std::istream
00164   {
00165   public:
00166     IFdStream() : FdStreamBase(), std::istream(&my_fdbuf) { }
00167     IFdStream(int fd) : FdStreamBase(fd), std::istream(&my_fdbuf) { }
00168     IFdStream(const char *filename,
00169               FdStreambuf::stream_mode_t mode = std::ios::in,
00170               mode_t prot = 0644,
00171               bool create = true, bool replace = true)
00172       : FdStreamBase(filename, mode, prot, create, replace),
00173         std::istream(&my_fdbuf)
00174     { }
00175 
00176     void open(const char *filename,
00177               FdStreambuf::stream_mode_t mode = std::ios::in,
00178               mode_t prot = 0644,
00179               bool create = true, bool replace = true)
00180     {
00181       FdStreamBase::open(filename, mode, prot, create, replace);
00182     }
00183   };
00184 
00185   // Output fd stream.  Analogous to ofstream.
00186 
00187   class OFdStream : public FdStreamBase, public std::ostream
00188   {
00189   public:
00190     OFdStream() : FdStreamBase(), std::ostream(&my_fdbuf) { }
00191     OFdStream(int fd) : FdStreamBase(fd), std::ostream(&my_fdbuf) { }
00192     OFdStream(const char *filename,
00193               FdStreambuf::stream_mode_t mode = std::ios::out,
00194               mode_t prot = 0644,
00195               bool create = true, bool replace = true)
00196       : FdStreamBase(filename, mode, prot, create, replace),
00197         std::ostream(&my_fdbuf)
00198     { }
00199 
00200     void open(const char *filename,
00201               FdStreambuf::stream_mode_t mode = std::ios::out,
00202               mode_t prot = 0644,
00203               bool create = true, bool replace = true)
00204     {
00205       FdStreamBase::open(filename, mode, prot, create, replace);
00206     }
00207   };
00208 
00209   // Generic fd stream.  Analogous to fstream.
00210 
00211   class FdStream : public FdStreamBase, public std::iostream
00212   {
00213   public:
00214     FdStream() : FdStreamBase(), std::iostream(&my_fdbuf) { }
00215     FdStream(int fd) : FdStreamBase(fd), std::iostream(&my_fdbuf) { }
00216     FdStream(const char *filename, FdStreambuf::stream_mode_t mode,
00217              mode_t prot = 0644,
00218              bool create = true, bool replace = true)
00219       : FdStreamBase(filename, mode, prot, create, replace),
00220         std::iostream(&my_fdbuf)
00221     { }
00222 
00223     void open(const char *filename, FdStreambuf::stream_mode_t mode,
00224               mode_t prot = 0644,
00225               bool create = true, bool replace = true)
00226     {
00227       FdStreamBase::open(filename, mode, prot, create, replace);
00228     }
00229   };
00230 }
00231 
00232 #endif

Generated on Mon May 8 00:48:30 2006 for Vesta by  doxygen 1.4.2