00001 // ============================================================================ 00002 // gzstream, C++ iostream classes wrapping the zlib compression library. 00003 // Copyright (C) 2001 Deepak Bandyopadhyay, Lutz Kettner 00004 // 00005 // This library is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This library is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this library; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 // ============================================================================ 00019 // 00020 // File : gzstream.h 00021 // Revision : $Revision: 1.5 $ 00022 // Revision_date : $Date: 2002/04/26 23:30:15 $ 00023 // Author(s) : Deepak Bandyopadhyay, Lutz Kettner 00024 // 00025 // Standard streambuf implementation following Nicolai Josuttis, "The 00026 // Standard C++ Library". 00027 // ============================================================================ 00028 00029 #ifndef GZSTREAM_H 00030 #define GZSTREAM_H 00031 00032 // standard C++ with new header file names and std:: namespace 00033 #include <iostream> 00034 #include <fstream> 00035 #include <zlib.h> 00036 00037 // ---------------------------------------------------------------------------- 00038 // Internal classes to implement gzstream. See below for user classes. 00039 // ---------------------------------------------------------------------------- 00040 00041 class gzstreambuf : public std::streambuf { 00042 private: 00043 static const int bufferSize = 47+256; // size of data buff 00044 // totals 512 bytes under g++ for igzstream at the end. 00045 00046 gzFile file; // file handle for compressed file 00047 char buffer[bufferSize]; // data buffer 00048 char opened; // open/close state of stream 00049 int mode; // I/O mode 00050 00051 int flush_buffer(); 00052 public: 00053 gzstreambuf() : opened(0) { 00054 setp( buffer, buffer + (bufferSize-1)); 00055 setg( buffer + 4, // beginning of putback area 00056 buffer + 4, // read position 00057 buffer + 4); // end position 00058 // ASSERT: both input & output capabilities will not be used together 00059 } 00060 int is_open() { return opened; } 00061 gzstreambuf* open( const char* name, int open_mode); 00062 gzstreambuf* close(); 00063 ~gzstreambuf() { close(); } 00064 00065 virtual int overflow( int c = EOF); 00066 virtual int underflow(); 00067 virtual int sync(); 00068 }; 00069 00070 class gzstreambase : virtual public std::ios { 00071 protected: 00072 gzstreambuf buf; 00073 public: 00074 gzstreambase() { init(&buf); } 00075 gzstreambase( const char* name, int open_mode); 00076 ~gzstreambase(); 00077 void open( const char* name, int open_mode); 00078 void close(); 00079 gzstreambuf* rdbuf() { return &buf; } 00080 }; 00081 00082 // ---------------------------------------------------------------------------- 00083 // User classes. Use igzstream and ogzstream analogously to ifstream and 00084 // ofstream respectively. They read and write files based on the gz* 00085 // function interface of the zlib. Files are compatible with gzip compression. 00086 // ---------------------------------------------------------------------------- 00087 00088 class igzstream : public gzstreambase, public std::istream { 00089 public: 00090 igzstream() : std::istream( &buf) {} 00091 igzstream( const char* name, int open_mode = std::ios::in) 00092 : gzstreambase( name, open_mode), std::istream( &buf) {} 00093 gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } 00094 void open( const char* name, int open_mode = std::ios::in) { 00095 gzstreambase::open( name, open_mode); 00096 } 00097 }; 00098 00099 class ogzstream : public gzstreambase, public std::ostream { 00100 public: 00101 ogzstream() : std::ostream( &buf) {} 00102 ogzstream( const char* name, int mode = std::ios::out) 00103 : gzstreambase( name, mode), std::ostream( &buf) {} 00104 gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); } 00105 void open( const char* name, int open_mode = std::ios::out) { 00106 gzstreambase::open( name, open_mode); 00107 } 00108 }; 00109 00110 00111 // this function tries to open the file using gz 00112 // if that fails it will open with normal stream 00113 // after usage the returned streem must be deleted 00114 std::istream * openGzFile(const char * name); 00115 00116 #endif