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