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