Zipios++
|
00001 00002 #include "zipios++/zipios-config.h" 00003 00004 #include "zipios++/meta-iostreams.h" 00005 #include <iterator> 00006 #include <string> 00007 #include <cassert> 00008 00009 #include "zipios_common.h" 00010 #include "zipios++/ziphead.h" 00011 #include "zipios++/zipheadio.h" 00012 #include "zipios++/zipios_defs.h" 00013 00014 #include "outputstringstream.h" 00015 00016 namespace zipios { 00017 00018 using std::ios ; 00019 00020 bool operator== ( const ZipLocalEntry &zlh, const ZipCDirEntry &ze ) { 00021 // Not all fields need to be identical. Some of the information 00022 // may be put in a data descriptor that trails the compressed 00023 // data, according to the specs (The trailing data descriptor 00024 // can contain crc_32, compress_size and uncompress_size.) 00025 00026 // Experience has shown that extra_field and extra_field_len 00027 // can differ too. 00028 00029 // cerr << "----- BEGIN -----" << endl ; 00030 // cerr << ( zlh.extract_version == ze.extract_version ) << endl ; 00031 // cerr << ( zlh.gp_bitfield == ze.gp_bitfield ) << endl ; 00032 // cerr << ( zlh.compress_method == ze.compress_method ) << endl ; 00033 // cerr << ( zlh.last_mod_ftime == ze.last_mod_ftime ) << endl ; 00034 // cerr << ( zlh.last_mod_fdate == ze.last_mod_fdate ) << endl ; 00035 00036 // cerr << ( zlh.filename_len == ze.filename_len ) << endl ; 00037 00038 // cerr << ( zlh.filename == ze.filename ) << endl ; 00039 // cerr << "----- END -----" << endl ; 00040 return ( zlh.extract_version == ze.extract_version && 00041 zlh.gp_bitfield == ze.gp_bitfield && 00042 zlh.compress_method == ze.compress_method && 00043 zlh.last_mod_ftime == ze.last_mod_ftime && 00044 zlh.last_mod_fdate == ze.last_mod_fdate && 00045 zlh.filename_len == ze.filename_len && 00046 00047 zlh.filename == ze.filename ) ; 00048 } 00049 00050 // 00051 // ZipLocalEntry methods 00052 // 00053 00054 const uint32 ZipLocalEntry::signature = 0x04034b50 ; 00055 00056 00057 00058 void ZipLocalEntry::setDefaultExtract() { 00059 extract_version = 20 ; // version number 00060 } 00061 00062 string ZipLocalEntry::getComment() const { 00063 return "" ; // No comment in a local entry 00064 } 00065 00066 uint32 ZipLocalEntry::getCompressedSize() const { 00067 return compress_size ; 00068 } 00069 00070 uint32 ZipLocalEntry::getCrc() const { 00071 return crc_32 ; 00072 } 00073 00074 vector< unsigned char > ZipLocalEntry::getExtra() const { 00075 return extra_field ; 00076 } 00077 00078 StorageMethod ZipLocalEntry::getMethod() const { 00079 return static_cast< StorageMethod >( compress_method ) ; 00080 } 00081 00082 string ZipLocalEntry::getName() const { 00083 return filename ; 00084 } 00085 00086 string ZipLocalEntry::getFileName() const { 00087 if ( isDirectory() ) 00088 return string() ; 00089 string::size_type pos ; 00090 pos = filename.find_last_of( separator ) ; 00091 if ( pos != string::npos ) { // separator found! 00092 // isDirectory() check means pos should not be last, so pos+1 is ok 00093 return filename.substr( pos + 1 ) ; 00094 } else { 00095 return filename ; 00096 } 00097 } 00098 00099 uint32 ZipLocalEntry::getSize() const { 00100 return uncompress_size ; 00101 } 00102 00103 int ZipLocalEntry::getTime() const { 00104 return ( last_mod_fdate << 16 ) + last_mod_ftime ; 00105 // FIXME: what to do with this time date thing? (not only here?) 00106 } 00107 00108 bool ZipLocalEntry::isValid() const { 00109 return _valid ; 00110 } 00111 00112 bool ZipLocalEntry::isDirectory() const { 00113 assert( filename.size() != 0 ) ; 00114 return filename[ filename.size() - 1 ] == separator ; 00115 } 00116 00117 00118 void ZipLocalEntry::setComment( const string & ) { 00119 // A local entry cannot hold a comment 00120 } 00121 00122 void ZipLocalEntry::setCompressedSize( uint32 size ) { 00123 compress_size = size ; 00124 } 00125 00126 void ZipLocalEntry::setCrc( uint32 crc ) { 00127 crc_32 = crc ; 00128 } 00129 00130 void ZipLocalEntry::setExtra( const vector< unsigned char > &extra ) { 00131 extra_field = extra ; 00132 extra_field_len = extra_field.size() ; 00133 } 00134 00135 void ZipLocalEntry::setMethod( StorageMethod method ) { 00136 compress_method = static_cast< uint16 >( method ) ; 00137 } 00138 00139 void ZipLocalEntry::setName( const string &name ) { 00140 filename = name ; 00141 filename_len = filename.size() ; 00142 } 00143 00144 void ZipLocalEntry::setSize( uint32 size ) { 00145 uncompress_size = size ; 00146 } 00147 00148 void ZipLocalEntry::setTime( int time ) { 00149 // FIXME: fix time setting here, and ind flist and elsewhere. Define the 00150 // date time semantics before mucking about - how surprising 00151 00152 // Mark Donszelmann: added these lines to make zip work for winzip 00153 last_mod_fdate = (time >> 16) & 0x0000FFFF; 00154 last_mod_ftime = time & 0x0000FFFF; 00155 } 00156 00157 string ZipLocalEntry::toString() const { 00158 OutputStringStream sout ; 00159 sout << filename << " (" << uncompress_size << " bytes, " ; 00160 sout << compress_size << " bytes compressed)" ; 00161 return sout.str() ; 00162 } 00163 00164 int ZipLocalEntry::getLocalHeaderSize() const { 00165 return 30 + filename.size() + extra_field.size() ; 00166 } 00167 00168 bool ZipLocalEntry::trailingDataDescriptor() const { 00169 // gp_bitfield bit 3 is one, if this entry uses a trailing data 00170 // descriptor to keep size, compressed size and crc-32 00171 // fields. 00172 if ( ( gp_bitfield & 4 ) == 1 ) 00173 return true ; 00174 else 00175 return false ; 00176 } 00177 00178 FileEntry *ZipLocalEntry::clone() const { 00179 return new ZipLocalEntry( *this ) ; 00180 } 00181 00182 00183 // 00184 // ZipCDirEntry methods 00185 // 00186 00187 const uint32 ZipCDirEntry::signature = 0x02014b50 ; 00188 00189 void ZipCDirEntry::setDefaultWriter() { 00190 writer_version = 0 ; 00191 #ifdef WIN32 00192 writer_version |= static_cast< uint16 >( 0 ) << 8 ; // Windows, DOS 00193 #else 00194 writer_version |= static_cast< uint16 >( 3 ) << 8 ; // Unix 00195 #endif 00196 writer_version |= 20 ; // version number 00197 } 00198 00199 string ZipCDirEntry::getComment() const { 00200 return file_comment ; 00201 } 00202 00203 uint32 ZipCDirEntry::getLocalHeaderOffset() const { 00204 return rel_offset_loc_head ; 00205 } 00206 00207 void ZipCDirEntry::setLocalHeaderOffset( uint32 offset ) { 00208 rel_offset_loc_head = offset ; 00209 } 00210 00211 00212 void ZipCDirEntry::setComment( const string &comment ) { 00213 file_comment = comment ; 00214 file_comment_len = file_comment.size() ; 00215 } 00216 00217 00218 string ZipCDirEntry::toString() const { 00219 OutputStringStream sout ; 00220 sout << filename << " (" << uncompress_size << " bytes, " ; 00221 sout << compress_size << " bytes compressed)" ; 00222 return sout.str() ; 00223 } 00224 00225 00226 int ZipCDirEntry::getCDirHeaderSize() const { 00227 return 46 + filename.size() + extra_field.size() + file_comment.size() ; 00228 } 00229 00230 00231 FileEntry *ZipCDirEntry::clone() const { 00232 return new ZipCDirEntry( *this ) ; 00233 } 00234 00235 00236 // 00237 // EndOfCentralDirectory methods 00238 // 00239 00240 const uint32 EndOfCentralDirectory::signature = 0x06054b50 ; 00241 00242 bool EndOfCentralDirectory::read( vector<unsigned char> &buf, int pos ) { 00243 if ( ( buf.size() - pos < sizeof( uint32 ) ) || 00244 ( ! checkSignature( &( buf[ pos ] ) ) ) ) 00245 return false ; 00246 00247 eocd_offset_from_end = buf.size() - pos ; 00248 pos += sizeof( uint32 ) ; 00249 disk_num = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ; 00250 cdir_disk_num = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ; 00251 cdir_entries = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ; 00252 cdir_tot_entries = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ; 00253 cdir_size = ztohl( &( buf[ pos ] ) ) ; pos += sizeof( uint32 ) ; 00254 cdir_offset = ztohl( &( buf[ pos ] ) ) ; pos += sizeof( uint32 ) ; 00255 zip_comment_len = ztohs( &( buf[ pos ] ) ) ; pos += sizeof( uint16 ) ; 00256 // cerr << "Zip comment length = " << zip_comment_len << endl ; 00257 // cerr << "Length of remaining file = " << buf.size() - pos << endl ; 00258 00259 return true ; // Dummy 00260 } 00261 00262 bool EndOfCentralDirectory::checkSignature ( unsigned char *buf ) const { 00263 // cerr << "potential header: " << ztohl( buf ) << endl ; 00264 return checkSignature( ztohl( buf ) ) ; 00265 } 00266 00267 00268 00269 } // namespace 00270 00271 00272 00278 /* 00279 Zipios++ - a small C++ library that provides easy access to .zip files. 00280 Copyright (C) 2000 Thomas Søndergaard 00281 00282 This library is free software; you can redistribute it and/or 00283 modify it under the terms of the GNU Lesser General Public 00284 License as published by the Free Software Foundation; either 00285 version 2 of the License, or (at your option) any later version. 00286 00287 This library is distributed in the hope that it will be useful, 00288 but WITHOUT ANY WARRANTY; without even the implied warranty of 00289 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00290 Lesser General Public License for more details. 00291 00292 You should have received a copy of the GNU Lesser General Public 00293 License along with this library; if not, write to the Free Software 00294 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00295 */