GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
gzfstream.h
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2005-2025 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/*
27
28 This file is adapted from the zlib 1.2.2 contrib/iostream3 code,
29 written by
30
31 Ludwig Schwardt <schwardt@sun.ac.za>
32 original version by Kevin Ruland <kevin@rodin.wustl.edu>
33
34*/
35
36#if ! defined (octave_zfsstream_h)
37#define octave_zfsstream_h 1
38
39#include "octave-config.h"
40
41#if defined (HAVE_ZLIB)
42
43#include <iosfwd>
44
45#include "zlib.h"
46
47/**
48 * @brief Gzipped file stream buffer class.
49 *
50 * This class implements basic_filebuf for gzipped files. It doesn't yet
51 * support seeking (allowed by zlib but slow/limited), putback and read/write
52 * access * (tricky). Otherwise, it attempts to be a drop-in replacement for
53 * the standard file streambuf.
54*/
55class gzfilebuf : public std::streambuf
56{
57public:
58 // Default constructor.
59 gzfilebuf ();
60
61 OCTAVE_DISABLE_COPY_MOVE (gzfilebuf)
62
63 // Destructor.
64 virtual ~gzfilebuf ();
65
66 /**
67 * @brief Set compression level and strategy on the fly.
68 * @param comp_level Compression level (see zlib.h for allowed values)
69 * @param comp_strategy Compression strategy (see zlib.h for allowed values)
70 * @return Z_OK on success, Z_STREAM_ERROR otherwise.
71 *
72 * Unfortunately, these parameters cannot be modified separately, as the
73 * previous zfstream version assumed. Since the strategy is seldom changed,
74 * it can default and setcompression(level) then becomes like the old
75 * setcompressionlevel(level).
76 */
77 int
78 setcompression (int comp_level,
79 int comp_strategy = Z_DEFAULT_STRATEGY);
80
81 /**
82 * @brief Check if file is open.
83 * @return True if file is open.
84 */
85 bool
86 is_open () const { return (m_file != nullptr); }
87
88 /**
89 * @brief Open gzipped file.
90 * @param name Filename.
91 * @param mode Open mode flags.
92 * @return @c this on success, NULL on failure.
93 */
94 gzfilebuf *
95 open (const char *name,
96 std::ios_base::openmode mode);
97
98 /**
99 * @brief Attach to already open gzipped file.
100 * @param fd File descriptor.
101 * @param mode Open mode flags.
102 * @return @c this on success, NULL on failure.
103 */
104 gzfilebuf *
105 attach (int fd,
106 std::ios_base::openmode mode);
107
108 /**
109 * @brief Close gzipped file.
110 * @return @c this on success, NULL on failure.
111 */
112 gzfilebuf *
113 close ();
114
115protected:
116 /**
117 * @brief Convert ios open mode int to mode string used by zlib.
118 * @return True if valid mode flag combination.
119 */
120 bool
121 open_mode (std::ios_base::openmode mode,
122 char *c_mode) const;
123
124 /**
125 * @brief Number of characters available in stream buffer.
126 * @return Number of characters.
127 *
128 * This indicates number of characters in get area of stream buffer.
129 * These characters can be read without accessing the gzipped file.
130 */
131 virtual std::streamsize
132 showmanyc ();
133
134 /**
135 * @brief Fill get area from gzipped file.
136 * @return First character in get area on success, EOF on error.
137 *
138 * This actually reads characters from gzipped file to stream
139 * buffer. Always buffered.
140 */
141 virtual int_type
142 underflow ();
143
144 /**
145 * @brief Write put area to gzipped file.
146 * @param c Extra character to add to buffer contents.
147 * @return Non-EOF on success, EOF on error.
148 *
149 * This actually writes characters in stream buffer to
150 * gzipped file. With unbuffered output this is done one
151 * character at a time.
152 */
153 virtual int_type
154 overflow (int_type c = traits_type::eof ());
155
156 /**
157 * @brief Installs external stream buffer.
158 * @param p Pointer to char buffer.
159 * @param n Size of external buffer.
160 * @return @c this on success, NULL on failure.
161 *
162 * Call setbuf(0,0) to enable unbuffered output.
163 */
164 virtual std::streambuf *
165 setbuf (char_type *p,
166 std::streamsize n);
167
168 /**
169 * @brief Flush stream buffer to file.
170 * @return 0 on success, -1 on error.
171 *
172 * This calls underflow(EOF) to do the job.
173 */
174 virtual int
175 sync ();
176
177 /**
178 * @brief Alters the stream positions.
179 *
180 * Each derived class provides its own appropriate behavior.
181 */
182 virtual pos_type
183 seekoff (off_type off, std::ios_base::seekdir way,
184 std::ios_base::openmode mode =
185 std::ios_base::in | std::ios_base::out);
186
187 /**
188 * @brief Alters the stream positions.
189 *
190 * Each derived class provides its own appropriate behavior.
191 */
192 virtual pos_type
193 seekpos (pos_type sp, std::ios_base::openmode mode =
194 std::ios_base::in | std::ios_base::out);
195
196 virtual int_type
197 pbackfail (int_type c = traits_type::eof ());
198
199//
200// Some future enhancements
201//
202// virtual int_type uflow();
203// virtual int_type pbackfail(int_type c = traits_type::eof());
204
205private:
206
207 /**
208 * @brief Allocate internal buffer.
209 *
210 * This function is safe to call multiple times. It will ensure
211 * that a proper internal buffer exists if it is required. If the
212 * buffer already exists or is external, the buffer pointers will be
213 * reset to their original state.
214 */
215 void
216 enable_buffer ();
217
218 /**
219 * @brief Destroy internal buffer.
220 *
221 * This function is safe to call multiple times. It will ensure
222 * that the internal buffer is deallocated if it exists. In any
223 * case, it will also reset the buffer pointers.
224 */
225 void
226 disable_buffer ();
227
228 /**
229 * Underlying file pointer.
230 */
231 gzFile m_file;
232
233 /**
234 * Mode in which file was opened.
235 */
236 std::ios_base::openmode m_io_mode;
237
238 /**
239 * @brief True if this object owns file descriptor.
240 *
241 * This makes the class responsible for closing the file
242 * upon destruction.
243 */
244 bool m_own_fd;
245
246 /**
247 * @brief Stream buffer.
248 *
249 * For simplicity this remains allocated on the free store for the
250 * entire life span of the gzfilebuf object, unless replaced by setbuf.
251 */
252 char_type *m_buffer;
253
254 /**
255 * @brief Stream buffer size.
256 *
257 * Defaults to system default buffer size (typically 8192 bytes).
258 * Modified by setbuf.
259 */
260 std::streamsize m_buffer_size;
261
262 /**
263 * @brief True if this object owns stream buffer.
264 *
265 * This makes the class responsible for deleting the buffer
266 * upon destruction.
267 */
268 bool m_own_buffer;
269};
270
271/**
272 * @brief Gzipped file input stream class.
273 *
274 * This class implements ifstream for gzipped files. Seeking and putback
275 * is not supported yet.
276*/
277class gzifstream : public std::istream
278{
279public:
280 // Default constructor
281 gzifstream ();
282
283 /**
284 * @brief Construct stream on gzipped file to be opened.
285 * @param name Filename.
286 * @param mode Open mode flags (forced to contain ios::in).
287 */
288 explicit
289 gzifstream (const char *name,
290 std::ios_base::openmode mode = std::ios_base::in);
291
292 /**
293 * @brief Construct stream on already open gzipped file.
294 * @param fd File descriptor.
295 * @param mode Open mode flags (forced to contain ios::in).
296 */
297 explicit
298 gzifstream (int fd,
299 std::ios_base::openmode mode = std::ios_base::in);
300
301 /**
302 * Obtain underlying stream buffer.
303 */
304 gzfilebuf *
305 rdbuf () const
306 { return const_cast<gzfilebuf *> (&m_sb); }
307
308 /**
309 * @brief Check if file is open.
310 * @return True if file is open.
311 */
312 bool
313 is_open () { return m_sb.is_open (); }
314
315 /**
316 * @brief Open gzipped file.
317 * @param name Filename.
318 * @param mode Open mode flags (forced to contain ios::in).
319 *
320 * Stream will be in state good() if file opens successfully;
321 * otherwise in state fail(). This differs from the behavior of
322 * ifstream, which never sets the state to good() and therefore
323 * won't allow you to reuse the stream for a second file unless
324 * you manually clear() the state. The choice is a matter of
325 * convenience.
326 */
327 void
328 open (const char *name,
329 std::ios_base::openmode mode = std::ios_base::in);
330
331 /**
332 * @brief Attach to already open gzipped file.
333 * @param fd File descriptor.
334 * @param mode Open mode flags (forced to contain ios::in).
335 *
336 * Stream will be in state good() if attach succeeded; otherwise
337 * in state fail().
338 */
339 void
340 attach (int fd,
341 std::ios_base::openmode mode = std::ios_base::in);
342
343 /**
344 * @brief Close gzipped file.
345 *
346 * Stream will be in state fail() if close failed.
347 */
348 void
349 close ();
350
351private:
352 /**
353 * Underlying stream buffer.
354 */
355 gzfilebuf m_sb;
356};
357
358/**
359 * @brief Gzipped file output stream class.
360 *
361 * This class implements ofstream for gzipped files. Seeking and putback
362 * is not supported yet.
363*/
364class gzofstream : public std::ostream
365{
366public:
367 // Default constructor
368 gzofstream ();
369
370 /**
371 * @brief Construct stream on gzipped file to be opened.
372 * @param name Filename.
373 * @param mode Open mode flags (forced to contain ios::out).
374 */
375 explicit
376 gzofstream (const char *name,
377 std::ios_base::openmode mode = std::ios_base::out);
378
379 /**
380 * @brief Construct stream on already open gzipped file.
381 * @param fd File descriptor.
382 * @param mode Open mode flags (forced to contain ios::out).
383 */
384 explicit
385 gzofstream (int fd,
386 std::ios_base::openmode mode = std::ios_base::out);
387
388 /**
389 * Obtain underlying stream buffer.
390 */
391 gzfilebuf *
392 rdbuf () const
393 { return const_cast<gzfilebuf *> (&m_sb); }
394
395 /**
396 * @brief Check if file is open.
397 * @return True if file is open.
398 */
399 bool
400 is_open () { return m_sb.is_open (); }
401
402 /**
403 * @brief Open gzipped file.
404 * @param name Filename.
405 * @param mode Open mode flags (forced to contain ios::out).
406 *
407 * Stream will be in state good() if file opens successfully;
408 * otherwise in state fail(). This differs from the behavior of
409 * ofstream, which never sets the state to good() and therefore
410 * won't allow you to reuse the stream for a second file unless
411 * you manually clear() the state. The choice is a matter of
412 * convenience.
413 */
414 void
415 open (const char *name,
416 std::ios_base::openmode mode = std::ios_base::out);
417
418 /**
419 * @brief Attach to already open gzipped file.
420 * @param fd File descriptor.
421 * @param mode Open mode flags (forced to contain ios::out).
422 *
423 * Stream will be in state good() if attach succeeded; otherwise
424 * in state fail().
425 */
426 void
427 attach (int fd,
428 std::ios_base::openmode mode = std::ios_base::out);
429
430 /**
431 * @brief Close gzipped file.
432 *
433 * Stream will be in state fail() if close failed.
434 */
435 void
436 close ();
437
438private:
439 /**
440 * Underlying stream buffer.
441 */
442 gzfilebuf m_sb;
443};
444
445/**
446 * @brief Gzipped file output stream manipulator class.
447 *
448 * This class defines a two-argument manipulator for gzofstream. It is used
449 * as base for the setcompression(int,int) manipulator.
450*/
451template <typename T1, typename T2>
453{
454public:
455 // Allows insertor to peek at internals
456 template <typename Ta, typename Tb>
459 const gzomanip2<Ta, Tb>&);
460
461 // Constructor
462 gzomanip2 (gzofstream& (*f)(gzofstream&, T1, T2),
463 T1 v1,
464 T2 v2);
465private:
466 // Underlying manipulator function
468 (*m_fcn)(gzofstream&, T1, T2);
469
470 // Arguments for manipulator function
471 T1 m_val1;
472 T2 m_val2;
473};
474
475// Manipulator function thunks through to stream buffer
476inline gzofstream&
477setcompression (gzofstream& gzs, int l, int s = Z_DEFAULT_STRATEGY)
478{
479 (gzs.rdbuf ())->setcompression (l, s);
480 return gzs;
481}
482
483// Manipulator constructor stores arguments
484template <typename T1, typename T2>
485inline
487 T1 v1,
488 T2 v2)
489 : m_fcn(f), m_val1(v1), m_val2(v2)
490{ }
491
492// Insertor applies underlying manipulator function to stream
493template <typename T1, typename T2>
496{ return (*m.m_fcn) (s, m.m_val1, m.m_val2); }
497
498// Insert this onto stream to simplify setting of compression level
500setcompression (int l, int s = Z_DEFAULT_STRATEGY)
501{ return gzomanip2<int, int> (&setcompression, l, s); }
502
503#endif
504
505#endif
Gzipped file stream buffer class.
Definition gzfstream.h:56
gzfilebuf * close()
Close gzipped file.
Definition gzfstream.cc:142
bool is_open() const
Check if file is open.
Definition gzfstream.h:86
virtual int_type underflow()
Fill get area from gzipped file.
Definition gzfstream.cc:260
virtual int_type overflow(int_type c=traits_type::eof())
Write put area to gzipped file.
Definition gzfstream.cc:303
virtual ~gzfilebuf()
Definition gzfstream.cc:68
virtual pos_type seekoff(off_type off, std::ios_base::seekdir way, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Alters the stream positions.
Definition gzfstream.cc:467
virtual int_type pbackfail(int_type c=traits_type::eof())
Definition gzfstream.cc:222
virtual std::streambuf * setbuf(char_type *p, std::streamsize n)
Installs external stream buffer.
Definition gzfstream.cc:356
gzfilebuf * open(const char *name, std::ios_base::openmode mode)
Open gzipped file.
Definition gzfstream.cc:88
virtual pos_type seekpos(pos_type sp, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::out)
Alters the stream positions.
Definition gzfstream.cc:504
bool open_mode(std::ios_base::openmode mode, char *c_mode) const
Convert ios open mode int to mode string used by zlib.
Definition gzfstream.cc:166
int setcompression(int comp_level, int comp_strategy=Z_DEFAULT_STRATEGY)
Set compression level and strategy on the fly.
Definition gzfstream.cc:81
virtual int sync()
Flush stream buffer to file.
Definition gzfstream.cc:389
gzfilebuf * attach(int fd, std::ios_base::openmode mode)
Attach to already open gzipped file.
Definition gzfstream.cc:115
virtual std::streamsize showmanyc()
Number of characters available in stream buffer.
Definition gzfstream.cc:205
Gzipped file input stream class.
Definition gzfstream.h:278
void close()
Close gzipped file.
Definition gzfstream.cc:566
void attach(int fd, std::ios_base::openmode mode=std::ios_base::in)
Attach to already open gzipped file.
Definition gzfstream.cc:556
void open(const char *name, std::ios_base::openmode mode=std::ios_base::in)
Open gzipped file.
Definition gzfstream.cc:546
bool is_open()
Check if file is open.
Definition gzfstream.h:313
gzfilebuf * rdbuf() const
Obtain underlying stream buffer.
Definition gzfstream.h:305
Gzipped file output stream class.
Definition gzfstream.h:365
gzfilebuf * rdbuf() const
Obtain underlying stream buffer.
Definition gzfstream.h:392
void close()
Close gzipped file.
Definition gzfstream.cc:615
void attach(int fd, std::ios_base::openmode mode=std::ios_base::out)
Attach to already open gzipped file.
Definition gzfstream.cc:605
bool is_open()
Check if file is open.
Definition gzfstream.h:400
void open(const char *name, std::ios_base::openmode mode=std::ios_base::out)
Open gzipped file.
Definition gzfstream.cc:595
Gzipped file output stream manipulator class.
Definition gzfstream.h:453
gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2), T1 v1, T2 v2)
Definition gzfstream.h:486
friend gzofstream & operator<<(gzofstream &, const gzomanip2< Ta, Tb > &)
gzofstream & setcompression(gzofstream &gzs, int l, int s=Z_DEFAULT_STRATEGY)
Definition gzfstream.h:477
gzofstream & operator<<(gzofstream &s, const gzomanip2< T1, T2 > &m)
Definition gzfstream.h:495
F77_RET_T const F77_DBLE const F77_DBLE * f
const octave_char_matrix & v2