| 
							RuNTiME
							
						 | 
						
							
								  | 
								
									
									«  Ответ #7 : 21-10-2011 17:39 »    | 
								
								 | 
							  
							 
							Добавил поддержку выбора стратегии сжатия zlib и исправил ошибки компиляции под Windows. fzstream.h (click to show) // ============================================================================ // fzstream.h // //  Created on : 08.09.2011 //  Last modify: 21.10.2011 //      Author : RuNTiME // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files // (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ============================================================================
  #ifndef FZSTREAM_H_ #define FZSTREAM_H_
  #include <iostream> #include <fstream> #include <zlib.h>
  // ---------------------------------------------------------------------------- //    fzstreambuf // ----------------------------------------------------------------------------
  class fzstreambuf: public std::streambuf {     friend class fzstreambase;     friend class ifzstream;     friend class ofzstream; private:     enum {         InputBufSize  = 16384,         OutputBufSize = 16384     };
      typedef enum {         NotOpened,         Ready,         StreamEnd,         Eof,         Error     } bufstate;
      std::fstream _fs;     std::streampos _zdleft;     std::ios::openmode _mode;     bufstate _state;     char _ibuf[InputBufSize];     char _obuf[OutputBufSize];     z_stream _zs;
      fzstreambuf();
      int flush(int mode = Z_NO_FLUSH);     void open(const char *filename, std::ios::openmode mode, int level,             int strategy);     void close(); protected:     virtual ~fzstreambuf() { close(); }
      virtual int_type overflow(int_type c = traits_type::eof());     virtual int_type underflow();     virtual int sync(); };
  // ---------------------------------------------------------------------------- //    fzstreambase // ----------------------------------------------------------------------------
  class fzstreambase: virtual public std::ios { protected:     fzstreambuf _zbuf;
      fzstreambase(): std::ios(&_zbuf) { } public:     fzstreambuf *rdbuf() { return &_zbuf; }     void close() { _zbuf.close(); }     bool fail() const { return _zbuf._state == fzstreambuf::Error; }     bool good() const { return !fail(); }     bool bad() const { return fail(); }     bool eof() const { return _zbuf._state == fzstreambuf::Eof; }     bool is_open() const { return _zbuf._state != fzstreambuf::NotOpened; }     uLong total_in() const { return _zbuf._zs.total_in; }     uLong total_out() const { return _zbuf._zs.total_out;} };
  // ---------------------------------------------------------------------------- //    ifzstream // ----------------------------------------------------------------------------
  class ifzstream: public fzstreambase, public std::istream { public:     ifzstream()     : std::istream(&_zbuf)     { }
      ifzstream(const char *filename)     : std::istream(&_zbuf)     { open(filename); }
      ifzstream(const std::string &filename)     : std::istream(&_zbuf)     { open( filename.c_str() ); }
      void open(const char *filename) {         _zbuf.open(filename, in | binary, 0, 0);     } };
  // ---------------------------------------------------------------------------- //    ofzstream // ----------------------------------------------------------------------------
  class ofzstream: public fzstreambase, public std::ostream { public:     typedef enum {         DefaultCompression = Z_DEFAULT_COMPRESSION,         NoCompression      = Z_NO_COMPRESSION,         BestSpeed          = Z_BEST_SPEED,         CompressionLevel2  = 2,         CompressionLevel3  = 3,         CompressionLevel4  = 4,         CompressionLevel5  = 5,         CompressionLevel6  = 6,         CompressionLevel7  = 7,         CompressionLevel8  = 8,         BestCompression    = Z_BEST_COMPRESSION     } comprlevel;
      typedef enum {         DefaultStrategy    = Z_DEFAULT_STRATEGY,         Filtered           = Z_FILTERED,         HuffmanOnly        = Z_HUFFMAN_ONLY,         Rle                = Z_RLE,         Fixed              = Z_FIXED     } comprstrategy;
      ofzstream()     : std::ostream(&_zbuf)     { }
      ofzstream(const char *filename, comprlevel level = DefaultCompression,             comprstrategy strategy = DefaultStrategy)     : std::ostream(&_zbuf)     { open(filename, level, strategy); }
      ofzstream(const std::string &filename, comprlevel level             = DefaultCompression, comprstrategy strategy = DefaultStrategy)     : std::ostream(&_zbuf)     { open(filename.c_str(), level, strategy); }
      void open(const char *filename, comprlevel level = DefaultCompression,             comprstrategy strategy = DefaultStrategy) {         _zbuf.open(filename, out | binary, level, strategy);     } };
  #endif /* FZSTREAM_H_ */ fzstream.cpp (click to show) // ============================================================================ // fzstream.cpp // //  Created on : 08.09.2011 //  Last modify: 21.10.2011 //      Author : RuNTiME // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files // (the "Software"), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // ============================================================================
  #include "fzstream.h" #include <cstring>
  using namespace std;
  fzstreambuf::fzstreambuf() : _state(NotOpened) {         memset(&_zs, 0, sizeof(z_stream));     setp(_ibuf, _ibuf + (InputBufSize-1)); }
  int fzstreambuf::flush(int mode) {     int len = pptr() - pbase();     pbump(-len);
      _zs.avail_in = len;     _zs.next_in  = (Bytef*)pbase();
      if(_zs.avail_out == 0) {         _zs.avail_out = OutputBufSize;         _zs.next_out  = (Bytef*)_obuf;     }
      while(1) {         if( deflate(&_zs, mode) == Z_STREAM_ERROR ) {             _state = Error; return -1;         }
          if(_zs.avail_out == 0) {             _fs.write(_obuf, OutputBufSize);             if( _fs.fail() ) {                 _state = Error; return -1;             }
              _zs.avail_out = OutputBufSize;             _zs.next_out  = (Bytef*)_obuf;
              continue;         }
          break;     }
      if(mode == Z_FINISH) {         len = OutputBufSize - _zs.avail_out;         if(len > 0) {             _fs.write(_obuf, len);             if( _fs.fail() ) {                 _state = Error; return -1;             }         }     }
      return 0; }
  fzstreambuf::int_type fzstreambuf::overflow(int_type c) {     if(_state != Ready || _mode & ios::in) {         return traits_type::eof();     }
      if( c != traits_type::eof() ) {         *pptr() = c; pbump(1);     }
      if( flush() == -1 ) {         return traits_type::eof();     }
      return c; }
  fzstreambuf::int_type fzstreambuf::underflow() {     if(_state != Ready || _mode & ios::out) {         if(_state == StreamEnd) {             _state = Eof;         }         return traits_type::eof();     }
      _zs.avail_out = OutputBufSize;     _zs.next_out  = (Bytef*)_obuf;
      do {         if(_zs.avail_in == 0) {             _zs.avail_in = (_zdleft >= InputBufSize) ?                     InputBufSize : (uInt)_zdleft;             _zdleft -= _zs.avail_in;
              _fs.read(_ibuf, _zs.avail_in);             if( _fs.fail() ) {                 _state = Error;                 return traits_type::eof();             }
              _zs.next_in = (Bytef*)_ibuf;         }
          int rc = inflate(&_zs, Z_NO_FLUSH);
          if(rc == Z_STREAM_END) {             if(OutputBufSize - _zs.avail_out > 0) {                 _state = StreamEnd; break;             }             else {                 _state = Eof;                 return traits_type::eof();             }         }         if(rc != Z_OK) {             _state = Error;             return traits_type::eof();         }     } while(_zs.avail_out != 0);
      setg(_obuf, _obuf, _obuf + (OutputBufSize - _zs.avail_out));
      return * reinterpret_cast<fzstreambuf::int_type*>( gptr() ); }
  int fzstreambuf::sync() {     if(_state != Ready) {         return -1;     }
      if( pptr() > pbase() ) {         return flush();     }
      return 0; }
  void fzstreambuf::open(const char *filename, ios::openmode mode,         int level, int strategy) {     close();     _mode = mode;
      _fs.open(filename, mode);     if( _fs.fail() ) {         _state = Error; return;     }
      if(mode & ios::in) {         _fs.seekg(0, ios::end);         _zdleft = _fs.tellg();         _fs.seekg(0, ios::beg);
          if( inflateInit(&_zs) != Z_OK ) {             _state = Error; return;         }     }     else {         if( deflateInit2(&_zs, level, Z_DEFLATED, MAX_WBITS, MAX_MEM_LEVEL,                 strategy) != Z_OK ) {             _state = Error; return;         }     }
      _state = Ready; }
  void fzstreambuf::close() {     if(_state != NotOpened) {         if(_mode & ios::in) {             inflateEnd(&_zs);         }         else {             if(_state != Error) {                 flush(Z_FINISH);             }             deflateEnd(&_zs);         }         memset(&_zs, 0, sizeof(z_stream));
          _fs.close();
          _state = NotOpened;     } }  
						 |