Zipios++
ziphead.cpp
Go to the documentation of this file.
1 
2 #include "zipios++/zipios-config.h"
3 
4 #include "zipios++/meta-iostreams.h"
5 #include <iterator>
6 #include <string>
7 #include <cassert>
8 
9 #include "zipios_common.h"
10 #include "zipios++/ziphead.h"
11 #include "zipios++/zipheadio.h"
12 #include "zipios++/zipios_defs.h"
13 
14 #include "outputstringstream.h"
15 
16 namespace zipios {
17 
18 using std::ios ;
19 
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.)
25 
26  // Experience has shown that extra_field and extra_field_len
27  // can differ too.
28 
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 ;
35 
36 // cerr << ( zlh.filename_len == ze.filename_len ) << endl ;
37 
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 &&
46 
47  zlh.filename == ze.filename ) ;
48 }
49 
50 //
51 // ZipLocalEntry methods
52 //
53 
54 const uint32 ZipLocalEntry::signature = 0x04034b50 ;
55 
56 
57 
58 void ZipLocalEntry::setDefaultExtract() {
59  extract_version = 20 ; // version number
60 }
61 
62 string ZipLocalEntry::getComment() const {
63  return "" ; // No comment in a local entry
64 }
65 
67  return compress_size ;
68 }
69 
70 uint32 ZipLocalEntry::getCrc() const {
71  return crc_32 ;
72 }
73 
74 vector< unsigned char > ZipLocalEntry::getExtra() const {
75  return extra_field ;
76 }
77 
78 StorageMethod ZipLocalEntry::getMethod() const {
79  return static_cast< StorageMethod >( compress_method ) ;
80 }
81 
82 string ZipLocalEntry::getName() const {
83  return filename ;
84 }
85 
87  if ( isDirectory() )
88  return string() ;
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 ) ;
94  } else {
95  return filename ;
96  }
97 }
98 
99 uint32 ZipLocalEntry::getSize() const {
100  return uncompress_size ;
101 }
102 
104  return ( last_mod_fdate << 16 ) + last_mod_ftime ;
105  // FIXME: what to do with this time date thing? (not only here?)
106 }
107 
109  return _valid ;
110 }
111 
113  assert( filename.size() != 0 ) ;
114  return filename[ filename.size() - 1 ] == separator ;
115 }
116 
117 
118 void ZipLocalEntry::setComment( const string & ) {
119  // A local entry cannot hold a comment
120 }
121 
122 void ZipLocalEntry::setCompressedSize( uint32 size ) {
123  compress_size = size ;
124 }
125 
126 void ZipLocalEntry::setCrc( uint32 crc ) {
127  crc_32 = crc ;
128 }
129 
130 void ZipLocalEntry::setExtra( const vector< unsigned char > &extra ) {
131  extra_field = extra ;
132  extra_field_len = extra_field.size() ;
133 }
134 
135 void ZipLocalEntry::setMethod( StorageMethod method ) {
136  compress_method = static_cast< uint16 >( method ) ;
137 }
138 
139 void ZipLocalEntry::setName( const string &name ) {
140  filename = name ;
141  filename_len = filename.size() ;
142 }
143 
144 void ZipLocalEntry::setSize( uint32 size ) {
145  uncompress_size = size ;
146 }
147 
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
151 
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;
155 }
156 
157 string ZipLocalEntry::toString() const {
158  OutputStringStream sout ;
159  sout << filename << " (" << uncompress_size << " bytes, " ;
160  sout << compress_size << " bytes compressed)" ;
161  return sout.str() ;
162 }
163 
164 int ZipLocalEntry::getLocalHeaderSize() const {
165  return 30 + filename.size() + extra_field.size() ;
166 }
167 
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
171  // fields.
172  if ( ( gp_bitfield & 4 ) == 1 )
173  return true ;
174  else
175  return false ;
176 }
177 
179  return new ZipLocalEntry( *this ) ;
180 }
181 
182 
183 //
184 // ZipCDirEntry methods
185 //
186 
187 const uint32 ZipCDirEntry::signature = 0x02014b50 ;
188 
189 void ZipCDirEntry::setDefaultWriter() {
190  writer_version = 0 ;
191 #ifdef WIN32
192  writer_version |= static_cast< uint16 >( 0 ) << 8 ; // Windows, DOS
193 #else
194  writer_version |= static_cast< uint16 >( 3 ) << 8 ; // Unix
195 #endif
196  writer_version |= 20 ; // version number
197 }
198 
199 string ZipCDirEntry::getComment() const {
200  return file_comment ;
201 }
202 
203 uint32 ZipCDirEntry::getLocalHeaderOffset() const {
204  return rel_offset_loc_head ;
205 }
206 
207 void ZipCDirEntry::setLocalHeaderOffset( uint32 offset ) {
208  rel_offset_loc_head = offset ;
209 }
210 
211 
212 void ZipCDirEntry::setComment( const string &comment ) {
213  file_comment = comment ;
214  file_comment_len = file_comment.size() ;
215 }
216 
217 
218 string ZipCDirEntry::toString() const {
219  OutputStringStream sout ;
220  sout << filename << " (" << uncompress_size << " bytes, " ;
221  sout << compress_size << " bytes compressed)" ;
222  return sout.str() ;
223 }
224 
225 
226 int ZipCDirEntry::getCDirHeaderSize() const {
227  return 46 + filename.size() + extra_field.size() + file_comment.size() ;
228 }
229 
230 
232  return new ZipCDirEntry( *this ) ;
233 }
234 
235 
236 //
237 // EndOfCentralDirectory methods
238 //
239 
240 const uint32 EndOfCentralDirectory::signature = 0x06054b50 ;
241 
242 bool EndOfCentralDirectory::read( vector<unsigned char> &buf, int pos ) {
243  if ( ( buf.size() - pos < sizeof( uint32 ) ) ||
244  ( ! checkSignature( &( buf[ pos ] ) ) ) )
245  return false ;
246 
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 ;
258 
259  return true ; // Dummy
260 }
261 
262 bool EndOfCentralDirectory::checkSignature ( unsigned char *buf ) const {
263 // cerr << "potential header: " << ztohl( buf ) << endl ;
264  return checkSignature( ztohl( buf ) ) ;
265 }
266 
267 
268 
269 } // namespace
270 
271 
272 
278 /*
279  Zipios++ - a small C++ library that provides easy access to .zip files.
280  Copyright (C) 2000 Thomas Søndergaard
281 
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.
286 
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.
291 
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
295 */