Home | History | Annotate | Download | only in iostream
      1 
      2 #include "zfstream.h"
      3 
      4 gzfilebuf::gzfilebuf() :
      5   file(NULL),
      6   mode(0),
      7   own_file_descriptor(0)
      8 { }
      9 
     10 gzfilebuf::~gzfilebuf() {
     11 
     12   sync();
     13   if ( own_file_descriptor )
     14     close();
     15 
     16 }
     17 
     18 gzfilebuf *gzfilebuf::open( const char *name,
     19                             int io_mode ) {
     20 
     21   if ( is_open() )
     22     return NULL;
     23 
     24   char char_mode[10];
     25   char *p = char_mode;
     26 
     27   if ( io_mode & ios::in ) {
     28     mode = ios::in;
     29     *p++ = 'r';
     30   } else if ( io_mode & ios::app ) {
     31     mode = ios::app;
     32     *p++ = 'a';
     33   } else {
     34     mode = ios::out;
     35     *p++ = 'w';
     36   }
     37 
     38   if ( io_mode & ios::binary ) {
     39     mode |= ios::binary;
     40     *p++ = 'b';
     41   }
     42 
     43   // Hard code the compression level
     44   if ( io_mode & (ios::out|ios::app )) {
     45     *p++ = '9';
     46   }
     47 
     48   // Put the end-of-string indicator
     49   *p = '\0';
     50 
     51   if ( (file = gzopen(name, char_mode)) == NULL )
     52     return NULL;
     53 
     54   own_file_descriptor = 1;
     55 
     56   return this;
     57 
     58 }
     59 
     60 gzfilebuf *gzfilebuf::attach( int file_descriptor,
     61                               int io_mode ) {
     62 
     63   if ( is_open() )
     64     return NULL;
     65 
     66   char char_mode[10];
     67   char *p = char_mode;
     68 
     69   if ( io_mode & ios::in ) {
     70     mode = ios::in;
     71     *p++ = 'r';
     72   } else if ( io_mode & ios::app ) {
     73     mode = ios::app;
     74     *p++ = 'a';
     75   } else {
     76     mode = ios::out;
     77     *p++ = 'w';
     78   }
     79 
     80   if ( io_mode & ios::binary ) {
     81     mode |= ios::binary;
     82     *p++ = 'b';
     83   }
     84 
     85   // Hard code the compression level
     86   if ( io_mode & (ios::out|ios::app )) {
     87     *p++ = '9';
     88   }
     89 
     90   // Put the end-of-string indicator
     91   *p = '\0';
     92 
     93   if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
     94     return NULL;
     95 
     96   own_file_descriptor = 0;
     97 
     98   return this;
     99 
    100 }
    101 
    102 gzfilebuf *gzfilebuf::close() {
    103 
    104   if ( is_open() ) {
    105 
    106     sync();
    107     gzclose( file );
    108     file = NULL;
    109 
    110   }
    111 
    112   return this;
    113 
    114 }
    115 
    116 int gzfilebuf::setcompressionlevel( int comp_level ) {
    117 
    118   return gzsetparams(file, comp_level, -2);
    119 
    120 }
    121 
    122 int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
    123 
    124   return gzsetparams(file, -2, comp_strategy);
    125 
    126 }
    127 
    128 
    129 streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
    130 
    131   return streampos(EOF);
    132 
    133 }
    134 
    135 int gzfilebuf::underflow() {
    136 
    137   // If the file hasn't been opened for reading, error.
    138   if ( !is_open() || !(mode & ios::in) )
    139     return EOF;
    140 
    141   // if a buffer doesn't exists, allocate one.
    142   if ( !base() ) {
    143 
    144     if ( (allocate()) == EOF )
    145       return EOF;
    146     setp(0,0);
    147 
    148   } else {
    149 
    150     if ( in_avail() )
    151       return (unsigned char) *gptr();
    152 
    153     if ( out_waiting() ) {
    154       if ( flushbuf() == EOF )
    155         return EOF;
    156     }
    157 
    158   }
    159 
    160   // Attempt to fill the buffer.
    161 
    162   int result = fillbuf();
    163   if ( result == EOF ) {
    164     // disable get area
    165     setg(0,0,0);
    166     return EOF;
    167   }
    168 
    169   return (unsigned char) *gptr();
    170 
    171 }
    172 
    173 int gzfilebuf::overflow( int c ) {
    174 
    175   if ( !is_open() || !(mode & ios::out) )
    176     return EOF;
    177 
    178   if ( !base() ) {
    179     if ( allocate() == EOF )
    180       return EOF;
    181     setg(0,0,0);
    182   } else {
    183     if (in_avail()) {
    184         return EOF;
    185     }
    186     if (out_waiting()) {
    187       if (flushbuf() == EOF)
    188         return EOF;
    189     }
    190   }
    191 
    192   int bl = blen();
    193   setp( base(), base() + bl);
    194 
    195   if ( c != EOF ) {
    196 
    197     *pptr() = c;
    198     pbump(1);
    199 
    200   }
    201 
    202   return 0;
    203 
    204 }
    205 
    206 int gzfilebuf::sync() {
    207 
    208   if ( !is_open() )
    209     return EOF;
    210 
    211   if ( out_waiting() )
    212     return flushbuf();
    213 
    214   return 0;
    215 
    216 }
    217 
    218 int gzfilebuf::flushbuf() {
    219 
    220   int n;
    221   char *q;
    222 
    223   q = pbase();
    224   n = pptr() - q;
    225 
    226   if ( gzwrite( file, q, n) < n )
    227     return EOF;
    228 
    229   setp(0,0);
    230 
    231   return 0;
    232 
    233 }
    234 
    235 int gzfilebuf::fillbuf() {
    236 
    237   int required;
    238   char *p;
    239 
    240   p = base();
    241 
    242   required = blen();
    243 
    244   int t = gzread( file, p, required );
    245 
    246   if ( t <= 0) return EOF;
    247 
    248   setg( base(), base(), base()+t);
    249 
    250   return t;
    251 
    252 }
    253 
    254 gzfilestream_common::gzfilestream_common() :
    255   ios( gzfilestream_common::rdbuf() )
    256 { }
    257 
    258 gzfilestream_common::~gzfilestream_common()
    259 { }
    260 
    261 void gzfilestream_common::attach( int fd, int io_mode ) {
    262 
    263   if ( !buffer.attach( fd, io_mode) )
    264     clear( ios::failbit | ios::badbit );
    265   else
    266     clear();
    267 
    268 }
    269 
    270 void gzfilestream_common::open( const char *name, int io_mode ) {
    271 
    272   if ( !buffer.open( name, io_mode ) )
    273     clear( ios::failbit | ios::badbit );
    274   else
    275     clear();
    276 
    277 }
    278 
    279 void gzfilestream_common::close() {
    280 
    281   if ( !buffer.close() )
    282     clear( ios::failbit | ios::badbit );
    283 
    284 }
    285 
    286 gzfilebuf *gzfilestream_common::rdbuf()
    287 {
    288   return &buffer;
    289 }
    290 
    291 gzifstream::gzifstream() :
    292   ios( gzfilestream_common::rdbuf() )
    293 {
    294   clear( ios::badbit );
    295 }
    296 
    297 gzifstream::gzifstream( const char *name, int io_mode ) :
    298   ios( gzfilestream_common::rdbuf() )
    299 {
    300   gzfilestream_common::open( name, io_mode );
    301 }
    302 
    303 gzifstream::gzifstream( int fd, int io_mode ) :
    304   ios( gzfilestream_common::rdbuf() )
    305 {
    306   gzfilestream_common::attach( fd, io_mode );
    307 }
    308 
    309 gzifstream::~gzifstream() { }
    310 
    311 gzofstream::gzofstream() :
    312   ios( gzfilestream_common::rdbuf() )
    313 {
    314   clear( ios::badbit );
    315 }
    316 
    317 gzofstream::gzofstream( const char *name, int io_mode ) :
    318   ios( gzfilestream_common::rdbuf() )
    319 {
    320   gzfilestream_common::open( name, io_mode );
    321 }
    322 
    323 gzofstream::gzofstream( int fd, int io_mode ) :
    324   ios( gzfilestream_common::rdbuf() )
    325 {
    326   gzfilestream_common::attach( fd, io_mode );
    327 }
    328 
    329 gzofstream::~gzofstream() { }
    330