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

Last change on this file since 7710 was 7449, checked in by tbretz, 19 years ago
*** empty log message ***
File size: 5.1 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 putback)
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-putback), 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 putback = gptr()-eback()>4 ? 4 : gptr()-eback();
109
110 // Copy the last four bytes flushed into the putback area
111 memcpy(fBuffer+(4-putback), gptr()-putback, putback);
112
113 if (fill_buffer(putback)==EOF)
114 return EOF;
115
116 // return next character
117 return *reinterpret_cast<unsigned char *>(gptr());
118}
119
120// --------------------------------------------------------------------------
121//
122streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode)
123{
124 // Using a switch instead results in:
125 // In member function `virtual std::streampos MZlib::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
126 // warning: enumeration value `_M_ios_seekdir_end' not handled in switch
127 // warning: case value `0' not in enumerated type `_Ios_Seekdir'
128 // warning: case value `1' not in enumerated type `_Ios_Seekdir'
129 // warning: case value `2' not in enumerated type `_Ios_Seekdir'
130
131 if (dir==ios::cur)
132 {
133 // Position in z-stream
134 const z_off_t zpos = gztell(fFile); //gzseek(fFile, 0, SEEK_CUR);
135
136 // Calculate future position in streambuffer
137 const char *ptr = gptr()+offset;
138
139 // Check if the new position will still be in the buffer
140 // In this case the target data was already decompressed.
141 if (ptr<eback() || ptr>=egptr())
142 return seekpos(zpos+ptr-egptr());
143
144 gbump(offset);
145 return zpos+offset;
146
147 // zpos-blen: Position in z-stream coresponding to buffer position
148 // return seekpos(gztell(fFile)+gptr()-egptr()+offset);
149 }
150
151 if (dir==ios::beg)
152 return seekpos(offset);
153
154 /*
155 // SEEK_END not supported by zlib
156 if (dir==ios::end)
157 {
158 // Position in z-stream
159 const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
160 if (zpos<0)
161 return EOF;
162
163 return fill_buffer()==EOF ? EOF : zpos;
164 }
165 */
166 return EOF;
167
168}
169
170// --------------------------------------------------------------------------
171//
172streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode)
173{
174 // Seek the z-stream to the given position
175 if (gzseek(fFile, pos, SEEK_SET)<0)
176 return EOF;
177
178 // Fill buffer
179 if (fill_buffer()==EOF)
180 return EOF;
181
182 return pos;
183}
Note: See TracBrowser for help on using the repository browser.