source: trunk/MagicSoft/Mars/mbase/MZlib.cc@ 7825

Last change on this file since 7825 was 7808, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 5.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 12/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2005
21!
22!
23\* ======================================================================== */
24
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MZlib
29//
30// This is a C++ wrapper for zlib.
31//
32// WARNING: - There might not be support for all features.
33// - seek calls might be rather slow
34//
35//////////////////////////////////////////////////////////////////////////////
36#include "MZlib.h"
37
38ClassImp(MZlib);
39
40using namespace std;
41
42// --------------------------------------------------------------------------
43//
44// Open a file by name. Test if it is open like for an ifstream
45// It doesn't matter whether the file is gzip compressed or not.
46//
47void MZlib::open(const char* name)
48{
49 if (is_open())
50 {
51 clear(rdstate()|ios::badbit);
52 return;
53 }
54
55 fFile = gzopen(name, "rb");
56 if (fFile == 0)
57 {
58 clear(rdstate()|ios::badbit);
59 return;
60 }
61}
62
63// --------------------------------------------------------------------------
64//
65// Close an open file.
66//
67void MZlib::close()
68{
69 if (!is_open())
70 return;
71
72 if (gzclose(fFile) != Z_OK)
73 clear(rdstate()|ios::badbit);
74
75 fFile = 0;
76}
77
78// --------------------------------------------------------------------------
79//
80// Fill the buffer starting at the current file position and reset buffer
81// pointers by calling setg
82//
83int MZlib::fill_buffer(int iputback)
84{
85 const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
86 if (num <= 0) // ERROR or EOF
87 return EOF;
88
89 // reset buffer pointers
90 setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num);
91
92 return num;
93}
94
95// --------------------------------------------------------------------------
96//
97// Handle a buffer underflow (buffer went empty)
98//
99int MZlib::underflow()
100{
101 if (gptr() && gptr()<egptr())
102 return * reinterpret_cast<unsigned char *>(gptr());
103
104 if (!is_open())
105 return EOF;
106
107 // gptr()-eback(): if more than four bytes are already flushed
108 const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback();
109
110 // Copy the last four bytes flushed into the putback area
111 memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback);
112
113 if (fill_buffer(iputback)==EOF)
114 return EOF;
115
116 // return next character
117 return *reinterpret_cast<unsigned char *>(gptr());
118}
119
120// --------------------------------------------------------------------------
121//
122# if (__GNUC__>2)
123streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir,
124 ios_base::openmode)
125# else
126streampos MZlib::seekoff(streamoff offset, int dir, int)
127# endif
128{
129 // Using a switch instead results in:
130 // In member function `virtual std::streampos MZlib::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
131 // warning: enumeration value `_M_ios_seekdir_end' not handled in switch
132 // warning: case value `0' not in enumerated type `_Ios_Seekdir'
133 // warning: case value `1' not in enumerated type `_Ios_Seekdir'
134 // warning: case value `2' not in enumerated type `_Ios_Seekdir'
135
136 if (dir==ios::cur)
137 {
138 // Position in z-stream
139 const z_off_t zpos = gztell(fFile); //gzseek(fFile, 0, SEEK_CUR);
140
141 // Calculate future position in streambuffer
142 const char *ptr = gptr()+offset;
143
144 // Check if the new position will still be in the buffer
145 // In this case the target data was already decompressed.
146 if (ptr<eback() || ptr>=egptr())
147 return seekpos(zpos+ptr-egptr());
148
149 gbump(offset);
150 return zpos+offset;
151
152 // zpos-blen: Position in z-stream coresponding to buffer position
153 // return seekpos(gztell(fFile)+gptr()-egptr()+offset);
154 }
155
156 if (dir==ios::beg)
157 return seekpos(offset);
158
159 /*
160 // SEEK_END not supported by zlib
161 if (dir==ios::end)
162 {
163 // Position in z-stream
164 const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
165 if (zpos<0)
166 return EOF;
167
168 return fill_buffer()==EOF ? EOF : zpos;
169 }
170 */
171 return EOF;
172
173}
174
175// --------------------------------------------------------------------------
176//
177# if (__GNUC__>2)
178streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode)
179# else
180streampos MZlib::seekpos(streampos pos, int)
181# endif
182{
183 // Seek the z-stream to the given position
184 if (gzseek(fFile, pos, SEEK_SET)<0)
185 return EOF;
186
187 // Fill buffer
188 if (fill_buffer()==EOF)
189 return EOF;
190
191 return pos;
192}
Note: See TracBrowser for help on using the repository browser.