2
#include "zipios-config.h"
4
#include "meta-iostreams.h"
8
#include "zipinputstream.h"
9
#include "zipios_defs.h"
11
#include "backbuffer.h"
12
#if defined(_WIN32) && defined(ZIPIOS_UTF8)
13
#include <Base/FileInfo.h>
22
ZipFile ZipFile::openEmbeddedZipFile( const string &name ) {
23
// open zipfile, read 4 last bytes close file
24
// create ZipFile object.
25
ifstream ifs( name.c_str(), ios::in | ios::binary ) ;
26
ifs.seekg( -4, ios::end ) ;
27
uint32 start_offset = readUint32( ifs ) ;
29
return ZipFile( name, start_offset, 4 ) ;
33
ZipFile::ZipFile( const string &name , int s_off, int e_off
34
/* , ios::open_mode mode */ )
35
: _vs( s_off, e_off ) {
39
#if defined(_WIN32) && defined(ZIPIOS_UTF8)
40
std::wstring wsname = Base::FileInfo(name).toStdWString();
41
ifstream _zipfile( wsname.c_str(), ios::in | ios::binary ) ;
43
ifstream _zipfile( name.c_str(), ios::in | ios::binary ) ;
49
FileCollection *ZipFile::clone() const {
50
return new ZipFile( *this ) ;
58
void ZipFile::close() {
63
istream *ZipFile::getInputStream( const ConstEntryPointer &entry ) {
65
throw InvalidStateException( "Attempt to use an invalid FileCollection" ) ;
66
return getInputStream( entry->getName() ) ;
69
istream *ZipFile::getInputStream( const string &entry_name,
70
MatchPath matchpath ) {
72
throw InvalidStateException( "Attempt to use an invalid ZipFile" ) ;
74
ConstEntryPointer ent = getEntry( entry_name, matchpath ) ;
79
return new ZipInputStream( _filename,
80
static_cast< const ZipCDirEntry * >( ent.get() )->
81
getLocalHeaderOffset() + _vs.startOffset() ) ;
89
bool ZipFile::init( istream &_zipfile ) {
91
// Check stream error state
93
setError ( "Error reading from file" ) ;
97
_valid = readCentralDirectory( _zipfile ) ;
103
bool ZipFile::readCentralDirectory ( istream &_zipfile ) {
104
// Find and read eocd.
105
if ( ! readEndOfCentralDirectory( _zipfile ) )
106
throw FCollException( "Unable to find zip structure: End-of-central-directory" ) ;
108
// Position read pointer to start of first entry in central dir.
109
_vs.vseekg( _zipfile, _eocd.offset(), ios::beg ) ;
112
// Giving the default argument in the next line to keep Visual C++ quiet
113
_entries.resize ( _eocd.totalCount(), nullptr ) ;
114
while ( ( entry_num < _eocd.totalCount() ) ) {
115
ZipCDirEntry *ent = new ZipCDirEntry ;
116
_entries[ entry_num ] = ent ;
119
if ( _zipfile.bad() )
120
throw IOException( "Error reading zip file while reading zip file central directory" ) ;
121
else if ( _zipfile.fail() )
122
throw FCollException( "Zip file consistency problem. Failure while reading zip file central directory" ) ;
123
else if ( _zipfile.eof() )
124
throw IOException( "Premature end of file while reading zip file central directory" ) ;
129
// Consistency check. eocd should start here
131
int pos = _vs.vtellg( _zipfile ) ;
132
_vs.vseekg( _zipfile, 0, ios::end ) ;
133
int remaining = static_cast< int >( _vs.vtellg( _zipfile ) ) - pos ;
134
if ( remaining != _eocd.eocdOffSetFromEnd() )
135
throw FCollException( "Zip file consistency problem. Zip file data fields are inconsistent with zip file layout" ) ;
137
// Consistency check 2, are local headers consistent with
139
if ( ! confirmLocalHeaders( _zipfile ) )
140
throw FCollException( "Zip file consistency problem. Zip file data fields are inconsistent with zip file layout" ) ;
146
bool ZipFile::readEndOfCentralDirectory ( istream &_zipfile ) {
147
BackBuffer bb( _zipfile, _vs ) ;
152
if ( ! bb.readChunk ( read_p ) ) {
156
if ( _eocd.read( bb, read_p ) ) {
166
bool ZipFile::confirmLocalHeaders( istream &_zipfile ) {
167
Entries::const_iterator it ;
169
int inconsistencies = 0 ;
171
for ( it = _entries.begin() ; it != _entries.end() ; it++ ) {
172
ent = static_cast< ZipCDirEntry * >( (*it).get() ) ;
173
_vs.vseekg( _zipfile, ent->getLocalHeaderOffset(), ios::beg ) ;
175
if ( ! _zipfile || zlh != *ent ) {
180
return ! inconsistencies ;
183
void ZipFile::setError ( string error_str ) {
185
#ifdef _USE_EXCEPTIONS
186
throw error_str ; // define exception class instead.
188
cerr << error_str << endl ; // define operator<< for exception class if such a class replaces string
196
The implementation of ZipFile.
200
Zipios++ - a small C++ library that provides easy access to .zip files.
201
Copyright (C) 2000 Thomas Søndergaard
203
This library is free software; you can redistribute it and/or
204
modify it under the terms of the GNU Lesser General Public
205
License as published by the Free Software Foundation; either
206
version 2 of the License, or (at your option) any later version.
208
This library is distributed in the hope that it will be useful,
209
but WITHOUT ANY WARRANTY; without even the implied warranty of
210
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
211
Lesser General Public License for more details.
213
You should have received a copy of the GNU Lesser General Public
214
License along with this library; if not, write to the Free Software
215
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA