Ignore:
Timestamp:
07/24/11 10:51:54 (13 years ago)
Author:
tbretz
Message:
Moved all the source code to the header; set the fail and bad bit more properly.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Mars/mbase/izstream.h

    r11549 r11551  
    1 #ifndef MARS_MZlib
    2 #define MARS_MZlib
     1#ifndef MARS_izstream
     2#define MARS_izstream
    33
     4#include <istream>
     5#include <streambuf>
     6
     7#ifdef __MARS__
    48#ifndef ROOT_TObject
    59#include <TObject.h> // Needed for ClassDef
     10#endif
    611#endif
    712
     
    1217#endif
    1318
    14 #include <istream>  // base classes for MLog
    15 
    16 class MZlib : public std::streambuf, public std::istream
     19class izstream : public std::streambuf, public std::istream
    1720{
    1821private:
     
    2225    char   fBuffer[fgBufferSize]; // data buffer
    2326
    24     int underflow();
     27    int underflow()
     28    {
     29        if (gptr() && gptr()<egptr())
     30            return * reinterpret_cast<unsigned char *>(gptr());
     31
     32        if (!is_open())
     33            return EOF;
     34
     35        // gptr()-eback(): if more than four bytes are already flushed
     36        const int iputback = gptr()-eback()>4 ? 4 : gptr()-eback();
     37
     38        // Copy the last four bytes flushed into the putback area
     39        memcpy(fBuffer+(4-iputback), gptr()-iputback, iputback);
     40
     41        // Fill the buffer starting at the current file position and reset buffer
     42        // pointers by calling setg
     43        const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
     44        if (num <= 0) // ERROR or EOF
     45            return EOF;
     46
     47        // reset buffer pointers
     48        setg(fBuffer+(4-iputback), fBuffer+4, fBuffer+4+num);
     49
     50        // return next character
     51        return *reinterpret_cast<unsigned char *>(gptr());
     52    }
     53
    2554
    2655public:
    27     MZlib() : istream(this), fFile(0)
     56    izstream() : std::istream(this), fFile(0)
    2857    {
    2958        setg(fBuffer+4, fBuffer+4, fBuffer+4);
    3059    }
    31     MZlib(const char *name) : istream(this), fFile(0)
     60    izstream(const char *name) : std::istream(this), fFile(0)
    3261    {
    3362        setg(fBuffer+4, fBuffer+4, fBuffer+4);
    3463        open(name);
    3564    }
    36     ~MZlib() { MZlib::close(); }
     65    ~izstream() { izstream::close(); }
    3766
    3867    int is_open() { return fFile!=0; }
    3968
    40     void open(const char* name);
    41     void close();
     69    // --------------------------------------------------------------------------
     70    //
     71    // Open a file by name. Test if it is open like for an ifstream
     72    // It doesn't matter whether the file is gzip compressed or not.
     73    //
     74    void open(const char* name)
     75    {
     76        if (is_open())
     77        {
     78            clear(rdstate()|std::ios::failbit);
     79            return;
     80        }
    4281
    43 # if (__GNUC__>2)
    44     std::streambuf::pos_type seekoff(std::streambuf::off_type, std::ios_base::seekdir,
    45                                      std::ios_base::openmode = std::ios_base::in);
    46     std::streambuf::pos_type seekpos(std::streambuf::pos_type,
    47                                      std::ios_base::openmode = std::ios_base::in);
    48 # else
    49     std::streampos seekoff(std::streamoff, int, int = std::ios::in);
    50 //    std::streampos seekpos(std::streampos, int = std::ios::in);
    51 # endif
     82        fFile = gzopen(name, "rb");
     83        if (fFile == 0)
     84        {
     85            clear(rdstate()|std::ios::failbit);
     86            return;
     87        }
     88    }
     89    // --------------------------------------------------------------------------
     90    //
     91    // Close an open file.
     92    //
     93    void close()
     94    {
     95        if (!is_open())
     96            return;
    5297
    53     ClassDef(MZlib, 0) // A C++ wrapper to istream zlib files
     98        if (gzclose(fFile) != Z_OK)
     99            clear(rdstate()|std::ios::failbit);
     100
     101        fFile = 0;
     102    }
     103
     104    std::streambuf::pos_type seekoff(std::streambuf::off_type offset, std::ios_base::seekdir dir,
     105                                     std::ios_base::openmode = std::ios_base::in)
     106    {
     107        // Using a switch instead results in:
     108        //  In member function `virtual std::streampos izstream::seekoff(long int, std::_Ios_Seekdir, std::_Ios_Openmode)':
     109        //  warning: enumeration value `_M_ios_seekdir_end' not handled in switch
     110        //  warning: case value `0' not in enumerated type `_Ios_Seekdir'
     111        //  warning: case value `1' not in enumerated type `_Ios_Seekdir'
     112        //  warning: case value `2' not in enumerated type `_Ios_Seekdir'
     113
     114        if (dir==std::ios::end)
     115        {
     116            clear(rdstate()|std::ios::failbit);
     117            return EOF;
     118        }
     119
     120        // We only do relative seeking to avoid unnecessary decompression
     121        // of the whole file
     122        if (dir==std::ios::beg)
     123            offset -= tellg();
     124
     125        // Calculate future position in streambuffer
     126        const char *ptr = gptr()+offset;
     127
     128        // This is the number of bytes still available in the buffer
     129        const size_t sbuf = egptr()-gptr();
     130
     131        // Check if the new position will still be in the buffer
     132        // In this case the target data was already decompressed.
     133        if (ptr>=eback() && ptr<egptr())
     134        {
     135            // Absolute position in z-stream
     136            const z_off_t zpos = gztell(fFile)-sbuf; //gzseek(fFile, 0, SEEK_CUR);
     137
     138            gbump(offset);
     139
     140            return zpos+offset;
     141        }
     142
     143        const streampos pos = gzseek(fFile, offset-sbuf, SEEK_CUR);
     144
     145        // Buffer is empty - force refilling
     146        setg(fBuffer+4, fBuffer+4, fBuffer+4);
     147
     148        return pos<0 ? streampos(EOF) : pos;
     149
     150        /*
     151         // SEEK_END not supported by zlib
     152         if (dir==ios::end)
     153         {
     154             // Position in z-stream
     155             const z_off_t zpos = gzseek(fFile, offset, SEEK_END);
     156             if (zpos<0)
     157                 return EOF;
     158
     159             return fill_buffer()==EOF ? EOF : zpos;
     160         }
     161         */
     162        return EOF;
     163    }
     164
     165    std::streambuf::pos_type seekpos(std::streambuf::pos_type pos,
     166                                     std::ios_base::openmode = std::ios_base::in)
     167    {
     168        return seekoff(pos, std::ios::beg);
     169    }
     170
     171#ifdef __MARS__
     172    ClassDef(izstream, 0) // A C++ wrapper to istream zlib files
     173#endif
    54174};
    55175
Note: See TracChangeset for help on using the changeset viewer.