]> git.donarmstrong.com Git - flightcrew.git/blob - src/zipios/src/ziphead.cpp
Imported Upstream version 0.7.2+dfsg
[flightcrew.git] / src / zipios / src / ziphead.cpp
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
66 uint32 ZipLocalEntry::getCompressedSize() const {
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
86 string ZipLocalEntry::getFileName() const {
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
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?)
106 }
107
108 bool ZipLocalEntry::isValid() const {
109   return _valid ;
110 }
111
112 bool ZipLocalEntry::isDirectory() const {
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 = static_cast< uint16 >( 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 = static_cast< uint16 >( 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 static_cast< int >( 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
178 FileEntry *ZipLocalEntry::clone() const {
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 = static_cast< uint16 >( 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 static_cast< int >( 46 + filename.size() + extra_field.size() + file_comment.size() ) ;
228 }
229
230
231 FileEntry *ZipCDirEntry::clone() const {
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
273 /** \file
274     Implementation of routines for reading the central directory and 
275     local headers of a zip archive. 
276 */
277
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 */