1275793eaSopenharmony_ci
2275793eaSopenharmony_ci#include "zfstream.h"
3275793eaSopenharmony_ci
4275793eaSopenharmony_cigzfilebuf::gzfilebuf() :
5275793eaSopenharmony_ci  file(NULL),
6275793eaSopenharmony_ci  mode(0),
7275793eaSopenharmony_ci  own_file_descriptor(0)
8275793eaSopenharmony_ci{ }
9275793eaSopenharmony_ci
10275793eaSopenharmony_cigzfilebuf::~gzfilebuf() {
11275793eaSopenharmony_ci
12275793eaSopenharmony_ci  sync();
13275793eaSopenharmony_ci  if ( own_file_descriptor )
14275793eaSopenharmony_ci    close();
15275793eaSopenharmony_ci
16275793eaSopenharmony_ci}
17275793eaSopenharmony_ci
18275793eaSopenharmony_cigzfilebuf *gzfilebuf::open( const char *name,
19275793eaSopenharmony_ci                            int io_mode ) {
20275793eaSopenharmony_ci
21275793eaSopenharmony_ci  if ( is_open() )
22275793eaSopenharmony_ci    return NULL;
23275793eaSopenharmony_ci
24275793eaSopenharmony_ci  char char_mode[10];
25275793eaSopenharmony_ci  char *p = char_mode;
26275793eaSopenharmony_ci
27275793eaSopenharmony_ci  if ( io_mode & ios::in ) {
28275793eaSopenharmony_ci    mode = ios::in;
29275793eaSopenharmony_ci    *p++ = 'r';
30275793eaSopenharmony_ci  } else if ( io_mode & ios::app ) {
31275793eaSopenharmony_ci    mode = ios::app;
32275793eaSopenharmony_ci    *p++ = 'a';
33275793eaSopenharmony_ci  } else {
34275793eaSopenharmony_ci    mode = ios::out;
35275793eaSopenharmony_ci    *p++ = 'w';
36275793eaSopenharmony_ci  }
37275793eaSopenharmony_ci
38275793eaSopenharmony_ci  if ( io_mode & ios::binary ) {
39275793eaSopenharmony_ci    mode |= ios::binary;
40275793eaSopenharmony_ci    *p++ = 'b';
41275793eaSopenharmony_ci  }
42275793eaSopenharmony_ci
43275793eaSopenharmony_ci  // Hard code the compression level
44275793eaSopenharmony_ci  if ( io_mode & (ios::out|ios::app )) {
45275793eaSopenharmony_ci    *p++ = '9';
46275793eaSopenharmony_ci  }
47275793eaSopenharmony_ci
48275793eaSopenharmony_ci  // Put the end-of-string indicator
49275793eaSopenharmony_ci  *p = '\0';
50275793eaSopenharmony_ci
51275793eaSopenharmony_ci  if ( (file = gzopen(name, char_mode)) == NULL )
52275793eaSopenharmony_ci    return NULL;
53275793eaSopenharmony_ci
54275793eaSopenharmony_ci  own_file_descriptor = 1;
55275793eaSopenharmony_ci
56275793eaSopenharmony_ci  return this;
57275793eaSopenharmony_ci
58275793eaSopenharmony_ci}
59275793eaSopenharmony_ci
60275793eaSopenharmony_cigzfilebuf *gzfilebuf::attach( int file_descriptor,
61275793eaSopenharmony_ci                              int io_mode ) {
62275793eaSopenharmony_ci
63275793eaSopenharmony_ci  if ( is_open() )
64275793eaSopenharmony_ci    return NULL;
65275793eaSopenharmony_ci
66275793eaSopenharmony_ci  char char_mode[10];
67275793eaSopenharmony_ci  char *p = char_mode;
68275793eaSopenharmony_ci
69275793eaSopenharmony_ci  if ( io_mode & ios::in ) {
70275793eaSopenharmony_ci    mode = ios::in;
71275793eaSopenharmony_ci    *p++ = 'r';
72275793eaSopenharmony_ci  } else if ( io_mode & ios::app ) {
73275793eaSopenharmony_ci    mode = ios::app;
74275793eaSopenharmony_ci    *p++ = 'a';
75275793eaSopenharmony_ci  } else {
76275793eaSopenharmony_ci    mode = ios::out;
77275793eaSopenharmony_ci    *p++ = 'w';
78275793eaSopenharmony_ci  }
79275793eaSopenharmony_ci
80275793eaSopenharmony_ci  if ( io_mode & ios::binary ) {
81275793eaSopenharmony_ci    mode |= ios::binary;
82275793eaSopenharmony_ci    *p++ = 'b';
83275793eaSopenharmony_ci  }
84275793eaSopenharmony_ci
85275793eaSopenharmony_ci  // Hard code the compression level
86275793eaSopenharmony_ci  if ( io_mode & (ios::out|ios::app )) {
87275793eaSopenharmony_ci    *p++ = '9';
88275793eaSopenharmony_ci  }
89275793eaSopenharmony_ci
90275793eaSopenharmony_ci  // Put the end-of-string indicator
91275793eaSopenharmony_ci  *p = '\0';
92275793eaSopenharmony_ci
93275793eaSopenharmony_ci  if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
94275793eaSopenharmony_ci    return NULL;
95275793eaSopenharmony_ci
96275793eaSopenharmony_ci  own_file_descriptor = 0;
97275793eaSopenharmony_ci
98275793eaSopenharmony_ci  return this;
99275793eaSopenharmony_ci
100275793eaSopenharmony_ci}
101275793eaSopenharmony_ci
102275793eaSopenharmony_cigzfilebuf *gzfilebuf::close() {
103275793eaSopenharmony_ci
104275793eaSopenharmony_ci  if ( is_open() ) {
105275793eaSopenharmony_ci
106275793eaSopenharmony_ci    sync();
107275793eaSopenharmony_ci    gzclose( file );
108275793eaSopenharmony_ci    file = NULL;
109275793eaSopenharmony_ci
110275793eaSopenharmony_ci  }
111275793eaSopenharmony_ci
112275793eaSopenharmony_ci  return this;
113275793eaSopenharmony_ci
114275793eaSopenharmony_ci}
115275793eaSopenharmony_ci
116275793eaSopenharmony_ciint gzfilebuf::setcompressionlevel( int comp_level ) {
117275793eaSopenharmony_ci
118275793eaSopenharmony_ci  return gzsetparams(file, comp_level, -2);
119275793eaSopenharmony_ci
120275793eaSopenharmony_ci}
121275793eaSopenharmony_ci
122275793eaSopenharmony_ciint gzfilebuf::setcompressionstrategy( int comp_strategy ) {
123275793eaSopenharmony_ci
124275793eaSopenharmony_ci  return gzsetparams(file, -2, comp_strategy);
125275793eaSopenharmony_ci
126275793eaSopenharmony_ci}
127275793eaSopenharmony_ci
128275793eaSopenharmony_ci
129275793eaSopenharmony_cistreampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
130275793eaSopenharmony_ci
131275793eaSopenharmony_ci  return streampos(EOF);
132275793eaSopenharmony_ci
133275793eaSopenharmony_ci}
134275793eaSopenharmony_ci
135275793eaSopenharmony_ciint gzfilebuf::underflow() {
136275793eaSopenharmony_ci
137275793eaSopenharmony_ci  // If the file hasn't been opened for reading, error.
138275793eaSopenharmony_ci  if ( !is_open() || !(mode & ios::in) )
139275793eaSopenharmony_ci    return EOF;
140275793eaSopenharmony_ci
141275793eaSopenharmony_ci  // if a buffer doesn't exists, allocate one.
142275793eaSopenharmony_ci  if ( !base() ) {
143275793eaSopenharmony_ci
144275793eaSopenharmony_ci    if ( (allocate()) == EOF )
145275793eaSopenharmony_ci      return EOF;
146275793eaSopenharmony_ci    setp(0,0);
147275793eaSopenharmony_ci
148275793eaSopenharmony_ci  } else {
149275793eaSopenharmony_ci
150275793eaSopenharmony_ci    if ( in_avail() )
151275793eaSopenharmony_ci      return (unsigned char) *gptr();
152275793eaSopenharmony_ci
153275793eaSopenharmony_ci    if ( out_waiting() ) {
154275793eaSopenharmony_ci      if ( flushbuf() == EOF )
155275793eaSopenharmony_ci        return EOF;
156275793eaSopenharmony_ci    }
157275793eaSopenharmony_ci
158275793eaSopenharmony_ci  }
159275793eaSopenharmony_ci
160275793eaSopenharmony_ci  // Attempt to fill the buffer.
161275793eaSopenharmony_ci
162275793eaSopenharmony_ci  int result = fillbuf();
163275793eaSopenharmony_ci  if ( result == EOF ) {
164275793eaSopenharmony_ci    // disable get area
165275793eaSopenharmony_ci    setg(0,0,0);
166275793eaSopenharmony_ci    return EOF;
167275793eaSopenharmony_ci  }
168275793eaSopenharmony_ci
169275793eaSopenharmony_ci  return (unsigned char) *gptr();
170275793eaSopenharmony_ci
171275793eaSopenharmony_ci}
172275793eaSopenharmony_ci
173275793eaSopenharmony_ciint gzfilebuf::overflow( int c ) {
174275793eaSopenharmony_ci
175275793eaSopenharmony_ci  if ( !is_open() || !(mode & ios::out) )
176275793eaSopenharmony_ci    return EOF;
177275793eaSopenharmony_ci
178275793eaSopenharmony_ci  if ( !base() ) {
179275793eaSopenharmony_ci    if ( allocate() == EOF )
180275793eaSopenharmony_ci      return EOF;
181275793eaSopenharmony_ci    setg(0,0,0);
182275793eaSopenharmony_ci  } else {
183275793eaSopenharmony_ci    if (in_avail()) {
184275793eaSopenharmony_ci        return EOF;
185275793eaSopenharmony_ci    }
186275793eaSopenharmony_ci    if (out_waiting()) {
187275793eaSopenharmony_ci      if (flushbuf() == EOF)
188275793eaSopenharmony_ci        return EOF;
189275793eaSopenharmony_ci    }
190275793eaSopenharmony_ci  }
191275793eaSopenharmony_ci
192275793eaSopenharmony_ci  int bl = blen();
193275793eaSopenharmony_ci  setp( base(), base() + bl);
194275793eaSopenharmony_ci
195275793eaSopenharmony_ci  if ( c != EOF ) {
196275793eaSopenharmony_ci
197275793eaSopenharmony_ci    *pptr() = c;
198275793eaSopenharmony_ci    pbump(1);
199275793eaSopenharmony_ci
200275793eaSopenharmony_ci  }
201275793eaSopenharmony_ci
202275793eaSopenharmony_ci  return 0;
203275793eaSopenharmony_ci
204275793eaSopenharmony_ci}
205275793eaSopenharmony_ci
206275793eaSopenharmony_ciint gzfilebuf::sync() {
207275793eaSopenharmony_ci
208275793eaSopenharmony_ci  if ( !is_open() )
209275793eaSopenharmony_ci    return EOF;
210275793eaSopenharmony_ci
211275793eaSopenharmony_ci  if ( out_waiting() )
212275793eaSopenharmony_ci    return flushbuf();
213275793eaSopenharmony_ci
214275793eaSopenharmony_ci  return 0;
215275793eaSopenharmony_ci
216275793eaSopenharmony_ci}
217275793eaSopenharmony_ci
218275793eaSopenharmony_ciint gzfilebuf::flushbuf() {
219275793eaSopenharmony_ci
220275793eaSopenharmony_ci  int n;
221275793eaSopenharmony_ci  char *q;
222275793eaSopenharmony_ci
223275793eaSopenharmony_ci  q = pbase();
224275793eaSopenharmony_ci  n = pptr() - q;
225275793eaSopenharmony_ci
226275793eaSopenharmony_ci  if ( gzwrite( file, q, n) < n )
227275793eaSopenharmony_ci    return EOF;
228275793eaSopenharmony_ci
229275793eaSopenharmony_ci  setp(0,0);
230275793eaSopenharmony_ci
231275793eaSopenharmony_ci  return 0;
232275793eaSopenharmony_ci
233275793eaSopenharmony_ci}
234275793eaSopenharmony_ci
235275793eaSopenharmony_ciint gzfilebuf::fillbuf() {
236275793eaSopenharmony_ci
237275793eaSopenharmony_ci  int required;
238275793eaSopenharmony_ci  char *p;
239275793eaSopenharmony_ci
240275793eaSopenharmony_ci  p = base();
241275793eaSopenharmony_ci
242275793eaSopenharmony_ci  required = blen();
243275793eaSopenharmony_ci
244275793eaSopenharmony_ci  int t = gzread( file, p, required );
245275793eaSopenharmony_ci
246275793eaSopenharmony_ci  if ( t <= 0) return EOF;
247275793eaSopenharmony_ci
248275793eaSopenharmony_ci  setg( base(), base(), base()+t);
249275793eaSopenharmony_ci
250275793eaSopenharmony_ci  return t;
251275793eaSopenharmony_ci
252275793eaSopenharmony_ci}
253275793eaSopenharmony_ci
254275793eaSopenharmony_cigzfilestream_common::gzfilestream_common() :
255275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
256275793eaSopenharmony_ci{ }
257275793eaSopenharmony_ci
258275793eaSopenharmony_cigzfilestream_common::~gzfilestream_common()
259275793eaSopenharmony_ci{ }
260275793eaSopenharmony_ci
261275793eaSopenharmony_civoid gzfilestream_common::attach( int fd, int io_mode ) {
262275793eaSopenharmony_ci
263275793eaSopenharmony_ci  if ( !buffer.attach( fd, io_mode) )
264275793eaSopenharmony_ci    clear( ios::failbit | ios::badbit );
265275793eaSopenharmony_ci  else
266275793eaSopenharmony_ci    clear();
267275793eaSopenharmony_ci
268275793eaSopenharmony_ci}
269275793eaSopenharmony_ci
270275793eaSopenharmony_civoid gzfilestream_common::open( const char *name, int io_mode ) {
271275793eaSopenharmony_ci
272275793eaSopenharmony_ci  if ( !buffer.open( name, io_mode ) )
273275793eaSopenharmony_ci    clear( ios::failbit | ios::badbit );
274275793eaSopenharmony_ci  else
275275793eaSopenharmony_ci    clear();
276275793eaSopenharmony_ci
277275793eaSopenharmony_ci}
278275793eaSopenharmony_ci
279275793eaSopenharmony_civoid gzfilestream_common::close() {
280275793eaSopenharmony_ci
281275793eaSopenharmony_ci  if ( !buffer.close() )
282275793eaSopenharmony_ci    clear( ios::failbit | ios::badbit );
283275793eaSopenharmony_ci
284275793eaSopenharmony_ci}
285275793eaSopenharmony_ci
286275793eaSopenharmony_cigzfilebuf *gzfilestream_common::rdbuf()
287275793eaSopenharmony_ci{
288275793eaSopenharmony_ci  return &buffer;
289275793eaSopenharmony_ci}
290275793eaSopenharmony_ci
291275793eaSopenharmony_cigzifstream::gzifstream() :
292275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
293275793eaSopenharmony_ci{
294275793eaSopenharmony_ci  clear( ios::badbit );
295275793eaSopenharmony_ci}
296275793eaSopenharmony_ci
297275793eaSopenharmony_cigzifstream::gzifstream( const char *name, int io_mode ) :
298275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
299275793eaSopenharmony_ci{
300275793eaSopenharmony_ci  gzfilestream_common::open( name, io_mode );
301275793eaSopenharmony_ci}
302275793eaSopenharmony_ci
303275793eaSopenharmony_cigzifstream::gzifstream( int fd, int io_mode ) :
304275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
305275793eaSopenharmony_ci{
306275793eaSopenharmony_ci  gzfilestream_common::attach( fd, io_mode );
307275793eaSopenharmony_ci}
308275793eaSopenharmony_ci
309275793eaSopenharmony_cigzifstream::~gzifstream() { }
310275793eaSopenharmony_ci
311275793eaSopenharmony_cigzofstream::gzofstream() :
312275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
313275793eaSopenharmony_ci{
314275793eaSopenharmony_ci  clear( ios::badbit );
315275793eaSopenharmony_ci}
316275793eaSopenharmony_ci
317275793eaSopenharmony_cigzofstream::gzofstream( const char *name, int io_mode ) :
318275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
319275793eaSopenharmony_ci{
320275793eaSopenharmony_ci  gzfilestream_common::open( name, io_mode );
321275793eaSopenharmony_ci}
322275793eaSopenharmony_ci
323275793eaSopenharmony_cigzofstream::gzofstream( int fd, int io_mode ) :
324275793eaSopenharmony_ci  ios( gzfilestream_common::rdbuf() )
325275793eaSopenharmony_ci{
326275793eaSopenharmony_ci  gzfilestream_common::attach( fd, io_mode );
327275793eaSopenharmony_ci}
328275793eaSopenharmony_ci
329275793eaSopenharmony_cigzofstream::~gzofstream() { }
330