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