Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:38

0001 //------------------------------------------------------------------------------
0002 // Copyright (c) 2011-2014 by European Organization for Nuclear Research (CERN)
0003 // Author: Michal Simon <michal.simon@cern.ch>
0004 //------------------------------------------------------------------------------
0005 // This file is part of the XRootD software suite.
0006 //
0007 // XRootD is free software: you can redistribute it and/or modify
0008 // it under the terms of the GNU Lesser General Public License as published by
0009 // the Free Software Foundation, either version 3 of the License, or
0010 // (at your option) any later version.
0011 //
0012 // XRootD is distributed in the hope that it will be useful,
0013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015 // GNU General Public License for more details.
0016 //
0017 // You should have received a copy of the GNU Lesser General Public License
0018 // along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
0019 //
0020 // In applying this licence, CERN does not waive the privileges and immunities
0021 // granted to it by virtue of its status as an Intergovernmental Organization
0022 // or submit itself to any jurisdiction.
0023 //------------------------------------------------------------------------------
0024 
0025 #ifndef SRC_XRDZIP_XRDZIPLFH_HH_
0026 #define SRC_XRDZIP_XRDZIPLFH_HH_
0027 
0028 #include "XrdZip/XrdZipUtils.hh"
0029 #include "XrdZip/XrdZipExtra.hh"
0030 
0031 #include <string>
0032 #include <memory>
0033 #include <algorithm>
0034 #include <iterator>
0035 
0036 namespace XrdZip
0037 {
0038   //---------------------------------------------------------------------------
0039   //! A data structure representing ZIP Local File Header
0040   //---------------------------------------------------------------------------
0041   struct LFH
0042   {
0043     //-------------------------------------------------------------------------
0044     //! Convenience function for initializing compressed/uncompressed size
0045     //-------------------------------------------------------------------------
0046     inline static uint32_t initSize( const off_t &fileSize )
0047     {
0048       return fileSize >= ovrflw<uint32_t>::value ?
0049              ovrflw<uint32_t>::value : fileSize;
0050     }
0051 
0052     //-------------------------------------------------------------------------
0053     //! Constructor
0054     //-------------------------------------------------------------------------
0055     LFH( const std::string &filename, uint32_t crc, off_t fileSize, time_t time ) :
0056       generalBitFlag( 0 ), compressionMethod( 0 ), timestmp( time ), ZCRC32( crc ),
0057       compressedSize( initSize( fileSize ) ), uncompressedSize( initSize( fileSize ) ),
0058       filenameLength( filename.size() ), filename( filename ), extra( new Extra( fileSize ) )
0059     {
0060       extraLength = extra->totalSize;
0061       if ( extraLength == 0 )
0062         minZipVersion = 10;
0063       else
0064         minZipVersion = 45;
0065       lfhSize = lfhBaseSize + filenameLength + extraLength;
0066     }
0067 
0068     //-------------------------------------------------------------------------
0069     //! Constructor from buffer
0070     //-------------------------------------------------------------------------
0071     LFH( const char *buffer, const uint64_t bufferSize = 0 )
0072     {
0073         if(bufferSize > 0 && bufferSize < (uint64_t)lfhBaseSize)
0074             throw bad_data();
0075       // check if the buffer contains a LFH record
0076       uint32_t signature = 0;
0077       from_buffer( signature, buffer );
0078       if( signature != lfhSign ) throw bad_data();
0079       // parse LFH filds
0080       from_buffer( minZipVersion, buffer );
0081       from_buffer( generalBitFlag, buffer );
0082       from_buffer( compressionMethod, buffer );
0083       from_buffer( timestmp.time, buffer );
0084       from_buffer( timestmp.date, buffer );
0085       from_buffer( ZCRC32, buffer );
0086       from_buffer( compressedSize, buffer );
0087       from_buffer( uncompressedSize, buffer );
0088       from_buffer( filenameLength, buffer );
0089       from_buffer( extraLength, buffer );
0090 
0091       if(bufferSize > 0 && (uint64_t)(lfhBaseSize + filenameLength + extraLength) > bufferSize)
0092           throw bad_data();
0093       // parse the filename
0094       filename.assign( buffer, filenameLength );
0095       buffer += filenameLength;
0096       // parse the extra record
0097       if( extraLength > 0 )
0098         ParseExtra( buffer, extraLength );
0099 
0100       lfhSize = lfhBaseSize + filenameLength + extraLength;
0101     }
0102 
0103     //-------------------------------------------------------------------------
0104     //! Serialize the object into a buffer
0105     //-------------------------------------------------------------------------
0106     void Serialize( buffer_t &buffer )
0107     {
0108       copy_bytes( lfhSign, buffer );
0109       copy_bytes( minZipVersion, buffer );
0110       copy_bytes( generalBitFlag, buffer );
0111       copy_bytes( compressionMethod, buffer );
0112       copy_bytes( timestmp.time, buffer );
0113       copy_bytes( timestmp.date, buffer );
0114       copy_bytes( ZCRC32, buffer );
0115       copy_bytes( compressedSize, buffer );
0116       copy_bytes( uncompressedSize, buffer );
0117       copy_bytes( filenameLength, buffer );
0118       copy_bytes( extraLength , buffer );
0119       std::copy( filename.begin(), filename.end(), std::back_inserter( buffer ) );
0120       extra->Serialize( buffer );
0121     }
0122 
0123     //-------------------------------------------------------------------------
0124     // Parse the extensible data fields
0125     //-------------------------------------------------------------------------
0126     void ParseExtra( const char *buffer, uint16_t length)
0127     {
0128       uint8_t ovrflws = Extra::NONE;
0129       uint16_t exsize = 0;
0130 
0131       // check if compressed size is overflown
0132       if( compressedSize == ovrflw<uint32_t>::value)
0133       {
0134         ovrflws |= Extra::CPMSIZE;
0135         exsize  += sizeof( uint64_t );
0136       }
0137 
0138       // check if original size is overflown
0139       if( uncompressedSize == ovrflw<uint32_t>::value )
0140       {
0141         ovrflws |= Extra::UCMPSIZE;
0142         exsize  += sizeof( uint64_t );
0143       }
0144 
0145       // if the expected size of ZIP64 extension is 0 we
0146       // can skip parsing of 'extra'
0147       if( exsize == 0 ) return;
0148 
0149       extra.reset( new Extra() );
0150 
0151       // Parse the extra part
0152       buffer = Extra::Find( buffer, length );
0153       if( buffer )
0154         extra->FromBuffer( buffer, exsize, ovrflws );
0155     }
0156 
0157     uint16_t               minZipVersion;      //< minimum ZIP version required to read the file
0158     uint16_t               generalBitFlag;     //< flags
0159     uint16_t               compressionMethod;  //< compression method
0160     dos_timestmp           timestmp;           //< DOS time stamp
0161     uint32_t               ZCRC32;             //< crc32 value
0162     uint32_t               compressedSize;     //< compressed data size
0163     uint32_t               uncompressedSize;   //< uncompressed data size
0164     uint16_t               filenameLength;     //< file name length
0165     uint16_t               extraLength;        //< size of the ZIP64 extra field
0166     std::string            filename;           //< file name
0167     std::unique_ptr<Extra> extra;              //< the ZIP64 extra field
0168     uint16_t               lfhSize;            //< size of the Local File Header
0169 
0170     //-------------------------------------------------------------------------
0171     //! Local File Header signature
0172     //-------------------------------------------------------------------------
0173     static const uint32_t lfhSign     = 0x04034b50;
0174     static const uint16_t lfhBaseSize = 30;
0175   };
0176 }
0177 
0178 #endif /* SRC_XRDZIP_XRDZIPLFH_HH_ */