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 ;
00026 }
00027 }
00028
00029 void ZipInputStreambuf::closeEntry() {
00030 if ( ! _open_entry )
00031 return ;
00032
00033
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
00050 istream is( _inbuf ) ;
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() ;
00058
00059 } else if ( _curr_entry.getMethod() == STORED ) {
00060 _open_entry = true ;
00061 _remain = _curr_entry.getSize() ;
00062
00063 setg( &( _outvec[ 0 ] ),
00064 &( _outvec[ 0 ] ) + _outvecsize,
00065 &( _outvec[ 0 ] ) + _outvecsize ) ;
00066
00067 } else {
00068 _open_entry = false ;
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 ;
00088 if ( _curr_entry.getMethod() == DEFLATED )
00089 return InflateInputStreambuf::underflow() ;
00090
00091
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 ;
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 }
00118
00123 00124 00125 00126 00127 00128 00129 00130 00131 00132 00133 00134 00135 00136 00137 00138 00139 00140