GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
c-file-ptr-stream.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2000-2022 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#if defined (HAVE_ZLIB_H)
35# include <zlib.h>
36#endif
37
38OCTAVE_NAMESPACE_BEGIN
39
40class
41c_file_ptr_buf : public std::streambuf
42{
43public:
44
45 typedef std::streambuf::int_type int_type;
46
47 typedef int (*close_fcn) (FILE *);
48
49 FILE *stdiofile (void) { return m_f; }
50
51 c_file_ptr_buf (FILE *f, close_fcn cf = file_close)
52 : std::streambuf (), m_f (f), m_cf (cf)
53 { }
54
55 // No copying!
56
57 c_file_ptr_buf (const c_file_ptr_buf&) = delete;
58
59 c_file_ptr_buf& operator = (const c_file_ptr_buf&) = delete;
60
61 ~c_file_ptr_buf (void);
62
63 int_type overflow (int_type);
64
65 int_type underflow (void) { return underflow_common (false); }
66
67 int_type uflow (void) { return underflow_common (true); }
68
69 int_type pbackfail (int_type);
70
71 std::streamsize xsputn (const char *, std::streamsize);
72
73 std::streamsize xsgetn (char *, std::streamsize);
74
75 std::streampos seekoff (std::streamoff, std::ios::seekdir,
76 std::ios::openmode = std::ios::in | std::ios::out);
77
78 std::streampos seekpos (std::streampos,
79 std::ios::openmode = std::ios::in | std::ios::out);
80
81 int sync (void);
82
83 int flush (void);
84
85 int buf_close (void);
86
87 int file_number () const { return m_f ? fileno (m_f) : -1; }
88
89 int seek (off_t offset, int origin);
90
91 off_t tell (void);
92
93 void clear (void) { if (m_f) clearerr (m_f); }
94
95 static int file_close (FILE *m_f);
96
97protected:
98
99 FILE *m_f;
100
101 close_fcn m_cf;
102
103private:
104
105 int_type underflow_common (bool);
106};
107
108// FIXME: the following three classes could probably share some code...
109
110template <typename STREAM_T, typename FILE_T, typename BUF_T>
111class
113{
114public:
115
116 c_file_ptr_stream (FILE_T m_f,
117 typename BUF_T::close_fcn m_cf = BUF_T::file_close)
118 : STREAM_T (nullptr), m_buf (new BUF_T (m_f, m_cf))
119 { STREAM_T::init (m_buf); }
120
121 // No copying!
122
124
125 c_file_ptr_stream& operator = (const c_file_ptr_stream&) = delete;
126
127 ~c_file_ptr_stream (void) { delete m_buf; m_buf = nullptr; }
128
129 BUF_T * rdbuf (void) { return m_buf; }
130
131 void stream_close (void) { if (m_buf) m_buf->buf_close (); }
132
133 int seek (off_t offset, int origin)
134 { return m_buf ? m_buf->seek (offset, origin) : -1; }
135
136 off_t tell (void) { return m_buf ? m_buf->tell () : -1; }
137
138 void clear (void) { if (m_buf) m_buf->clear (); STREAM_T::clear (); }
139
140private:
141
142 BUF_T *m_buf;
143};
144
151
152
153#if defined (HAVE_ZLIB)
154
155class
156c_zfile_ptr_buf : public std::streambuf
157{
158public:
159
160 typedef std::streambuf::int_type int_type;
161
162 typedef int (*close_fcn) (gzFile);
163
164 gzFile stdiofile (void) { return m_f; }
165
166 c_zfile_ptr_buf (gzFile f, close_fcn cf = file_close)
167 : std::streambuf (), m_f (f), m_cf (cf)
168 { }
169
170 // No copying!
171
173
174 c_zfile_ptr_buf& operator = (const c_zfile_ptr_buf&) = delete;
175
176 ~c_zfile_ptr_buf (void);
177
178 int_type overflow (int_type);
179
180 int_type underflow (void) { return underflow_common (false); }
181
182 int_type uflow (void) { return underflow_common (true); }
183
184 int_type pbackfail (int_type);
185
186 std::streamsize xsputn (const char *, std::streamsize);
187
188 std::streamsize xsgetn (char *, std::streamsize);
189
190 std::streampos seekoff (std::streamoff, std::ios::seekdir,
191 std::ios::openmode = std::ios::in | std::ios::out);
192
193 std::streampos seekpos (std::streampos,
194 std::ios::openmode = std::ios::in | std::ios::out);
195
196 int sync (void);
197
198 int flush (void);
199
200 int buf_close (void);
201
202 int file_number () const { return -1; }
203
204 int seek (off_t offset, int origin)
205 { return m_f ? gzseek (m_f, offset, origin) >= 0 : -1; }
206
207 off_t tell (void) { return m_f ? gztell (m_f) : -1; }
208
209 void clear (void) { if (m_f) gzclearerr (m_f); }
210
211 static int file_close (gzFile m_f) { return ::gzclose (m_f); }
212
213protected:
214
215 gzFile m_f;
216
217 close_fcn m_cf;
218
219private:
220
221 int_type underflow_common (bool);
222};
223
230
231#endif
232
233OCTAVE_NAMESPACE_END
234
235#if defined (OCTAVE_PROVIDE_DEPRECATED_SYMBOLS)
236
237OCTAVE_DEPRECATED (7, "use 'octave::i_c_file_ptr_stream' instead")
239
240OCTAVE_DEPRECATED (7, "use 'octave::o_c_file_ptr_stream' instead")
242
243OCTAVE_DEPRECATED (7, "use 'octave::io_c_file_ptr_stream' instead")
245
246// FIXME: HAVE_ZLIB is not defined here because we do not (and should
247// not) include config.h in this header file. We need to find a way to
248// define this interface without exposing gzFile. Should this be a
249// private header that can only be used if included after config.h in an
250// Octave source file and not inside another header file?
251
252# if defined (HAVE_ZLIB)
253
254OCTAVE_DEPRECATED (7, "use 'octave::i_c_zfile_ptr_stream' instead")
257
258OCTAVE_DEPRECATED (7, "use 'octave::o_c_zfile_ptr_stream' instead")
261
262OCTAVE_DEPRECATED (7, "use 'octave::io_c_zfile_ptr_stream' instead")
263typedef octave::c_file_ptr_stream<std::iostream, gzFile, octave::c_zfile_ptr_buf>
265
266# endif
267
268#endif
269
270#endif
c_file_ptr_stream< std::ostream, gzFile, c_zfile_ptr_buf > o_c_zfile_ptr_stream
c_file_ptr_stream< std::iostream, gzFile, c_zfile_ptr_buf > io_c_zfile_ptr_stream
c_file_ptr_stream< std::istream, FILE *, c_file_ptr_buf > i_c_file_ptr_stream
c_file_ptr_stream< std::iostream, FILE *, c_file_ptr_buf > io_c_file_ptr_stream
c_file_ptr_stream< std::ostream, FILE *, c_file_ptr_buf > o_c_file_ptr_stream
c_file_ptr_stream< std::istream, gzFile, c_zfile_ptr_buf > i_c_zfile_ptr_stream
FILE * stdiofile(void)
c_file_ptr_buf(FILE *f, close_fcn cf=file_close)
int_type uflow(void)
int_type underflow(void)
int file_number() const
std::streambuf::int_type int_type
c_file_ptr_buf(const c_file_ptr_buf &)=delete
int seek(off_t offset, int origin)
c_file_ptr_stream(FILE_T m_f, typename BUF_T::close_fcn m_cf=BUF_T::file_close)
c_file_ptr_stream(const c_file_ptr_stream &)=delete
c_zfile_ptr_buf(const c_zfile_ptr_buf &)=delete
int_type uflow(void)
int file_number() const
static int file_close(gzFile m_f)
c_zfile_ptr_buf(gzFile f, close_fcn cf=file_close)
int seek(off_t offset, int origin)
gzFile stdiofile(void)
int_type underflow(void)
std::streambuf::int_type int_type
F77_RET_T const F77_DBLE const F77_DBLE * f
STL namespace.