Jpp
gzstream.h
Go to the documentation of this file.
1 /**
2  * \author mdejong
3  */
4 
5 // ============================================================================
6 // gzstream, C++ iostream classes wrapping the zlib compression library.
7 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 // ============================================================================
23 //
24 // File : gzstream.h
25 // Revision : $Revision: 1.5 $
26 // Revision_date : $Date: 2002/04/26 23:30:15 $
27 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner
28 //
29 // Standard streambuf implementation following Nicolai Josuttis, "The
30 // Standard C++ Library".
31 // ============================================================================
32 
33 #ifndef GZSTREAM_H
34 #define GZSTREAM_H 1
35 
36 // standard C++ with new header file names and std:: namespace
37 #include <iostream>
38 #include <fstream>
39 #include <zlib.h>
40 #include <string>
41 #include <string.h>
42 
43 #ifdef GZSTREAM_NAMESPACE
44 namespace GZSTREAM_NAMESPACE {
45 #endif
46 
47 // ----------------------------------------------------------------------------
48 // Internal classes to implement gzstream. See below for user classes.
49 // ----------------------------------------------------------------------------
50 
51 class gzstreambuf : public std::streambuf {
52 private:
53  static const int bufferSize = 47+256; // size of data buff
54  // totals 512 bytes under g++ for igzstream at the end.
55 
56  gzFile file; // file handle for compressed file
57  char buffer[bufferSize]; // data buffer
58  char opened; // open/close state of stream
59  int mode; // I/O mode
60 
61 
62  int flush_buffer() {
63  // Separate the writing of the buffer from overflow() and
64  // sync() operation.
65  int w = pptr() - pbase();
66  if ( gzwrite( file, pbase(), w) != w)
67  return EOF;
68  pbump( -w);
69  return w;
70  }
71 public:
72  gzstreambuf() : opened(0) {
73  setp( buffer, buffer + (bufferSize-1));
74  setg( buffer + 4, // beginning of putback area
75  buffer + 4, // read position
76  buffer + 4); // end position
77  // ASSERT: both input & output capabilities will not be used together
78  }
79  int is_open() const { return opened; }
80 
82  gzstreambuf* open( const char* name, int open_mode) {
83  if ( is_open())
84  return (gzstreambuf*)0;
85  mode = open_mode;
86  // no append nor read/write mode
87  if ((mode & std::ios::ate) || (mode & std::ios::app)
88  || ((mode & std::ios::in) && (mode & std::ios::out)))
89  return (gzstreambuf*)0;
90  char fmode[10];
91  char* fmodeptr = fmode;
92  if ( mode & std::ios::in)
93  *fmodeptr++ = 'r';
94  else if ( mode & std::ios::out)
95  *fmodeptr++ = 'w';
96  *fmodeptr++ = 'b';
97  *fmodeptr = '\0';
98  file = gzopen( name, fmode);
99  if (file == 0)
100  return (gzstreambuf*)0;
101  opened = 1;
102  setg( buffer + 4, // beginning of putback area
103  buffer + 4, // read position
104  buffer + 4); // end position
105  return this;
106  }
107 
109  if ( is_open()) {
110  sync();
111  opened = 0;
112  if ( gzclose( file) == Z_OK)
113  return this;
114  }
115  return (gzstreambuf*)0;
116  }
117 
118  virtual int underflow() { // used for input buffer only
119  if ( gptr() && ( gptr() < egptr()))
120  return * reinterpret_cast<unsigned char *>( gptr());
121 
122  if ( ! (mode & std::ios::in) || ! opened)
123  return EOF;
124  // Josuttis' implementation of inbuf
125  int n_putback = gptr() - eback();
126  if ( n_putback > 4)
127  n_putback = 4;
128  memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
129 
130  int num = gzread( file, buffer+4, bufferSize-4);
131  if (num <= 0) // ERROR or EOF
132  return EOF;
133 
134  // reset buffer pointers
135  setg( buffer + (4 - n_putback), // beginning of putback area
136  buffer + 4, // read position
137  buffer + 4 + num); // end of buffer
138 
139  // return next character
140  return * reinterpret_cast<unsigned char *>( gptr());
141  }
142 
143  virtual int overflow( int c=EOF) { // used for output buffer only
144  if ( ! ( mode & std::ios::out) || ! opened)
145  return EOF;
146  if (c != EOF) {
147  *pptr() = c;
148  pbump(1);
149  }
150  if ( flush_buffer() == EOF)
151  return EOF;
152  return c;
153  }
154 
155  virtual int sync() {
156  // Changed to use flush_buffer() instead of overflow( EOF)
157  // which caused improper behavior with std::endl and flush(),
158  // bug reported by Vincent Ricard.
159  if ( pptr() && pptr() > pbase()) {
160  if ( flush_buffer() == EOF)
161  return -1;
162  }
163  return 0;
164  }
165 };
166 
167 class gzstreambase : virtual public std::ios {
168 protected:
170 public:
171 
172  gzstreambase() { init(&buf); }
173  gzstreambase( const char* name, int mode) {
174  init( &buf);
175  open( name, mode);
176  }
178  buf.close();
179  }
180  void open( const char* name, int open_mode) {
181  if ( ! buf.open( name, open_mode))
182  clear( rdstate() | std::ios::badbit);
183  }
184 
185  void close() {
186  if ( buf.is_open()) {
187  if ( ! buf.close())
188  clear( rdstate() | std::ios::badbit );
189  else
190  clear();
191  }
192  }
193  gzstreambuf* rdbuf() { return &buf; }
194  bool is_open() const { return buf.is_open(); }
195 };
196 
197 // ----------------------------------------------------------------------------
198 // User classes. Use igzstream and ogzstream analogously to ifstream and
199 // ofstream respectively. They read and write files based on the gz*
200 // function interface of the zlib. Files are compatible with gzip compression.
201 // ----------------------------------------------------------------------------
202 
203 class igzstream : public gzstreambase, public std::istream {
204 public:
205  igzstream() : std::istream( &buf) {}
206  igzstream( const char* name, int open_mode = std::ios::in)
207  : gzstreambase( name, open_mode), std::istream( &buf) {}
208  void open( const char* name, int open_mode = std::ios::in) {
209  gzstreambase::open( name, open_mode);
210  }
211 };
212 
213 class ogzstream : public gzstreambase, public std::ostream {
214 public:
215  ogzstream() : std::ostream( &buf) {}
216  ogzstream( const char* name, int mode = std::ios::out)
217  : gzstreambase( name, mode), std::ostream( &buf) {}
218  void open( const char* name, int open_mode = std::ios::out) {
219  gzstreambase::open( name, open_mode);
220  }
221 };
222 
223 #ifdef GZSTREAM_NAMESPACE
224 } // namespace GZSTREAM_NAMESPACE
225 #endif
226 
227 #endif // GZSTREAM_H
228 // ============================================================================
229 // EOF //
gzstreambuf::gzstreambuf
gzstreambuf()
Definition: gzstream.h:72
JEEP::close
void close(std::istream *pf)
Close file.
Definition: JeepToolkit.hh:342
gzstreambuf::open
gzstreambuf * open(const char *name, int open_mode)
Definition: gzstream.h:82
JTOOLS::w
data_type w[N+1][M+1]
Definition: JPolint.hh:708
igzstream::open
void open(const char *name, int open_mode=std::ios::in)
Definition: gzstream.h:208
gzstreambase::close
void close()
Definition: gzstream.h:185
igzstream
Definition: gzstream.h:203
gzstreambuf::opened
char opened
Definition: gzstream.h:58
gzstreambuf::file
gzFile file
Definition: gzstream.h:56
igzstream::igzstream
igzstream()
Definition: gzstream.h:205
gzstreambuf
Definition: gzstream.h:51
ogzstream
Definition: gzstream.h:213
gzstreambuf::flush_buffer
int flush_buffer()
Definition: gzstream.h:62
ogzstream::open
void open(const char *name, int open_mode=std::ios::out)
Definition: gzstream.h:218
gzstreambuf::overflow
virtual int overflow(int c=EOF)
Definition: gzstream.h:143
gzstreambase::gzstreambase
gzstreambase()
Definition: gzstream.h:172
gzstreambase::gzstreambase
gzstreambase(const char *name, int mode)
Definition: gzstream.h:173
JEEP::open
T * open(const std::string &file_name)
Open file.
Definition: JeepToolkit.hh:302
gzstreambuf::~gzstreambuf
~gzstreambuf()
Definition: gzstream.h:81
gzstreambuf::close
gzstreambuf * close()
Definition: gzstream.h:108
gzstreambuf::mode
int mode
Definition: gzstream.h:59
ogzstream::ogzstream
ogzstream(const char *name, int mode=std::ios::out)
Definition: gzstream.h:216
std
Definition: jaanetDictionary.h:36
gzstreambase::is_open
bool is_open() const
Definition: gzstream.h:194
gzstreambase::~gzstreambase
~gzstreambase()
Definition: gzstream.h:177
gzstreambuf::sync
virtual int sync()
Definition: gzstream.h:155
igzstream::igzstream
igzstream(const char *name, int open_mode=std::ios::in)
Definition: gzstream.h:206
gzstreambuf::underflow
virtual int underflow()
Definition: gzstream.h:118
gzstreambase::buf
gzstreambuf buf
Definition: gzstream.h:169
ogzstream::ogzstream
ogzstream()
Definition: gzstream.h:215
gzstreambase::rdbuf
gzstreambuf * rdbuf()
Definition: gzstream.h:193
gzstreambase::open
void open(const char *name, int open_mode)
Definition: gzstream.h:180
gzstreambuf::is_open
int is_open() const
Definition: gzstream.h:79
gzstreambase
Definition: gzstream.h:167