Scippy

SoPlex

Sequential object-oriented simPlex

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