1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2000-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if ! defined (octave_c_file_ptr_stream_h) 27 #define octave_c_file_ptr_stream_h 1 28 29 #include "octave-config.h" 30 31 #include <cstdio> 32 #include <istream> 33 34 class 35 c_file_ptr_buf : public std::streambuf 36 { 37 public: 38 39 typedef std::streambuf::int_type int_type; 40 41 typedef int (*close_fcn) (FILE *); 42 stdiofile(void)43 FILE *stdiofile (void) { return f; } 44 45 c_file_ptr_buf (FILE *f_arg, close_fcn cf_arg = file_close) streambuf()46 : std::streambuf (), f (f_arg), cf (cf_arg) 47 { } 48 49 // No copying! 50 51 c_file_ptr_buf (const c_file_ptr_buf&) = delete; 52 53 c_file_ptr_buf& operator = (const c_file_ptr_buf&) = delete; 54 55 ~c_file_ptr_buf (void); 56 57 int_type overflow (int_type); 58 underflow(void)59 int_type underflow (void) { return underflow_common (false); } 60 uflow(void)61 int_type uflow (void) { return underflow_common (true); } 62 63 int_type pbackfail (int_type); 64 65 std::streamsize xsputn (const char*, std::streamsize); 66 67 std::streamsize xsgetn (char *, std::streamsize); 68 69 std::streampos seekoff (std::streamoff, std::ios::seekdir, 70 std::ios::openmode = std::ios::in | std::ios::out); 71 72 std::streampos seekpos (std::streampos, 73 std::ios::openmode = std::ios::in | std::ios::out); 74 75 int sync (void); 76 77 int flush (void); 78 79 int buf_close (void); 80 file_number()81 int file_number () const { return f ? fileno (f) : -1; } 82 83 int seek (off_t offset, int origin); 84 85 off_t tell (void); 86 clear(void)87 void clear (void) { if (f) clearerr (f); } 88 89 static int file_close (FILE *f); 90 91 protected: 92 93 FILE *f; 94 95 close_fcn cf; 96 97 private: 98 99 int_type underflow_common (bool); 100 }; 101 102 // FIXME: the following three classes could probably share some code... 103 104 template <typename STREAM_T, typename FILE_T, typename BUF_T> 105 class 106 c_file_ptr_stream : public STREAM_T 107 { 108 public: 109 110 c_file_ptr_stream (FILE_T f, typename BUF_T::close_fcn cf = BUF_T::file_close) STREAM_T(nullptr)111 : STREAM_T (nullptr), buf (new BUF_T (f, cf)) { STREAM_T::init (buf); } 112 113 // No copying! 114 115 c_file_ptr_stream (const c_file_ptr_stream&) = delete; 116 117 c_file_ptr_stream& operator = (const c_file_ptr_stream&) = delete; 118 ~c_file_ptr_stream(void)119 ~c_file_ptr_stream (void) { delete buf; buf = nullptr; } 120 rdbuf(void)121 BUF_T * rdbuf (void) { return buf; } 122 stream_close(void)123 void stream_close (void) { if (buf) buf->buf_close (); } 124 seek(off_t offset,int origin)125 int seek (off_t offset, int origin) 126 { return buf ? buf->seek (offset, origin) : -1; } 127 tell(void)128 off_t tell (void) { return buf ? buf->tell () : -1; } 129 clear(void)130 void clear (void) { if (buf) buf->clear (); STREAM_T::clear (); } 131 132 private: 133 134 BUF_T *buf; 135 }; 136 137 typedef c_file_ptr_stream<std::istream, FILE *, c_file_ptr_buf> 138 i_c_file_ptr_stream; 139 typedef c_file_ptr_stream<std::ostream, FILE *, c_file_ptr_buf> 140 o_c_file_ptr_stream; 141 typedef c_file_ptr_stream<std::iostream, FILE *, c_file_ptr_buf> 142 io_c_file_ptr_stream; 143 144 #if defined (HAVE_ZLIB) 145 146 #if defined (HAVE_ZLIB_H) 147 # include <zlib.h> 148 #endif 149 150 class 151 c_zfile_ptr_buf : public std::streambuf 152 { 153 public: 154 155 typedef std::streambuf::int_type int_type; 156 157 typedef int (*close_fcn) (gzFile); 158 stdiofile(void)159 gzFile stdiofile (void) { return f; } 160 161 c_zfile_ptr_buf (gzFile f_arg, close_fcn cf_arg = file_close) streambuf()162 : std::streambuf (), f (f_arg), cf (cf_arg) 163 { } 164 165 // No copying! 166 167 c_zfile_ptr_buf (const c_zfile_ptr_buf&) = delete; 168 169 c_zfile_ptr_buf& operator = (const c_zfile_ptr_buf&) = delete; 170 171 ~c_zfile_ptr_buf (void); 172 173 int_type overflow (int_type); 174 underflow(void)175 int_type underflow (void) { return underflow_common (false); } 176 uflow(void)177 int_type uflow (void) { return underflow_common (true); } 178 179 int_type pbackfail (int_type); 180 181 std::streamsize xsputn (const char*, std::streamsize); 182 183 std::streamsize xsgetn (char *, std::streamsize); 184 185 std::streampos seekoff (std::streamoff, std::ios::seekdir, 186 std::ios::openmode = std::ios::in | std::ios::out); 187 188 std::streampos seekpos (std::streampos, 189 std::ios::openmode = std::ios::in | std::ios::out); 190 191 int sync (void); 192 193 int flush (void); 194 195 int buf_close (void); 196 file_number()197 int file_number () const { return -1; } 198 seek(off_t offset,int origin)199 int seek (off_t offset, int origin) 200 { return f ? gzseek (f, offset, origin) >= 0 : -1; } 201 tell(void)202 off_t tell (void) { return f ? gztell (f) : -1; } 203 clear(void)204 void clear (void) { if (f) gzclearerr (f); } 205 file_close(gzFile f)206 static int file_close (gzFile f) { return ::gzclose (f); } 207 208 protected: 209 210 gzFile f; 211 212 close_fcn cf; 213 214 private: 215 216 int_type underflow_common (bool); 217 }; 218 219 typedef c_file_ptr_stream<std::istream, gzFile, c_zfile_ptr_buf> 220 i_c_zfile_ptr_stream; 221 typedef c_file_ptr_stream<std::ostream, gzFile, c_zfile_ptr_buf> 222 o_c_zfile_ptr_stream; 223 typedef c_file_ptr_stream<std::iostream, gzFile, c_zfile_ptr_buf> 224 io_c_zfile_ptr_stream; 225 226 #endif 227 228 #endif 229