PandA-2024.02
gzstream.hpp
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.h
21 // Revision : $Revision: 1.5 $
22 // Revision_date : $Date: 2002/04/26 23:30:15 $
23 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner
24 //
25 // Standard streambuf implementation following Nicolai Josuttis, "The
26 // Standard C++ Library".
27 // ============================================================================
28 /*
29  *
30  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
31  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
32  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
33  * _/ _/ _/ _/ _/ _/ _/ _/ _/
34  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
35  *
36  * ***********************************************
37  * PandA Project
38  * URL: http://panda.dei.polimi.it
39  * Politecnico di Milano - DEIB
40  * System Architectures Group
41  * ***********************************************
42  * Copyright (C) 2004-2024 Politecnico di Milano
43  *
44  * This file is part of the PandA framework.
45  *
46  * The PandA framework is free software; you can redistribute it and/or modify
47  * it under the terms of the GNU General Public License as published by
48  * the Free Software Foundation; either version 3 of the License, or
49  * (at your option) any later version.
50  *
51  * This program is distributed in the hope that it will be useful,
52  * but WITHOUT ANY WARRANTY; without even the implied warranty of
53  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54  * GNU General Public License for more details.
55  *
56  * You should have received a copy of the GNU General Public License
57  * along with this program. If not, see <http://www.gnu.org/licenses/>.
58  *
59  */
63 #ifndef GZSTREAM_HPP
64 #define GZSTREAM_HPP
65 
66 // standard C++ with new header file names and std:: namespace
67 #include <cstring>
68 #include <fstream>
69 #include <iosfwd>
70 #include <zlib.h>
71 
77 class gzstreambuf : public std::streambuf
78 {
79  private:
80  static const int bufferSize = 47 + 256; // size of data buff
81  // totals 512 bytes under g++ for igzstream at the end.
82 
83  gzFile file; // file handle for compressed file
84  char buffer[bufferSize]; // data buffer
85  char opened; // open/close state of stream
86  std::ios_base::openmode mode; // I/O mode
87 
88  int flush_buffer();
89 
90  public:
91  inline gzstreambuf() : opened(0), mode(std::ios::out)
92  {
93  setp(buffer, buffer + (bufferSize - 1));
94  setg(buffer + 4, // beginning of putback area
95  buffer + 4, // read position
96  buffer + 4); // end position
97  // ASSERT: both input & output capabilities will not be used together
98  }
99  inline int is_open()
100  {
101  return opened;
102  }
103  inline gzstreambuf* open(const char* name, std::ios_base::openmode open_mode);
104  inline gzstreambuf* close();
105  inline ~gzstreambuf() override
106  {
107  close();
108  }
109 
110  int overflow(int c = EOF) override;
111  int underflow() override;
112  int sync() override;
113 };
114 
115 class gzstreambase : virtual public std::ios
116 {
117  protected:
119 
120  public:
121  inline gzstreambase()
122  {
123  init(&buf);
124  }
125  inline gzstreambase(const char* name, std::ios_base::openmode open_mode);
126  inline ~gzstreambase() override;
127  inline void open(const char* name, std::ios_base::openmode open_mode);
128  inline void close();
129  inline gzstreambuf* rdbuf()
130  {
131  return &buf;
132  }
133 };
134 
142 class igzstream : public std::istream, public gzstreambase
143 {
144  public:
145  inline igzstream() : std::istream(&buf)
146  {
147  }
148  inline igzstream(const char* name, std::ios_base::openmode _open_mode = std::ios::in)
149  : std::istream(&buf), gzstreambase(name, _open_mode)
150  {
151  }
152  inline gzstreambuf* rdbuf()
153  {
154  return gzstreambase::rdbuf();
155  }
156  inline void open(const char* name, std::ios_base::openmode _open_mode = std::ios::in)
157  {
158  gzstreambase::open(name, _open_mode);
159  }
160 };
161 
162 class ogzstream : public std::ostream, public gzstreambase
163 {
164  public:
165  inline ogzstream() : std::ostream(&buf)
166  {
167  }
168  inline ogzstream(const char* name, std::ios_base::openmode mode = std::ios::out)
169  : std::ostream(&buf), gzstreambase(name, mode)
170  {
171  }
172  inline gzstreambuf* rdbuf()
173  {
174  return gzstreambase::rdbuf();
175  }
176  inline void open(const char* name, std::ios_base::openmode _open_mode = std::ios::out)
177  {
178  gzstreambase::open(name, _open_mode);
179  }
180 };
181 
182 inline gzstreambuf* gzstreambuf::open(const char* name, std::ios_base::openmode open_mode)
183 {
184  if(is_open())
185  {
186  return nullptr;
187  }
188  mode = open_mode;
189  // no append nor read/write mode
190  if((mode & std::ios::ate) || (mode & std::ios::app) || ((mode & std::ios::in) && (mode & std::ios::out)))
191  {
192  return nullptr;
193  }
194  char fmode[10];
195  char* fmodeptr = fmode;
196  if(mode & std::ios::in)
197  {
198  *fmodeptr++ = 'r';
199  }
200  else if(mode & std::ios::out)
201  {
202  *fmodeptr++ = 'w';
203  }
204  *fmodeptr++ = 'b';
205  *fmodeptr = '\0';
206  file = gzopen(name, fmode);
207  if(file == nullptr)
208  {
209  return nullptr;
210  }
211  opened = 1;
212  return this;
213 }
214 
216 {
217  if(is_open())
218  {
219  sync();
220  opened = 0;
221  if(gzclose(file) == Z_OK)
222  {
223  return this;
224  }
225  }
226  return nullptr;
227 }
228 
230 { // used for input buffer only
231  if(gptr() && (gptr() < egptr()))
232  {
233  return *reinterpret_cast<unsigned char*>(gptr());
234  }
235 
236  if(!(mode & std::ios::in) || !opened)
237  {
238  return EOF;
239  }
240  // Josuttis' implementation of inbuf
241  std::streamsize n_putback = gptr() - eback();
242  if(n_putback > 4)
243  {
244  n_putback = 4;
245  }
246  memcpy(buffer + (4 - static_cast<size_t>(n_putback)), gptr() - static_cast<size_t>(n_putback),
247  static_cast<size_t>(n_putback));
248 
249  int num = gzread(file, buffer + 4, bufferSize - 4);
250  if(num <= 0)
251  { // ERROR or EOF
252  return EOF;
253  }
254 
255  // reset buffer pointers
256  setg(buffer + (4 - n_putback), // beginning of putback area
257  buffer + 4, // read position
258  buffer + 4 + num); // end of buffer
259 
260  // return next character
261  return *reinterpret_cast<unsigned char*>(gptr());
262 }
263 
265 {
266  // Separate the writing of the buffer from overflow() and
267  // sync() operation.
268  auto w = static_cast<int>(pptr() - pbase());
269  if(gzwrite(file, pbase(), static_cast<unsigned int>(w)) != w)
270  {
271  return EOF;
272  }
273  pbump(-w);
274  return w;
275 }
276 
277 inline int gzstreambuf::overflow(int c)
278 { // used for output buffer only
279  if(!(mode & std::ios::out) || !opened)
280  {
281  return EOF;
282  }
283  if(c != EOF)
284  {
285  *pptr() = static_cast<char>(c);
286  pbump(1);
287  }
288  if(flush_buffer() == EOF)
289  {
290  return EOF;
291  }
292  return c;
293 }
294 
295 inline int gzstreambuf::sync()
296 {
297  // Changed to use flush_buffer() instead of overflow( EOF)
298  // which caused improper behavior with std::endl and flush(),
299  // bug reported by Vincent Ricard.
300  if(pptr() && pptr() > pbase())
301  {
302  if(flush_buffer() == EOF)
303  {
304  return -1;
305  }
306  }
307  return 0;
308 }
309 
315 inline gzstreambase::gzstreambase(const char* name, std::ios_base::openmode mode)
316 {
317  init(&buf);
318  open(name, mode);
319 }
320 
322 {
323  buf.close();
324 }
325 
326 inline void gzstreambase::open(const char* name, std::ios_base::openmode _open_mode)
327 {
328  if(!buf.open(name, _open_mode))
329  {
330  clear(rdstate() | std::ios::badbit);
331  }
332 }
333 
334 inline void gzstreambase::close()
335 {
336  if(buf.is_open())
337  {
338  if(!buf.close())
339  {
340  clear(rdstate() | std::ios::badbit);
341  }
342  }
343 }
344 
345 #endif // GZSTREAM_H
346 
347 // ============================================================================
348 // EOF //
gzstreambuf * close()
Definition: gzstream.hpp:215
gzFile file
Definition: gzstream.hpp:83
User classes.
Definition: gzstream.hpp:142
char opened
Definition: gzstream.hpp:85
The big change with respect to the original code is a refactoring for a header based library...
Definition: gzstream.hpp:77
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
igzstream(const char *name, std::ios_base::openmode _open_mode=std::ios::in)
Definition: gzstream.hpp:148
~gzstreambuf() override
Definition: gzstream.hpp:105
char buffer[bufferSize]
Definition: gzstream.hpp:84
gzstreambuf * rdbuf()
Definition: gzstream.hpp:129
void open(const char *name, std::ios_base::openmode _open_mode=std::ios::out)
Definition: gzstream.hpp:176
void open(const char *name, std::ios_base::openmode _open_mode=std::ios::in)
Definition: gzstream.hpp:156
gzstreambuf * rdbuf()
Definition: gzstream.hpp:172
int flush_buffer()
Definition: gzstream.hpp:264
int is_open()
Definition: gzstream.hpp:99
void open(const char *name, std::ios_base::openmode open_mode)
Definition: gzstream.hpp:326
std::ios_base::openmode mode
Definition: gzstream.hpp:86
void close()
Definition: gzstream.hpp:334
void init(int bucket[BUCKETSIZE])
Definition: sort.c:42
int sync() override
Definition: gzstream.hpp:295
ogzstream(const char *name, std::ios_base::openmode mode=std::ios::out)
Definition: gzstream.hpp:168
~gzstreambase() override
Definition: gzstream.hpp:321
static const int bufferSize
Definition: gzstream.hpp:80
gzstreambuf * rdbuf()
Definition: gzstream.hpp:152
int underflow() override
Definition: gzstream.hpp:229
int overflow(int c=EOF) override
Definition: gzstream.hpp:277
gzstreambuf buf
Definition: gzstream.hpp:118
gzstreambuf * open(const char *name, std::ios_base::openmode open_mode)
Definition: gzstream.hpp:182

Generated on Mon Feb 12 2024 13:02:56 for PandA-2024.02 by doxygen 1.8.13