2 #include "zipios++/zipios-config.h"
4 #include "zipios++/meta-iostreams.h"
6 #include "zipios++/fcoll.h"
7 #include "zipios++/zipfile.h"
8 #include "zipios++/zipinputstream.h"
9 #include "zipios++/zipios_defs.h"
11 #include "backbuffer.h"
13 #include "../../FlightCrew/Misc/BoostFilesystemUse.h"
21 ZipFile ZipFile::openEmbeddedZipFile( const string &name ) {
22 // open zipfile, read 4 last bytes close file
23 // create ZipFile object.
24 ifstream ifs( name.c_str(), ios::in | ios::binary ) ;
25 ifs.seekg( -4, ios::end ) ;
26 uint32 start_offset = readUint32( ifs ) ;
28 return ZipFile( name, start_offset, 4 ) ;
32 ZipFile::ZipFile( const string &name , int s_off, int e_off
33 /* , ios::open_mode mode */ )
34 : _vs( s_off, e_off ) {
38 ifstream _zipfile( name.c_str(), ios::in | ios::binary ) ;
42 ZipFile::ZipFile( const fs::path &name , int s_off, int e_off
43 /* , ios::open_mode mode */ )
44 : _vs( s_off, e_off ) {
46 _filename = name.string();
48 fs::ifstream _zipfile( name, ios::in | ios::binary ) ;
53 FileCollection *ZipFile::clone() const {
54 return new ZipFile( *this ) ;
62 void ZipFile::close() {
67 istream *ZipFile::getInputStream( const ConstEntryPointer &entry ) {
69 throw InvalidStateException( "Attempt to use an invalid FileCollection" ) ;
70 return getInputStream( entry->getName() ) ;
73 istream *ZipFile::getInputStream( const string &entry_name,
74 MatchPath matchpath ) {
76 throw InvalidStateException( "Attempt to use an invalid ZipFile" ) ;
78 ConstEntryPointer ent = getEntry( entry_name, matchpath ) ;
83 ZipInputStream *zis( new ZipInputStream( _filename,
84 static_cast< const ZipCDirEntry * >( ent.get() )->
85 getLocalHeaderOffset() + _vs.startOffset() ) ) ;
96 bool ZipFile::init( istream &_zipfile ) {
98 // Check stream error state
100 setError ( "Error reading from file" ) ;
104 _valid = readCentralDirectory( _zipfile ) ;
110 bool ZipFile::readCentralDirectory ( istream &_zipfile ) {
111 // Find and read eocd.
112 if ( ! readEndOfCentralDirectory( _zipfile ) )
113 throw FCollException( "Unable to find zip structure: End-of-central-directory" ) ;
115 // Position read pointer to start of first entry in central dir.
116 _vs.vseekg( _zipfile, _eocd.offset(), ios::beg ) ;
119 // Giving the default argument in the next line to keep Visual C++ quiet
120 _entries.resize ( _eocd.totalCount(), 0 ) ;
121 while ( ( entry_num < _eocd.totalCount() ) ) {
122 ZipCDirEntry *ent = new ZipCDirEntry ;
123 _entries[ entry_num ] = ent ;
126 if ( _zipfile.bad() )
127 throw IOException( "Error reading zip file while reading zip file central directory" ) ;
128 else if ( _zipfile.fail() )
129 throw FCollException( "Zip file consistency problem. Failure while reading zip file central directory" ) ;
130 else if ( _zipfile.eof() )
131 throw IOException( "Premature end of file while reading zip file central directory" ) ;
136 // Consistency check. eocd should start here
138 int pos = _vs.vtellg( _zipfile ) ;
139 _vs.vseekg( _zipfile, 0, ios::end ) ;
140 int remaining = static_cast< int >( _vs.vtellg( _zipfile ) ) - pos ;
141 if ( remaining != _eocd.eocdOffSetFromEnd() )
142 throw FCollException( "Zip file consistency problem. Zip file data fields are inconsistent with zip file layout" ) ;
144 // Consistency check 2, are local headers consistent with
146 if ( ! confirmLocalHeaders( _zipfile ) )
147 throw FCollException( "Zip file consistency problem. Zip file data fields are inconsistent with zip file layout" ) ;
153 bool ZipFile::readEndOfCentralDirectory ( istream &_zipfile ) {
154 BackBuffer bb( _zipfile, _vs ) ;
159 if ( ! bb.readChunk ( read_p ) ) {
163 if ( _eocd.read( bb, read_p ) ) {
173 bool ZipFile::confirmLocalHeaders( istream &_zipfile ) {
174 Entries::const_iterator it ;
176 int inconsistencies = 0 ;
178 for ( it = _entries.begin() ; it != _entries.end() ; it++ ) {
179 ent = static_cast< ZipCDirEntry * >( (*it).get() ) ;
180 _vs.vseekg( _zipfile, ent->getLocalHeaderOffset(), ios::beg ) ;
182 if ( ! _zipfile || zlh != *ent ) {
187 return ! inconsistencies ;
190 void ZipFile::setError ( string error_str ) {
192 #ifdef _USE_EXCEPTIONS
193 throw error_str ; // define exception class instead.
195 cerr << error_str << endl ; // define operator<< for exception class if such a class replaces string
203 The implementation of ZipFile.
207 Zipios++ - a small C++ library that provides easy access to .zip files.
208 Copyright (C) 2000 Thomas Søndergaard
210 This library is free software; you can redistribute it and/or
211 modify it under the terms of the GNU Lesser General Public
212 License as published by the Free Software Foundation; either
213 version 2 of the License, or (at your option) any later version.
215 This library is distributed in the hope that it will be useful,
216 but WITHOUT ANY WARRANTY; without even the implied warranty of
217 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
218 Lesser General Public License for more details.
220 You should have received a copy of the GNU Lesser General Public
221 License along with this library; if not, write to the Free Software
222 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA