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