Scippy

SoPlex

Sequential object-oriented simPlex

gzstream.cpp
Go to the documentation of this file.
1 #ifdef SOPLEX_WITH_ZLIB
2 
3 // ============================================================================
4 // gzstream, C++ iostream classes wrapping the zlib compression library.
5 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
6 //
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 //
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // ============================================================================
21 //
22 // File : gzstream.C
23 // Revision : $Revision: 1.8 $
24 // Revision_date : $Date: 2005/12/07 18:03:25 $
25 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner
26 //
27 // Standard streambuf implementation following Nicolai Josuttis, "The
28 // Standard C++ Library".
29 // ============================================================================
30 
31 #include "soplex/gzstream.h"
32 #include <iostream>
33 #include <string.h> // for memcpy
34 
35 #ifdef GZSTREAM_NAMESPACE
36 namespace GZSTREAM_NAMESPACE
37 {
38 #endif
39 
40 // ----------------------------------------------------------------------------
41 // Internal classes to implement gzstream. See header file for user classes.
42 // ----------------------------------------------------------------------------
43 
44 // --------------------------------------
45 // class gzstreambuf:
46 // --------------------------------------
47 
48 gzstreambuf* gzstreambuf::open(const char* _name, int _open_mode)
49 {
50  if(is_open())
51  return 0;
52 
53  mode = static_cast<unsigned int>(_open_mode);
54 
55  // no append nor read/write mode
56  if((mode & std::ios::ate) || (mode & std::ios::app)
57  || ((mode & std::ios::in) && (mode & std::ios::out)))
58  return 0;
59 
60  char fmode[10];
61  char* fmodeptr = fmode;
62 
63  if(mode & std::ios::in)
64  *fmodeptr++ = 'r';
65  else if(mode & std::ios::out)
66  *fmodeptr++ = 'w';
67 
68  *fmodeptr++ = 'b';
69  *fmodeptr = '\0';
70  file = gzopen(_name, fmode);
71 
72  if(file == 0)
73  return 0;
74 
75  opened = 1;
76  return this;
77 }
78 
79 gzstreambuf* gzstreambuf::close()
80 {
81  if(is_open())
82  {
83  sync();
84  opened = 0;
85 
86  if(gzclose(file) == Z_OK)
87  return this;
88  }
89 
90  return 0;
91 }
92 
93 int gzstreambuf::underflow() // used for input buffer only
94 {
95  if(gptr() && (gptr() < egptr()))
96  return * reinterpret_cast<unsigned char*>(gptr());
97 
98  if(!(mode & std::ios::in) || ! opened)
99  return EOF;
100 
101  // Josuttis' implementation of inbuf
102  size_t n_putback = (size_t)(gptr() - eback());
103 
104  if(n_putback > 4)
105  n_putback = 4;
106 
107  memcpy(buffer + (4 - n_putback), gptr() - n_putback, n_putback);
108 
109  int num = gzread(file, buffer + 4, bufferSize - 4);
110 
111  if(num <= 0) // ERROR or EOF
112  return EOF;
113 
114  // reset buffer pointers
115  setg(buffer + (4 - n_putback), // beginning of putback area
116  buffer + 4, // read position
117  buffer + 4 + num); // end of buffer
118 
119  // return next character
120  return * reinterpret_cast<unsigned char*>(gptr());
121 }
122 
123 int gzstreambuf::flush_buffer()
124 {
125  // Separate the writing of the buffer from overflow() and
126  // sync() operation.
127  int w = static_cast<int>(pptr() - pbase());
128 
129  if(gzwrite(file, pbase(), (unsigned int) w) != w)
130  return EOF;
131 
132  pbump(-w);
133  return w;
134 }
135 
136 int gzstreambuf::overflow(int c) // used for output buffer only
137 {
138  if(!(mode & std::ios::out) || ! opened)
139  return EOF;
140 
141  if(c != EOF)
142  {
143  *pptr() = static_cast<char>(c);
144  pbump(1);
145  }
146 
147  if(flush_buffer() == EOF)
148  return EOF;
149 
150  return c;
151 }
152 
153 int gzstreambuf::sync()
154 {
155  // Changed to use flush_buffer() instead of overflow( EOF)
156  // which caused improper behavior with std::endl and flush(),
157  // bug reported by Vincent Ricard.
158  if(pptr() && pptr() > pbase())
159  {
160  if(flush_buffer() == EOF)
161  return -1;
162  }
163 
164  return 0;
165 }
166 
167 // --------------------------------------
168 // class gzstreambase:
169 // --------------------------------------
170 
171 gzstreambase::gzstreambase(const char* name, int mode)
172 {
173  init(&buf);
174  open(name, mode);
175 }
176 
177 gzstreambase::~gzstreambase()
178 {
179  buf.close();
180 }
181 
182 void gzstreambase::open(const char* _name, int _open_mode)
183 {
184  if(! buf.open(_name, _open_mode))
185  setstate(std::ios::badbit);
186 
187  // clear( rdstate() | std::ios::badbit);
188 }
189 
190 void gzstreambase::close()
191 {
192  if(buf.is_open())
193  if(! buf.close())
194  setstate(std::ios::badbit);
195 
196  // clear( rdstate() | std::ios::badbit);
197 }
198 
199 #ifdef GZSTREAM_NAMESPACE
200 } // namespace GZSTREAM_NAMESPACE
201 #endif
202 
203 // ============================================================================
204 // EOF //
205 
206 #endif