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