Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

zipiostream.h

Go to the documentation of this file.
00001 
00013 #include <iostream>
00014 #include <zlib.h>
00015 
00016 #ifndef __ZIPIOSTREAM_H__
00017 #define __ZIPIOSTREAM_H__
00018 
00019 
00024 #define zapeof(c) ((c)&0377)
00025 
00026 
00027 class zipstreambuf : public streambuf
00028 {
00029 public:
00030   static const int openprot;
00031 private:
00032   char opened;
00033   int mode;
00034   gzFile file;
00035 public:
00036   zipstreambuf() { opened = 0; }
00037   int is_open() const { return opened; }
00038 
00039   
00040   zipstreambuf* open(const char * name, int om) {
00041     if (is_open())
00042       return (zipstreambuf*)0;
00043 
00044     mode = om;
00045     // no append nor read/write mode
00046     if ((mode & ios::ate) || (mode & ios::app)
00047         || ((mode & ios::in) && (mode & ios::out)))
00048       return (zipstreambuf*)0;
00049 
00050     char fmode[10];
00051     char * fmodeptr = fmode;
00052     if (mode & ios::in)
00053       {
00054         *fmodeptr++ = 'r';
00055       }
00056     else if (mode & ios::out)
00057       *fmodeptr++ = 'w';
00058     *fmodeptr++ = 'b';
00059     *fmodeptr = '\0';
00060         
00061     file = gzopen(name,fmode);
00062     if (file == NULL)
00063       return (zipstreambuf*)0;
00064   
00065     opened = 1;
00066     return this;
00067   }
00068 
00069   
00070   zipstreambuf* close() {
00071     if (opened)
00072       {
00073         sync();
00074         opened = 0;
00075         if (gzclose(file) == Z_OK)
00076           return this;
00077       }
00078     return (zipstreambuf*)0;
00079   }
00080     
00081   
00082   ~zipstreambuf() { close(); }
00083 
00084   virtual int     overflow(int c=EOF) {
00085         
00086     if (!(mode&ios::out) || !opened || allocate()==EOF) return EOF;
00087     if (gptr() && egptr() > gptr())
00088       return EOF;
00089 
00090     setg(0,0,0);
00091 
00092     // make sure there is a put area
00093     if (!pptr()) setp(base(),base());
00094 
00095     int w = pptr() -pbase();
00096 
00097     if (c != EOF)
00098       {
00099         *pptr() = c;
00100         ++w;
00101       }
00102 
00103     if (gzwrite(file,pbase(),w))
00104       {
00105         setp(base(),ebuf()-1);
00106         return zapeof(c);
00107       }
00108 
00109     setp(0,0);
00110     return EOF;
00111   }
00112 
00113     
00114   virtual int     underflow() {
00115     if (gptr() && gptr() < egptr()) return zapeof(*gptr());
00116 
00117     if (!(mode&ios::in) || !opened || allocate()==EOF) return EOF;
00118 
00119     int count = gzread(file,base(),blen());
00120     if (count < 1)
00121       {
00122         setg(0,0,0);
00123         return EOF;
00124       }
00125     setg(base(),base(),base()+count);
00126     return zapeof(*base());
00127   }
00128 
00129 
00130     
00131   virtual int     sync() {
00132     if (gptr() && egptr() > gptr())
00133       return EOF;
00134     if (pptr() && pptr() > pbase())
00135       return overflow(EOF);
00136 
00137     return 0;
00138   }
00139 
00140   /* NYI
00141      virtual streambuf*
00142      setbuf(char*  p, int len) ;
00143   */
00144 };
00145 
00146 
00147 
00148 class zipstreambase : virtual public ios
00149 {
00150   zipstreambuf buf;
00151 public:
00152   zipstreambase() {init(&buf);}
00153   zipstreambase(const char* name, int mode) {
00154     init(&buf);
00155     open(name,mode);
00156   }
00157   ~zipstreambase() {
00158     if(buf.is_open())
00159       buf.close();
00160   }
00161 
00162   void open(const char* name, int mode){
00163     if (!buf.open(name,mode))
00164       clear(rdstate() & ios::badbit);
00165   }
00166 
00167   void close(){
00168     if (buf.is_open())
00169       if (!buf.close())
00170         clear(rdstate() & ios::badbit);
00171   }
00172 
00175   inline operator bool()  const {  return  buf.is_open(); }
00176   inline bool operator!() const {  return !buf.is_open(); }  
00177 
00178   // NYI  void setbuf(char*  p, int l);
00179   zipstreambuf* rdbuf() { return &buf; }
00180 };
00181 
00182 
00183 
00184 class izipstream : public zipstreambase, public istream
00185 {
00186 public:
00187   izipstream() {}
00188   izipstream(const char* name,
00189              int mode=ios::in)
00190     : zipstreambase(name,mode) {}
00191 
00192   zipstreambuf* rdbuf() {return zipstreambase::rdbuf(); }
00193   void open(const char* name)
00194     {zipstreambase::open(name,ios::in);}
00195 };
00196 
00197 
00198 
00199 class ozipstream : public zipstreambase, public ostream
00200 {
00201 public:
00202   ozipstream() {}
00203   ozipstream(const char* name,
00204              int mode=ios::out)
00205     : zipstreambase(name,mode) {}
00206 
00207   zipstreambuf* rdbuf() {return zipstreambase::rdbuf(); }
00208   void open(const char* name)
00209     {zipstreambase::open(name,ios::out);}
00210 };
00211 
00212 
00213 #endif /* __ZIPIOSTREAM_H__ */

Generated on Mon Jan 20 02:35:46 2003 for RF-LISSOM by doxygen1.3-rc2