c-file-ptr-stream.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2000-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #if !defined (octave_c_file_ptr_stream_h)
00024 #define octave_c_file_ptr_stream_h 1
00025 
00026 #include <cstdio>
00027 
00028 #include <iosfwd>
00029 
00030 class
00031 c_file_ptr_buf : public std::streambuf
00032 {
00033 public:
00034 
00035 #if !defined (CXX_ISO_COMPLIANT_LIBRARY)
00036   typedef int int_type;
00037 #else
00038   typedef std::streambuf::int_type int_type;
00039 #endif
00040 
00041   typedef int (*close_fcn) (FILE *);
00042 
00043   FILE* stdiofile (void) { return f; }
00044 
00045   c_file_ptr_buf (FILE *f_arg, close_fcn cf_arg = file_close)
00046     : std::streambuf (), f (f_arg), cf (cf_arg)
00047     { }
00048 
00049   ~c_file_ptr_buf (void);
00050 
00051   int_type overflow (int_type);
00052 
00053   int_type underflow (void) { return underflow_common (false); }
00054 
00055   int_type uflow (void) { return underflow_common (true); }
00056 
00057   int_type pbackfail (int_type);
00058 
00059   std::streamsize xsputn (const char*, std::streamsize);
00060 
00061   std::streamsize xsgetn (char *, std::streamsize);
00062 
00063   std::streampos seekoff (std::streamoff, std::ios::seekdir,
00064                           std::ios::openmode = std::ios::in | std::ios::out);
00065 
00066   std::streampos seekpos (std::streampos,
00067                           std::ios::openmode = std::ios::in | std::ios::out);
00068 
00069   int sync (void);
00070 
00071   int flush (void);
00072 
00073   int buf_close (void);
00074 
00075   int file_number () const { return f ? fileno (f) : -1; }
00076 
00077   int seek (long offset, int origin);
00078 
00079   long tell (void);
00080 
00081   void clear (void) { if (f) clearerr (f); }
00082 
00083   static int file_close (FILE *f);
00084 
00085 protected:
00086 
00087   FILE *f;
00088 
00089   close_fcn cf;
00090 
00091 private:
00092 
00093   int_type underflow_common (bool);
00094 
00095   // No copying!
00096 
00097   c_file_ptr_buf (const c_file_ptr_buf&);
00098 
00099   c_file_ptr_buf& operator = (const c_file_ptr_buf&);
00100 };
00101 
00102 // FIXME -- the following three classes could probably share
00103 // some code...
00104 
00105 template <typename STREAM_T, typename FILE_T, typename BUF_T>
00106 class
00107 c_file_ptr_stream : public STREAM_T
00108 {
00109 public:
00110 
00111   c_file_ptr_stream (FILE_T f, typename BUF_T::close_fcn cf = BUF_T::file_close)
00112     : STREAM_T (0), buf (new BUF_T (f, cf)) { STREAM_T::init (buf); }
00113 
00114   ~c_file_ptr_stream (void) { delete buf; buf = 0; }
00115 
00116   BUF_T *rdbuf (void) { return buf; }
00117 
00118   void stream_close (void) { if (buf) buf->buf_close (); }
00119 
00120   int seek (long offset, int origin)
00121     { return buf ? buf->seek (offset, origin) : -1; }
00122 
00123   long tell (void) { return buf ? buf->tell () : -1; }
00124 
00125   void clear (void) { if (buf) buf->clear (); STREAM_T::clear (); }
00126 
00127 private:
00128 
00129   BUF_T *buf;
00130 
00131   // No copying!
00132 
00133   c_file_ptr_stream (const c_file_ptr_stream&);
00134 
00135   c_file_ptr_stream& operator = (const c_file_ptr_stream&);
00136 };
00137 
00138 typedef c_file_ptr_stream<std::istream, FILE *, c_file_ptr_buf> i_c_file_ptr_stream;
00139 typedef c_file_ptr_stream<std::ostream, FILE *, c_file_ptr_buf> o_c_file_ptr_stream;
00140 typedef c_file_ptr_stream<std::iostream, FILE *, c_file_ptr_buf> io_c_file_ptr_stream;
00141 
00142 #ifdef HAVE_ZLIB
00143 
00144 #ifdef HAVE_ZLIB_H
00145 #include <zlib.h>
00146 #endif
00147 
00148 class
00149 c_zfile_ptr_buf : public std::streambuf
00150 {
00151 public:
00152 
00153 #if !defined (CXX_ISO_COMPLIANT_LIBRARY)
00154   typedef int int_type;
00155 #else
00156   typedef std::streambuf::int_type int_type;
00157 #endif
00158 
00159   typedef int (*close_fcn) (gzFile);
00160 
00161   gzFile stdiofile (void) { return f; }
00162 
00163   c_zfile_ptr_buf (gzFile f_arg, close_fcn cf_arg = file_close)
00164     : std::streambuf (), f (f_arg), cf (cf_arg)
00165     { }
00166 
00167   ~c_zfile_ptr_buf (void);
00168 
00169   int_type overflow (int_type);
00170 
00171   int_type underflow (void) { return underflow_common (false); }
00172 
00173   int_type uflow (void) { return underflow_common (true); }
00174 
00175   int_type pbackfail (int_type);
00176 
00177   std::streamsize xsputn (const char*, std::streamsize);
00178 
00179   std::streamsize xsgetn (char *, std::streamsize);
00180 
00181   std::streampos seekoff (std::streamoff, std::ios::seekdir,
00182                           std::ios::openmode = std::ios::in | std::ios::out);
00183 
00184   std::streampos seekpos (std::streampos,
00185                           std::ios::openmode = std::ios::in | std::ios::out);
00186 
00187   int sync (void);
00188 
00189   int flush (void);
00190 
00191   int buf_close (void);
00192 
00193   int file_number () const { return -1; }
00194 
00195   int seek (long offset, int origin)
00196     { return f ? gzseek (f, offset, origin) : -1; }
00197 
00198   long tell (void) { return f ? gztell (f) : -1; }
00199 
00200   void clear (void) { if (f) gzclearerr (f); }
00201 
00202   static int file_close (gzFile f) { return ::gzclose (f); }
00203 
00204 protected:
00205 
00206   gzFile f;
00207 
00208   close_fcn cf;
00209 
00210 private:
00211 
00212   int_type underflow_common (bool);
00213 
00214   // No copying!
00215 
00216   c_zfile_ptr_buf (const c_zfile_ptr_buf&);
00217 
00218   c_zfile_ptr_buf& operator = (const c_zfile_ptr_buf&);
00219 };
00220 
00221 typedef c_file_ptr_stream<std::istream, gzFile, c_zfile_ptr_buf> i_c_zfile_ptr_stream;
00222 typedef c_file_ptr_stream<std::ostream, gzFile, c_zfile_ptr_buf> o_c_zfile_ptr_stream;
00223 typedef c_file_ptr_stream<std::iostream, gzFile, c_zfile_ptr_buf> io_c_zfile_ptr_stream;
00224 
00225 #endif
00226 
00227 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines