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