Main Page   Class Hierarchy   Compound List   File List   Compound Members  

zipinputstreambuf.cpp

Go to the documentation of this file.
00001 
00002 #include "zipios++/zipios-config.h"
00003 
00004 #include <algorithm>
00005 #include "zipios++/meta-iostreams.h"
00006 
00007 #include <zlib.h>
00008 
00009 #include "zipios++/zipinputstreambuf.h"
00010 #include "zipios_common.h"
00011 
00012 namespace zipios {
00013 
00014 using std::ios ;
00015 using std::cerr ;
00016 using std::endl ;
00017 
00018 ZipInputStreambuf::ZipInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf ) 
00019   : InflateInputStreambuf( inbuf, s_pos, del_inbuf ),
00020     _open_entry( false                   ) 
00021 {
00022   ConstEntryPointer entry = getNextEntry() ;
00023   
00024   if ( ! entry->isValid() ) {
00025     ; // FIXME: throw something?
00026   }
00027 }
00028 
00029 void ZipInputStreambuf::closeEntry() {
00030   if ( ! _open_entry )
00031     return ;
00032   
00033   // check if we're positioned correctly, otherwise position us correctly
00034   int position = _inbuf->pubseekoff(0, ios::cur, 
00035                                     ios::in);
00036   if ( position != _data_start + static_cast< int >( _curr_entry.getCompressedSize() ) )
00037     _inbuf->pubseekoff(_data_start + _curr_entry.getCompressedSize(), 
00038                        ios::beg, ios::in) ;
00039 
00040 }
00041 
00042 void ZipInputStreambuf::close() {
00043 }
00044 
00045 ConstEntryPointer ZipInputStreambuf::getNextEntry() {
00046   if ( _open_entry )
00047     closeEntry() ;
00048 
00049   // read the zip local header
00050   istream is( _inbuf ) ; // istream does not destroy the streambuf.
00051   is >> _curr_entry ;
00052   if ( _curr_entry.isValid() ) {
00053     _data_start = _inbuf->pubseekoff(0, ios::cur, 
00054                                      ios::in);
00055     if ( _curr_entry.getMethod() == DEFLATED ) {
00056       _open_entry = true ;
00057       reset() ; // reset inflatestream data structures 
00058 //        cerr << "deflated" << endl ;
00059     } else if ( _curr_entry.getMethod() == STORED ) {
00060       _open_entry = true ;
00061       _remain = _curr_entry.getSize() ;
00062       // Force underflow on first read:
00063       setg( &( _outvec[ 0 ] ),
00064             &( _outvec[ 0 ] ) + _outvecsize,
00065             &( _outvec[ 0 ] ) + _outvecsize ) ;
00066 //        cerr << "stored" << endl ;
00067     } else {
00068       _open_entry = false ; // Unsupported compression format.
00069       throw FCollException( "Unsupported compression format" ) ;
00070     }
00071   } else {
00072     _open_entry = false ;
00073   }
00074 
00075   if ( _curr_entry.isValid() && _curr_entry.trailingDataDescriptor() )
00076     throw FCollException( "Trailing data descriptor in zip file not supported" ) ; 
00077   return new ZipLocalEntry( _curr_entry ) ;
00078 }
00079 
00080 
00081 ZipInputStreambuf::~ZipInputStreambuf() {
00082 }
00083 
00084 
00085 int ZipInputStreambuf::underflow() {
00086   if ( ! _open_entry )
00087     return EOF ; // traits_type::eof() 
00088   if ( _curr_entry.getMethod() == DEFLATED )
00089     return InflateInputStreambuf::underflow() ;
00090 
00091   // Ok, we're are stored, so we handle it ourselves.
00092   int num_b = min( _remain, _outvecsize ) ;
00093   int g = _inbuf->sgetn( &(_outvec[ 0 ] ) , num_b ) ;
00094   setg( &( _outvec[ 0 ] ),
00095         &( _outvec[ 0 ] ),
00096         &( _outvec[ 0 ] ) + g ) ;
00097   _remain -= g ;
00098   if ( g > 0 )
00099     return static_cast< unsigned char >( *gptr() ) ;
00100   else
00101     return EOF ; // traits_type::eof() 
00102 }
00103 
00104 
00105 // FIXME: We need to check somew
00106 //  
00107 //    // gp_bitfield bit 3 is one, if the length of the zip entry
00108 //    // is stored in a trailer.
00109 //    if ( is->good  && ( _curr_entry.gp_bitfield & 4 ) != 1 )
00110 //      return true ;
00111 //    else {
00112 //      is->clear() ;
00113 //      return false ;
00114 //    }
00115 
00116 
00117 } // namespace
00118 
00123 /*
00124   Zipios++ - a small C++ library that provides easy access to .zip files.
00125   Copyright (C) 2000  Thomas Søndergaard
00126   
00127   This library is free software; you can redistribute it and/or
00128   modify it under the terms of the GNU Lesser General Public
00129   License as published by the Free Software Foundation; either
00130   version 2 of the License, or (at your option) any later version.
00131   
00132   This library is distributed in the hope that it will be useful,
00133   but WITHOUT ANY WARRANTY; without even the implied warranty of
00134   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00135   Lesser General Public License for more details.
00136   
00137   You should have received a copy of the GNU Lesser General Public
00138   License along with this library; if not, write to the Free Software
00139   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
00140 */

Generated at Tue Aug 14 20:39:26 2001 for Zipios++ by doxygen1.2.0 written by Dimitri van Heesch, © 1997-2000