File indexing completed on 2025-01-18 10:15:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
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
0040
0041 struct LFH
0042 {
0043
0044
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
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
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
0076 uint32_t signature = 0;
0077 from_buffer( signature, buffer );
0078 if( signature != lfhSign ) throw bad_data();
0079
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
0094 filename.assign( buffer, filenameLength );
0095 buffer += filenameLength;
0096
0097 if( extraLength > 0 )
0098 ParseExtra( buffer, extraLength );
0099
0100 lfhSize = lfhBaseSize + filenameLength + extraLength;
0101 }
0102
0103
0104
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
0125
0126 void ParseExtra( const char *buffer, uint16_t length)
0127 {
0128 uint8_t ovrflws = Extra::NONE;
0129 uint16_t exsize = 0;
0130
0131
0132 if( compressedSize == ovrflw<uint32_t>::value)
0133 {
0134 ovrflws |= Extra::CPMSIZE;
0135 exsize += sizeof( uint64_t );
0136 }
0137
0138
0139 if( uncompressedSize == ovrflw<uint32_t>::value )
0140 {
0141 ovrflws |= Extra::UCMPSIZE;
0142 exsize += sizeof( uint64_t );
0143 }
0144
0145
0146
0147 if( exsize == 0 ) return;
0148
0149 extra.reset( new Extra() );
0150
0151
0152 buffer = Extra::Find( buffer, length );
0153 if( buffer )
0154 extra->FromBuffer( buffer, exsize, ovrflws );
0155 }
0156
0157 uint16_t minZipVersion;
0158 uint16_t generalBitFlag;
0159 uint16_t compressionMethod;
0160 dos_timestmp timestmp;
0161 uint32_t ZCRC32;
0162 uint32_t compressedSize;
0163 uint32_t uncompressedSize;
0164 uint16_t filenameLength;
0165 uint16_t extraLength;
0166 std::string filename;
0167 std::unique_ptr<Extra> extra;
0168 uint16_t lfhSize;
0169
0170
0171
0172
0173 static const uint32_t lfhSign = 0x04034b50;
0174 static const uint16_t lfhBaseSize = 30;
0175 };
0176 }
0177
0178 #endif