ARTS  2.0.49
gzstream.cc
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.C
21 // Revision : $Revision: 1.7 $
22 // Revision_date : $Date: 2003/01/08 14:41:27 $
23 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner
24 //
25 // Standard streambuf implementation following Nicolai Josuttis, "The
26 // Standard C++ Library".
27 // ============================================================================
28 
29 #include <cstring> // for memcpy
30 #include "gzstream.h"
31 
32 #ifdef GZSTREAM_NAMESPACE
33 namespace GZSTREAM_NAMESPACE {
34 #endif
35 
36 // ----------------------------------------------------------------------------
37 // Internal classes to implement gzstream. See header file for user classes.
38 // ----------------------------------------------------------------------------
39 
40 // --------------------------------------
41 // class gzstreambuf:
42 // --------------------------------------
43 
44 gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
45  if ( is_open())
46  return (gzstreambuf*)0;
47  mode = open_mode;
48  // no append nor read/write mode
49  if ((mode & std::ios::ate) || (mode & std::ios::app)
50  || ((mode & std::ios::in) && (mode & std::ios::out)))
51  return (gzstreambuf*)0;
52  char fmode[10];
53  char* fmodeptr = fmode;
54  if ( mode & std::ios::in)
55  *fmodeptr++ = 'r';
56  else if ( mode & std::ios::out)
57  *fmodeptr++ = 'w';
58  *fmodeptr++ = 'b';
59  *fmodeptr = '\0';
60  file = gzopen( name, fmode);
61  if (file == 0)
62  return (gzstreambuf*)0;
63  opened = 1;
64  return this;
65 }
66 
68  if ( is_open()) {
69  sync();
70  opened = 0;
71  if ( gzclose( file) == Z_OK)
72  return this;
73  }
74  return (gzstreambuf*)0;
75 }
76 
77 int gzstreambuf::underflow() { // used for input buffer only
78  if ( gptr() && ( gptr() < egptr()))
79  return * reinterpret_cast<unsigned char *>( gptr());
80 
81  if ( ! (mode & std::ios::in) || ! opened)
82  return EOF;
83  // Josuttis' implementation of inbuf
84  int n_putback = (int)(gptr() - eback());
85  if ( n_putback > 4)
86  n_putback = 4;
87  memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
88 
89  int num = gzread( file, buffer+4, bufferSize-4);
90  if (num <= 0) // ERROR or EOF
91  return EOF;
92 
93  // reset buffer pointers
94  setg( buffer + (4 - n_putback), // beginning of putback area
95  buffer + 4, // read position
96  buffer + 4 + num); // end of buffer
97 
98  // return next character
99  return * reinterpret_cast<unsigned char *>( gptr());
100 }
101 
103  // Separate the writing of the buffer from overflow() and
104  // sync() operation.
105  int w = (int)(pptr() - pbase());
106  if ( gzwrite( file, pbase(), w) != w)
107  return EOF;
108  pbump( -w);
109  return w;
110 }
111 
112 int gzstreambuf::overflow( int c) { // used for output buffer only
113  if ( ! ( mode & std::ios::out) || ! opened)
114  return EOF;
115  if (c != EOF) {
116  *pptr() = (char)c;
117  pbump(1);
118  }
119  if ( flush_buffer() == EOF)
120  return EOF;
121  return c;
122 }
123 
125  // Changed to use flush_buffer() instead of overflow( EOF)
126  // which caused improper behavior with std::endl and flush(),
127  // bug reported by Vincent Ricard.
128  if ( pptr() && pptr() > pbase()) {
129  if ( flush_buffer() == EOF)
130  return -1;
131  }
132  return 0;
133 }
134 
135 // --------------------------------------
136 // class gzstreambase:
137 // --------------------------------------
138 
139 gzstreambase::gzstreambase( const char* name, int mode) {
140  init( &buf);
141  open( name, mode);
142 }
143 
145  buf.close();
146 }
147 
148 void gzstreambase::open( const char* name, int gz_open_mode) {
149  if ( ! buf.open( name, gz_open_mode))
150  clear( rdstate() | std::ios::badbit);
151 }
152 
154  if ( buf.is_open())
155  if ( ! buf.close())
156  clear( rdstate() | std::ios::badbit);
157 }
158 
159 #ifdef GZSTREAM_NAMESPACE
160 } // namespace GZSTREAM_NAMESPACE
161 #endif
162 
163 // ============================================================================
164 // EOF //
gzstreambuf::close
gzstreambuf * close()
Definition: gzstream.cc:67
gzstreambuf::overflow
virtual int overflow(int c=EOF)
Definition: gzstream.cc:112
gzstreambuf::sync
virtual int sync()
Definition: gzstream.cc:124
gzstreambase::close
void close()
Definition: gzstream.cc:153
gzstreambuf
Definition: gzstream.h:45
gzstreambuf::flush_buffer
int flush_buffer()
Definition: gzstream.cc:102
gzstreambuf::open
gzstreambuf * open(const char *name, int open_mode)
Definition: gzstream.cc:44
gzstreambase::gzstreambase
gzstreambase()
Definition: gzstream.h:78
gzstream.h
gzstreambuf::underflow
virtual int underflow()
Definition: gzstream.cc:77
gzstreambase::~gzstreambase
~gzstreambase()
Definition: gzstream.cc:144
gzstreambase::open
void open(const char *name, int open_mode)
Definition: gzstream.cc:148