ziphead.cpp

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

Generated on Wed Nov 23 19:01:12 2011 for FreeCAD by  doxygen 1.6.1