FreeCAD
1
2#include "zipios-config.h"3
4#include <algorithm>5#include "meta-iostreams.h"6
7#include <zlib.h>8
9#include "zipinputstreambuf.h"10#include "zipios_common.h"11
12namespace zipios {13
14using std::ios ;15using std::cerr ;16using std::endl ;17
18ZipInputStreambuf::ZipInputStreambuf( streambuf *inbuf, int s_pos, bool del_inbuf )19: InflateInputStreambuf( inbuf, s_pos, del_inbuf ),20_open_entry( false )21{
22ConstEntryPointer entry = getNextEntry() ;23
24if ( ! entry->isValid() ) {25; // FIXME: throw something?26}27}
28
29void ZipInputStreambuf::closeEntry() {30if ( ! _open_entry )31return ;32
33// check if we're positioned correctly, otherwise position us correctly34int position = _inbuf->pubseekoff(0, ios::cur,35ios::in);36if ( position != _data_start + static_cast< int >( _curr_entry.getCompressedSize() ) )37_inbuf->pubseekoff(_data_start + _curr_entry.getCompressedSize(),38ios::beg, ios::in) ;39
40}
41
42void ZipInputStreambuf::close() {43}
44
45ConstEntryPointer ZipInputStreambuf::getNextEntry() {46if ( _open_entry )47closeEntry() ;48
49// read the zip local header50istream is( _inbuf ) ; // istream does not destroy the streambuf.51is.exceptions(istream::eofbit | istream::failbit | istream::badbit);52is >> _curr_entry ;53if ( _curr_entry.isValid() ) {54_data_start = _inbuf->pubseekoff(0, ios::cur,55ios::in);56if ( _curr_entry.getMethod() == DEFLATED ) {57_open_entry = true ;58reset() ; // reset inflatestream data structures59// cerr << "deflated" << endl ;
60} else if ( _curr_entry.getMethod() == STORED ) {61_open_entry = true ;62_remain = _curr_entry.getSize() ;63// Force underflow on first read:64setg( &( _outvec[ 0 ] ),65&( _outvec[ 0 ] ) + _outvecsize,66&( _outvec[ 0 ] ) + _outvecsize ) ;67// cerr << "stored" << endl ;
68} else {69_open_entry = false ; // Unsupported compression format.70throw FCollException( "Unsupported compression format" ) ;71}72} else {73_open_entry = false ;74}75
76if ( _curr_entry.isValid() && _curr_entry.trailingDataDescriptor() )77throw FCollException( "Trailing data descriptor in zip file not supported" ) ;78return new ZipLocalEntry( _curr_entry ) ;79}
80
81
82ZipInputStreambuf::~ZipInputStreambuf() {83}
84
85
86int ZipInputStreambuf::underflow() {87if ( ! _open_entry )88return EOF ; // traits_type::eof()89if ( _curr_entry.getMethod() == DEFLATED )90return InflateInputStreambuf::underflow() ;91
92// Ok, we're are stored, so we handle it ourselves.93int num_b = min( _remain, _outvecsize ) ;94int g = _inbuf->sgetn( &(_outvec[ 0 ] ) , num_b ) ;95setg( &( _outvec[ 0 ] ),96&( _outvec[ 0 ] ),97&( _outvec[ 0 ] ) + g ) ;98_remain -= g ;99if ( g > 0 )100return static_cast< unsigned char >( *gptr() ) ;101else102return EOF ; // traits_type::eof()103}
104
105
106// FIXME: We need to check somew
107//
108// // gp_bitfield bit 3 is one, if the length of the zip entry
109// // is stored in a trailer.
110// if ( is->good && ( _curr_entry.gp_bitfield & 4 ) != 1 )
111// return true ;
112// else {
113// is->clear() ;
114// return false ;
115// }
116
117
118} // namespace119
120/** \file
121Implementation of ZipInputStreambuf.
122*/
123
124/*
125Zipios++ - a small C++ library that provides easy access to .zip files.
126Copyright (C) 2000 Thomas Søndergaard
127
128This library is free software; you can redistribute it and/or
129modify it under the terms of the GNU Lesser General Public
130License as published by the Free Software Foundation; either
131version 2 of the License, or (at your option) any later version.
132
133This library is distributed in the hope that it will be useful,
134but WITHOUT ANY WARRANTY; without even the implied warranty of
135MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
136Lesser General Public License for more details.
137
138You should have received a copy of the GNU Lesser General Public
139License along with this library; if not, write to the Free Software
140Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
141*/
142