2 #include "zipios++/zipios-config.h"
4 #include "zipios++/meta-iostreams.h"
9 #include "zipios_common.h"
10 #include "zipios++/ziphead.h"
11 #include "zipios++/zipheadio.h"
12 #include "zipios++/zipios_defs.h"
14 #include "outputstringstream.h"
20 bool operator== ( const ZipLocalEntry &zlh, const ZipCDirEntry &ze ) {
21 // Not all fields need to be identical. Some of the information
22 // may be put in a data descriptor that trails the compressed
23 // data, according to the specs (The trailing data descriptor
24 // can contain crc_32, compress_size and uncompress_size.)
26 // Experience has shown that extra_field and extra_field_len
29 // cerr << "----- BEGIN -----" << endl ;
30 // cerr << ( zlh.extract_version == ze.extract_version ) << endl ;
31 // cerr << ( zlh.gp_bitfield == ze.gp_bitfield ) << endl ;
32 // cerr << ( zlh.compress_method == ze.compress_method ) << endl ;
33 // cerr << ( zlh.last_mod_ftime == ze.last_mod_ftime ) << endl ;
34 // cerr << ( zlh.last_mod_fdate == ze.last_mod_fdate ) << endl ;
36 // cerr << ( zlh.filename_len == ze.filename_len ) << endl ;
38 // cerr << ( zlh.filename == ze.filename ) << endl ;
39 // cerr << "----- END -----" << endl ;
40 return ( zlh.extract_version == ze.extract_version &&
41 zlh.gp_bitfield == ze.gp_bitfield &&
42 zlh.compress_method == ze.compress_method &&
43 zlh.last_mod_ftime == ze.last_mod_ftime &&
44 zlh.last_mod_fdate == ze.last_mod_fdate &&
45 zlh.filename_len == ze.filename_len &&
47 zlh.filename == ze.filename ) ;
51 // ZipLocalEntry methods
54 const uint32 ZipLocalEntry::signature = 0x04034b50 ;
58 void ZipLocalEntry::setDefaultExtract() {
59 extract_version = 20 ; // version number
62 string ZipLocalEntry::getComment() const {
63 return "" ; // No comment in a local entry
66 uint32 ZipLocalEntry::getCompressedSize() const {
67 return compress_size ;
70 uint32 ZipLocalEntry::getCrc() const {
74 vector< unsigned char > ZipLocalEntry::getExtra() const {
78 StorageMethod ZipLocalEntry::getMethod() const {
79 return static_cast< StorageMethod >( compress_method ) ;
82 string ZipLocalEntry::getName() const {
86 string ZipLocalEntry::getFileName() const {
89 string::size_type pos ;
90 pos = filename.find_last_of( separator ) ;
91 if ( pos != string::npos ) { // separator found!
92 // isDirectory() check means pos should not be last, so pos+1 is ok
93 return filename.substr( pos + 1 ) ;
99 uint32 ZipLocalEntry::getSize() const {
100 return uncompress_size ;
103 int ZipLocalEntry::getTime() const {
104 return ( last_mod_fdate << 16 ) + last_mod_ftime ;
105 // FIXME: what to do with this time date thing? (not only here?)
108 bool ZipLocalEntry::isValid() const {
112 bool ZipLocalEntry::isDirectory() const {
113 assert( filename.size() != 0 ) ;
114 return filename[ filename.size() - 1 ] == separator ;
118 void ZipLocalEntry::setComment( const string & ) {
119 // A local entry cannot hold a comment
122 void ZipLocalEntry::setCompressedSize( uint32 size ) {
123 compress_size = size ;
126 void ZipLocalEntry::setCrc( uint32 crc ) {
130 void ZipLocalEntry::setExtra( const vector< unsigned char > &extra ) {
131 extra_field = extra ;
132 extra_field_len = static_cast< uint16 >( extra_field.size() ) ;
135 void ZipLocalEntry::setMethod( StorageMethod method ) {
136 compress_method = static_cast< uint16 >( method ) ;
139 void ZipLocalEntry::setName( const string &name ) {
141 filename_len = static_cast< uint16 >( filename.size() ) ;
144 void ZipLocalEntry::setSize( uint32 size ) {
145 uncompress_size = size ;
148 void ZipLocalEntry::setTime( int time ) {
149 // FIXME: fix time setting here, and ind flist and elsewhere. Define the
150 // date time semantics before mucking about - how surprising
152 // Mark Donszelmann: added these lines to make zip work for winzip
153 last_mod_fdate = (time >> 16) & 0x0000FFFF;
154 last_mod_ftime = time & 0x0000FFFF;
157 string ZipLocalEntry::toString() const {
158 OutputStringStream sout ;
159 sout << filename << " (" << uncompress_size << " bytes, " ;
160 sout << compress_size << " bytes compressed)" ;
164 int ZipLocalEntry::getLocalHeaderSize() const {
165 return static_cast< int >( 30 + filename.size() + extra_field.size() ) ;
168 bool ZipLocalEntry::trailingDataDescriptor() const {
169 // gp_bitfield bit 3 is one, if this entry uses a trailing data
170 // descriptor to keep size, compressed size and crc-32
172 if ( ( gp_bitfield & 4 ) == 1 )
178 FileEntry *ZipLocalEntry::clone() const {
179 return new ZipLocalEntry( *this ) ;
184 // ZipCDirEntry methods
187 const uint32 ZipCDirEntry::signature = 0x02014b50 ;
189 void ZipCDirEntry::setDefaultWriter() {
192 writer_version |= static_cast< uint16 >( 0 ) << 8 ; // Windows, DOS
194 writer_version |= static_cast< uint16 >( 3 ) << 8 ; // Unix
196 writer_version |= 20 ; // version number
199 string ZipCDirEntry::getComment() const {
200 return file_comment ;
203 uint32 ZipCDirEntry::getLocalHeaderOffset() const {
204 return rel_offset_loc_head ;
207 void ZipCDirEntry::setLocalHeaderOffset( uint32 offset ) {
208 rel_offset_loc_head = offset ;
212 void ZipCDirEntry::setComment( const string &comment ) {
213 file_comment = comment ;
214 file_comment_len = static_cast< uint16 >( file_comment.size() ) ;
218 string ZipCDirEntry::toString() const {
219 OutputStringStream sout ;
220 sout << filename << " (" << uncompress_size << " bytes, " ;
221 sout << compress_size << " bytes compressed)" ;
226 int ZipCDirEntry::getCDirHeaderSize() const {
227 return static_cast< int >( 46 + filename.size() + extra_field.size() + file_comment.size() ) ;
231 FileEntry *ZipCDirEntry::clone() const {
232 return new ZipCDirEntry( *this ) ;
237 // EndOfCentralDirectory methods
240 const uint32 EndOfCentralDirectory::signature = 0x06054b50 ;
242 bool EndOfCentralDirectory::read( vector<unsigned char> &buf, int pos ) {
243 if ( ( buf.size() - pos < sizeof( uint32 ) ) ||
244 ( ! checkSignature( &( buf[ pos ] ) ) ) )
247 eocd_offset_from_end = buf.size() - pos ;
248 pos += sizeof( uint32 ) ;
249 disk_num = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ;
250 cdir_disk_num = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ;
251 cdir_entries = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ;
252 cdir_tot_entries = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ;
253 cdir_size = ztohl( &( buf[ pos ] ) ) ; pos += sizeof( uint32 ) ;
254 cdir_offset = ztohl( &( buf[ pos ] ) ) ; pos += sizeof( uint32 ) ;
255 zip_comment_len = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ;
256 // cerr << "Zip comment length = " << zip_comment_len << endl ;
257 // cerr << "Length of remaining file = " << buf.size() - pos << endl ;
259 return true ; // Dummy
262 bool EndOfCentralDirectory::checkSignature ( unsigned char *buf ) const {
263 // cerr << "potential header: " << ztohl( buf ) << endl ;
264 return checkSignature( ztohl( buf ) ) ;
274 Implementation of routines for reading the central directory and
275 local headers of a zip archive.
279 Zipios++ - a small C++ library that provides easy access to .zip files.
280 Copyright (C) 2000 Thomas Søndergaard
282 This library is free software; you can redistribute it and/or
283 modify it under the terms of the GNU Lesser General Public
284 License as published by the Free Software Foundation; either
285 version 2 of the License, or (at your option) any later version.
287 This library is distributed in the hope that it will be useful,
288 but WITHOUT ANY WARRANTY; without even the implied warranty of
289 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
290 Lesser General Public License for more details.
292 You should have received a copy of the GNU Lesser General Public
293 License along with this library; if not, write to the Free Software
294 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA