EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gzstream.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file gzstream.cc
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 <eicsmear/gzstream.h>
30 #include <iostream>
31 #include <string.h> // for memcpy
32 
33 #ifdef GZSTREAM_NAMESPACE
34 namespace GZSTREAM_NAMESPACE {
35 #endif
36 
37 // ----------------------------------------------------------------------------
38 // Internal classes to implement gzstream. See header file for user classes.
39 // ----------------------------------------------------------------------------
40 
41 // --------------------------------------
42 // class gzstreambuf:
43 // --------------------------------------
44 
45 gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
46  if ( is_open())
47  return (gzstreambuf*)0;
48  mode = open_mode;
49  // no append nor read/write mode
50  if ((mode & std::ios::ate) || (mode & std::ios::app)
51  || ((mode & std::ios::in) && (mode & std::ios::out)))
52  return (gzstreambuf*)0;
53  char fmode[10];
54  char* fmodeptr = fmode;
55  if ( mode & std::ios::in)
56  *fmodeptr++ = 'r';
57  else if ( mode & std::ios::out)
58  *fmodeptr++ = 'w';
59  *fmodeptr++ = 'b';
60  *fmodeptr = '\0';
61  file = gzopen( name, fmode);
62  if (file == 0)
63  return (gzstreambuf*)0;
64  opened = 1;
65  return this;
66 }
67 
69  if ( is_open()) {
70  sync();
71  opened = 0;
72  if ( gzclose( file) == Z_OK)
73  return this;
74  }
75  return (gzstreambuf*)0;
76 }
77 
78 int gzstreambuf::underflow() { // used for input buffer only
79  if ( gptr() && ( gptr() < egptr()))
80  return * reinterpret_cast<unsigned char *>( gptr());
81 
82  if ( ! (mode & std::ios::in) || ! opened)
83  return EOF;
84  // Josuttis' implementation of inbuf
85  int n_putback = gptr() - eback();
86  if ( n_putback > 4)
87  n_putback = 4;
88  memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
89 
90  int num = gzread( file, buffer+4, bufferSize-4);
91  if (num <= 0) // ERROR or EOF
92  return EOF;
93 
94  // reset buffer pointers
95  setg( buffer + (4 - n_putback), // beginning of putback area
96  buffer + 4, // read position
97  buffer + 4 + num); // end of buffer
98 
99  // return next character
100  return * reinterpret_cast<unsigned char *>( gptr());
101 }
102 
104  // Separate the writing of the buffer from overflow() and
105  // sync() operation.
106  int w = pptr() - pbase();
107  if ( gzwrite( file, pbase(), w) != w)
108  return EOF;
109  pbump( -w);
110  return w;
111 }
112 
113 int gzstreambuf::overflow( int c) { // used for output buffer only
114  if ( ! ( mode & std::ios::out) || ! opened)
115  return EOF;
116  if (c != EOF) {
117  *pptr() = c;
118  pbump(1);
119  }
120  if ( flush_buffer() == EOF)
121  return EOF;
122  return c;
123 }
124 
126  // Changed to use flush_buffer() instead of overflow( EOF)
127  // which caused improper behavior with std::endl and flush(),
128  // bug reported by Vincent Ricard.
129  if ( pptr() && pptr() > pbase()) {
130  if ( flush_buffer() == EOF)
131  return -1;
132  }
133  return 0;
134 }
135 
136 // --------------------------------------
137 // class gzstreambase:
138 // --------------------------------------
139 
140 gzstreambase::gzstreambase( const char* name, int mode) {
141  init( &buf);
142  open( name, mode);
143 }
144 
146  buf.close();
147 }
148 
149 void gzstreambase::open( const char* name, int open_mode) {
150  if ( ! buf.open( name, open_mode))
151  clear( rdstate() | std::ios::badbit);
152 }
153 
155  if ( buf.is_open())
156  if ( ! buf.close())
157  clear( rdstate() | std::ios::badbit);
158 }
159 
160 #ifdef GZSTREAM_NAMESPACE
161 } // namespace GZSTREAM_NAMESPACE
162 #endif
163 
164 // ============================================================================
165 // EOF //