source: trunk/Mars/mbase/MZlib.cc@ 9853

Last change on this file since 9853 was 9195, checked in by tbretz, 16 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
38#include <string.h> // memcpy (UBuntu 8.10)
39
40ClassImp(MZlib);
41
42using namespace std;
43
44// --------------------------------------------------------------------------
45//
46// Open a file by name. Test if it is open like for an ifstream
47// It doesn't matter whether the file is gzip compressed or not.
48//
49void MZlib::open(const char* name)
50{
51 if (is_open())
52 {
53 clear(rdstate()|ios::badbit);
54 return;
55 }
56
57 fFile = gzopen(name, "rb");
58 if (fFile == 0)
59 {
60 clear(rdstate()|ios::badbit);
61 return;
62 }
63}
64
65// --------------------------------------------------------------------------
66//
67// Close an open file.
68//
69void MZlib::close()
70{
71 if (!is_open())
72 return;
73
74 if (gzclose(fFile) != Z_OK)
75 clear(rdstate()|ios::badbit);
76
77 fFile = 0;
78}
79
80// --------------------------------------------------------------------------
81//
82// Fill the buffer starting at the current file position and reset buffer
83// pointers by calling setg
84//
85int MZlib::fill_buffer(int iputback)
86{
87 const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
88 if (num <= 0) // ERROR or EOF
89 return EOF;
90
91 // reset buffer pointers
92 setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num);
93
94 return num;
95}
96
97// --------------------------------------------------------------------------
98//
99// Handle a buffer underflow (buffer went empty)
100//
101int MZlib::underflow()
102{
103 if (gptr() && gptr()<egptr())
104 return * reinterpret_cast<unsigned char *>(gptr());
105
106 if (!is_open())
107 return EOF;
108
109 // gptr()-eback(): if more than four bytes are already flushed
110 const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback();
111
112 // Copy the last four bytes flushed into the putback area
113 memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback);
114
115 if (fill_buffer(iputback)==EOF)
116 return EOF;
117
118 // return next character
119 return *reinterpret_cast<unsigned char *>(gptr());
120}
121
122// --------------------------------------------------------------------------
123//
124# if (__GNUC__>2)
125streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir,
126 ios_base::openmode)
127# else
128streampos MZlib::seekoff(streamoff offset, int dir, int)
129# endif
130{
131 // Using a switch instead results in:
132 // In member function `virtual std::streampos MZlib::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
133 // warning: enumeration value `_M_ios_seekdir_end' not handled in switch
134 // warning: case value `0' not in enumerated type `_Ios_Seekdir'
135 // warning: case value `1' not in enumerated type `_Ios_Seekdir'
136 // warning: case value `2' not in enumerated type `_Ios_Seekdir'
137
138 if (dir==ios::cur)
139 {
140 // Position in z-stream
141 const z_off_t zpos = gztell(fFile); //gzseek(fFile, 0, SEEK_CUR);
142
143 // Calculate future position in streambuffer
144 const char *ptr = gptr()+offset;
145
146 // Check if the new position will still be in the buffer
147 // In this case the target data was already decompressed.
148 if (ptr<eback() || ptr>=egptr())
149 return seekpos(zpos+ptr-egptr());
150
151 gbump(offset);
152 return zpos+offset;
153
154 // zpos-blen: Position in z-stream coresponding to buffer position
155 // return seekpos(gztell(fFile)+gptr()-egptr()+offset);
156 }
157
158 if (dir==ios::beg)
159 return seekpos(offset);
160
161 /*
162 // SEEK_END not supported by zlib
163 if (dir==ios::end)
164 {
165 // Position in z-stream
166 const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
167 if (zpos<0)
168 return EOF;
169
170 return fill_buffer()==EOF ? EOF : zpos;
171 }
172 */
173 return EOF;
174
175}
176
177// --------------------------------------------------------------------------
178//
179# if (__GNUC__>2)
180streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode)
181# else
182streampos MZlib::seekpos(streampos pos, int)
183# endif
184{
185 // Seek the z-stream to the given position
186 if (gzseek(fFile, pos, SEEK_SET)<0)
187 return EOF;
188
189 // Fill buffer
190 if (fill_buffer()==EOF)
191 return EOF;
192
193 return pos;
194}
Note: See TracBrowser for help on using the repository browser.