Zipios++

ziphead.cpp

Go to the documentation of this file.
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 */