/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 12/2005 ! ! Copyright: MAGIC Software Development, 2000-2005 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MZlib // // This is a C++ wrapper for zlib. // // WARNING: - There might not be support for all features. // - seek calls might be rather slow // ////////////////////////////////////////////////////////////////////////////// #include "MZlib.h" #include // memcpy (UBuntu 8.10) ClassImp(MZlib); using namespace std; // -------------------------------------------------------------------------- // // Open a file by name. Test if it is open like for an ifstream // It doesn't matter whether the file is gzip compressed or not. // void MZlib::open(const char* name) { if (is_open()) { clear(rdstate()|ios::badbit); return; } fFile = gzopen(name, "rb"); if (fFile == 0) { clear(rdstate()|ios::badbit); return; } } // -------------------------------------------------------------------------- // // Close an open file. // void MZlib::close() { if (!is_open()) return; if (gzclose(fFile) != Z_OK) clear(rdstate()|ios::badbit); fFile = 0; } // -------------------------------------------------------------------------- // // Handle a buffer underflow (buffer went empty) // int MZlib::underflow() { if (gptr() && gptr()(gptr()); if (!is_open()) return EOF; // gptr()-eback(): if more than four bytes are already flushed const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback(); // Copy the last four bytes flushed into the putback area memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback); // Fill the buffer starting at the current file position and reset buffer // pointers by calling setg const int num = gzread(fFile, fBuffer+4, fgBufferSize-4); if (num <= 0) // ERROR or EOF return EOF; // reset buffer pointers setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num); // return next character return *reinterpret_cast(gptr()); } // -------------------------------------------------------------------------- // #include # if (__GNUC__>2) streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode) # else streampos MZlib::seekoff(streamoff offset, int dir, int) # endif { // Using a switch instead results in: // In member function `virtual std::streampos MZlib::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)': // warning: enumeration value `_M_ios_seekdir_end' not handled in switch // warning: case value `0' not in enumerated type `_Ios_Seekdir' // warning: case value `1' not in enumerated type `_Ios_Seekdir' // warning: case value `2' not in enumerated type `_Ios_Seekdir' if (dir==ios::end) { clear(rdstate()|ios::failbit); return EOF; } // We only do relative seeking to avoid unnecessary decompression // of the whole file if (dir==ios::beg) offset -= tellg(); // Calculate future position in streambuffer const char *ptr = gptr()+offset; // This is the number of bytes still available in the buffer const size_t sbuf = egptr()-gptr(); // Check if the new position will still be in the buffer // In this case the target data was already decompressed. if (ptr>=eback() && ptr2) streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode) # else streampos MZlib::seekpos(streampos pos, int) # endif { return seekoff(pos, ios::beg); }