StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Streams.cc
1 // Streams.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2020 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // Internal classes to implement gzstream. See header file for user classes.
7 // Adapted for Sherpa by Frank Siegert from:
8 // gzstream, C++ iostream classes wrapping the zlib compression library.
9 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner
10 // (http://www.cs.unc.edu/Research/compgeom/gzstream).
11 // Further adapted to PYTHIA by Stefan Prestel.
12 
13 #include "Pythia8/Streams.h"
14 
15 namespace Pythia8 {
16 
17 #ifdef GZIP
18 
19 //==========================================================================
20 
21 // The gzstreambuf class.
22 
23 //--------------------------------------------------------------------------
24 
25 gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
26  if ( is_open())
27  return (gzstreambuf*)0;
28  mode = open_mode;
29  // no append nor read/write mode
30  if ((mode & std::ios::ate) || (mode & std::ios::app)
31  || ((mode & std::ios::in) && (mode & std::ios::out)))
32  return (gzstreambuf*)0;
33  char fmode[10];
34  char* fmodeptr = fmode;
35  if ( mode & std::ios::in)
36  *fmodeptr++ = 'r';
37  else if ( mode & std::ios::out)
38  *fmodeptr++ = 'w';
39  *fmodeptr++ = 'b';
40  *fmodeptr = '\0';
41  file = gzopen( name, fmode);
42  if (file == Z_NULL)
43  return (gzstreambuf*)0;
44  opened = 1;
45  return this;
46 }
47 
48 //--------------------------------------------------------------------------
49 
50 gzstreambuf * gzstreambuf::close() {
51  if ( is_open()) {
52  sync();
53  opened = 0;
54  if ( gzclose( file) == Z_OK)
55  return this;
56  }
57  return (gzstreambuf*)0;
58 }
59 
60 //--------------------------------------------------------------------------
61 
62 int gzstreambuf::underflow() { // used for input buffer only
63  if ( gptr() && ( gptr() < egptr()))
64  return * reinterpret_cast<unsigned char *>( gptr());
65 
66  if ( ! (mode & std::ios::in) || ! opened)
67  return EOF;
68  // Josuttis' implementation of inbuf
69  int n_putback = gptr() - eback();
70  if ( n_putback > 4)
71  n_putback = 4;
72  memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
73 
74  int num = gzread( file, buffer+4, bufferSize-4);
75  if (num <= 0) // ERROR or EOF
76  return EOF;
77 
78  // reset buffer pointers
79  setg( buffer + (4 - n_putback), // beginning of putback area
80  buffer + 4, // read position
81  buffer + 4 + num); // end of buffer
82 
83  // return next character
84  return * reinterpret_cast<unsigned char *>( gptr());
85 }
86 
87 //--------------------------------------------------------------------------
88 
89 int gzstreambuf::flush_buffer() {
90  // Separate the writing of the buffer from overflow() and
91  // sync() operation.
92  int w = pptr() - pbase();
93  if ( gzwrite( file, pbase(), w) != w)
94  return EOF;
95  pbump( -w);
96  return w;
97 }
98 
99 //--------------------------------------------------------------------------
100 
101 int gzstreambuf::overflow( int c) { // used for output buffer only
102  if ( ! ( mode & std::ios::out) || ! opened)
103  return EOF;
104  if (c != EOF) {
105  *pptr() = c;
106  pbump(1);
107  }
108  if ( flush_buffer() == EOF)
109  return EOF;
110  return c;
111 }
112 
113 //--------------------------------------------------------------------------
114 
115 int gzstreambuf::sync() {
116  // Changed to use flush_buffer() instead of overflow( EOF)
117  // which caused improper behavior with std::endl and flush(),
118  // bug reported by Vincent Ricard.
119  if ( pptr() && pptr() > pbase()) {
120  if ( flush_buffer() == EOF)
121  return -1;
122  }
123  return 0;
124 }
125 
126 //==========================================================================
127 
128 // The gzstreambase class.
129 
130 //--------------------------------------------------------------------------
131 
132 gzstreambase::gzstreambase( const char* name, int mode) {
133  init( &buf);
134  open( name, mode);
135 }
136 
137 //--------------------------------------------------------------------------
138 
139 gzstreambase::~gzstreambase() {
140  buf.close();
141 }
142 
143 //--------------------------------------------------------------------------
144 
145 void gzstreambase::open( const char* name, int mode) {
146  if ( ! buf.open( name, mode))
147  clear( rdstate() | std::ios::badbit);
148 }
149 
150 //--------------------------------------------------------------------------
151 
152 void gzstreambase::close() {
153  if ( buf.is_open())
154  if ( ! buf.close())
155  clear( rdstate() | std::ios::badbit);
156 }
157 
158 //==========================================================================
159 
160 #endif
161 
162 // Dummy to avoid harmless compiler warning that Streams.o has no symbols.
163 double DummyForStreams::xtox(double x) {return x;}
164 
165 //==========================================================================
166 
167 } // end namespace Pythia8