Ignore:
Timestamp:
12/07/05 09:14:13 (19 years ago)
Author:
tbretz
Message:
*** empty log message ***
Location:
trunk/MagicSoft/Mars/mbase
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/MagicSoft/Mars/mbase/MZlib.cc

    r7438 r7449  
    2828// MZlib
    2929//
    30 // This is a C++ wrapper for zlib (taken from root)
     30// This is a C++ wrapper for zlib.
    3131//
    3232// WARNING: - There might not be support for all features.
     
    5353    }
    5454
    55     fFile = gzopen(name, "rb0");
     55    fFile = gzopen(name, "rb");
    5656    if (fFile == 0)
    5757    {
     
    7070        return;
    7171
    72     sync();
    73 
    7472    if (gzclose(fFile) != Z_OK)
    7573        clear(rdstate()|ios::badbit);
     
    7977
    8078// --------------------------------------------------------------------------
     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)
    8198//
    8299int MZlib::underflow()
     
    88105        return EOF;
    89106
    90     // implementation of inbuf
     107    // gptr()-eback(): if more than four bytes are already flushed
    91108    const int putback = gptr()-eback()>4 ? 4 : gptr()-eback();
    92109
     110    // Copy the last four bytes flushed into the putback area
    93111    memcpy(fBuffer+(4-putback), gptr()-putback, putback);
    94112
    95     const int num = gzread(fFile, fBuffer+4, fgBufferSize-4);
    96     if (num <= 0) // ERROR or EOF
     113    if (fill_buffer(putback)==EOF)
    97114        return EOF;
    98 
    99     // reset buffer pointers
    100     setg(fBuffer+(4-putback), fBuffer+4, fBuffer+4+num);
    101115
    102116    // return next character
     
    106120// --------------------------------------------------------------------------
    107121//
    108 int MZlib::flush_buffer()
     122streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode)
    109123{
    110     // Separate the writing of the buffer from overflow() and sync() operation.
    111     const int w = pptr() - pbase();
     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'
    112130
    113     if (gzwrite(fFile, pbase(), w) != w)
    114         return EOF;
     131    if (dir==ios::cur)
     132    {
     133        // Position in z-stream
     134        const z_off_t zpos = gztell(fFile); //gzseek(fFile, 0, SEEK_CUR);
    115135
    116     pbump(-w);
     136        // Calculate future position in streambuffer
     137        const char *ptr = gptr()+offset;
    117138
    118     return w;
    119 }
     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());
    120143
    121 /*
    122 int MZlib::overflow( int c)
    123 {
    124     if ( ! ( mode & ios::out) || ! opened)
    125         return EOF;
     144        gbump(offset);
     145        return zpos+offset;
    126146
    127     if (c != EOF)
    128     {
    129         *pptr() = c;
    130         pbump(1);
     147        // zpos-blen: Position in z-stream coresponding to buffer position
     148        // return seekpos(gztell(fFile)+gptr()-egptr()+offset);
     149    }
    131150
    132     }
    133     if ( flush_buffer() == EOF)
    134         return EOF;
     151    if (dir==ios::beg)
     152        return seekpos(offset);
    135153
    136     return c;
    137 }
    138 */
     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;
    139167
    140 // --------------------------------------------------------------------------
    141 //
    142 int MZlib::sync()
    143 {
    144     // Use flush_buffer() instead of overflow(EOF) to
    145     // cause proper behavior with std::endl and flush()
    146     if (pptr() && pptr()>pbase())
    147     {
    148         if (flush_buffer() == EOF)
    149             return -1;
    150     }
    151     return 0;
    152168}
    153169
    154170// --------------------------------------------------------------------------
    155171//
    156 streambuf::pos_type MZlib::seekoff(streambuf::off_type offset, ios_base::seekdir dir, ios_base::openmode)
     172streambuf::pos_type MZlib::seekpos(streambuf::pos_type pos, ios_base::openmode)
    157173{
    158     return gzseek(fFile, offset, dir);
     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;
    159183}
  • trunk/MagicSoft/Mars/mbase/MZlib.h

    r7438 r7449  
    1313
    1414#include <iostream>  // base classes for MLog
     15#include <fstream>
    1516
    1617class MZlib : public std::streambuf, virtual public std::istream, public TObject
     
    2223    char   fBuffer[fgBufferSize]; // data buffer
    2324
    24     int flush_buffer();
    2525    int underflow();
    26     int sync();
     26    int fill_buffer(int putback=0);
    2727
    2828public:
    2929    MZlib() : istream(this), fFile(0)
    3030    {
    31         setp(fBuffer,   fBuffer+fgBufferSize-1);
    3231        setg(fBuffer+4, fBuffer+4, fBuffer+4);
    3332    }
    3433    MZlib(const char *name) : istream(this), fFile(0)
    3534    {
    36         setp(fBuffer,   fBuffer+fgBufferSize-1);
    3735        setg(fBuffer+4, fBuffer+4, fBuffer+4);
    38 
    3936        open(name);
    4037    }
     
    4744
    4845    std::streambuf::pos_type seekoff(std::streambuf::off_type, std::ios_base::seekdir,
    49                                      std::ios_base::openmode = std::ios_base::in | std::ios_base::out);
    50     //std::streambuf::pos_type seekpos(std::streambuf::pos_type,
    51     //                                 std::ios_base::openmode = std::ios_base::in | std::ios_base::out);
     46                                     std::ios_base::openmode = std::ios_base::in);
     47    std::streambuf::pos_type seekpos(std::streambuf::pos_type,
     48                                     std::ios_base::openmode = std::ios_base::in);
    5249
    5350    ClassDef(MZlib, 0) // A C++ wrapper to istream zlib files
Note: See TracChangeset for help on using the changeset viewer.