1 /**
2  * \file gzfstream.hxx
3  * A C++ I/O streams interface to the zlib gz* functions.
4  */
5 
6 // Written by Bernie Bright, 1998
7 // Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
8 //
9 // Copyright (C) 1998  Bernie Bright - bbright@c031.aone.net.au
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Library General Public
13 // License as published by the Free Software Foundation; either
14 // version 2 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 // Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
24 //
25 // $Id$
26 
27 #ifndef _gzfstream_hxx
28 #define _gzfstream_hxx
29 
30 #include <simgear/compiler.h>
31 
32 #include <zlib.h>
33 
34 
35 #include <streambuf>
36 #include <istream>
37 
38 #define ios_openmode std::ios_base::openmode
39 #define ios_in       std::ios_base::in
40 #define ios_out      std::ios_base::out
41 #define ios_app      std::ios_base::app
42 #define ios_binary   std::ios_base::binary
43 
44 #define ios_seekdir  std::ios_base::seekdir
45 
46 #define ios_badbit   std::ios_base::badbit
47 #define ios_failbit  std::ios_base::failbit
48 
49 /**
50  * A C++ I/O streams interface to the zlib gz* functions.
51  */
52 #ifdef SG_NEED_STREAMBUF_HACK
53 class gzfilebuf : public __streambuf {
54     typedef __streambuf parent;
55 #else
56 class gzfilebuf : public std::streambuf {
57     typedef std::streambuf parent;
58 #endif
59 
60 public:
61     /** Constructor */
62     gzfilebuf();
63 
64     /** Destructor */
65     virtual ~gzfilebuf();
66 
67     /**
68      * Open a stream
69      * @param name file name, UTF-8 encoded
70      * @param io_mode mode flags
71      * @return file stream
72      */
73     gzfilebuf* open( const char* name, ios_openmode io_mode );
74 
75     /**
76      * Attach to an existing file descriptor
77      * @param file_descriptor file descriptor
78      * @param io_mode mode flags
79      * @return file stream
80      */
81     gzfilebuf* attach( int file_descriptor, ios_openmode io_mode );
82 
83     /** Close stream */
84     gzfilebuf* close();
85 
86     int setcompressionlevel( int comp_level );
87     int setcompressionstrategy( int comp_strategy );
88 
89     /** @return true if open, false otherwise */
is_open() const90     bool is_open() const { return (file != NULL); }
91 
92     /**
93      * @return the current offset in the file being read or written.
94      * The offset corresponds to compressed data if the file is compressed,
95      * and is influenced by buffering performed in zlib, hence the "approx"
96      * qualifier. It should be suitable for progress indicators and such,
97      * though.
98      */
99     z_off_t approxOffset();
100 
101     /** @return stream position */
102     virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, ios_openmode which );
103 
104     /** sync the stream */
105     virtual int sync();
106 
107 protected:
108 
109     virtual int_type underflow();
110 
111     virtual int_type overflow( int_type c = parent::traits_type::eof() );
112     bool    out_waiting();
base()113     char*   base() {return obuffer;}
blen()114     int     blen() {return obuf_size;}
115     char    allocate();
116 
117 private:
118 
119     int_type flushbuf();
120     int fillbuf();
121 
122     // Convert io_mode to "rwab" string.
123     void cvt_iomode( char* mode_str, ios_openmode io_mode );
124 
125 private:
126 
127     gzFile file;
128     ios_openmode mode;
129     bool own_file_descriptor;
130 
131     // Get (input) buffer.
132     int ibuf_size;
133     char* ibuffer;
134 
135     // Put (output) buffer.
136     int obuf_size;
137     char* obuffer;
138 
139     enum { page_size = 65536 };
140 
141 private:
142     // Not defined
143     gzfilebuf( const gzfilebuf& );
144     void operator= ( const gzfilebuf& );
145 };
146 
147 /**
148  * document me
149  */
150 struct gzifstream_base
151 {
gzifstream_basegzifstream_base152     gzifstream_base() {}
153 
154     gzfilebuf gzbuf;
155 };
156 
157 /**
158  * document me too
159  */
160 struct gzofstream_base
161 {
gzofstream_basegzofstream_base162     gzofstream_base() {}
163 
164     gzfilebuf gzbuf;
165 };
166 
167 #endif // _gzfstream_hxx
168