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_XRDZIPEOCD_HH_
0026 #define SRC_XRDZIP_XRDZIPEOCD_HH_
0027
0028 #include "XrdZip/XrdZipUtils.hh"
0029 #include "XrdZip/XrdZipLFH.hh"
0030 #include "XrdZip/XrdZipCDFH.hh"
0031 #include <string>
0032 #include <sstream>
0033
0034 namespace XrdZip
0035 {
0036
0037
0038
0039 struct EOCD
0040 {
0041 inline static const char* Find( const char *buffer, uint64_t size )
0042 {
0043 for( ssize_t offset = size - eocdBaseSize; offset >= 0; --offset )
0044 {
0045 uint32_t signature = to<uint32_t>( buffer + offset );
0046 if( signature == eocdSign ) return buffer + offset;
0047 }
0048 return 0;
0049 }
0050
0051
0052
0053
0054 EOCD( const char *buffer, uint32_t maxSize = 0 )
0055 {
0056 nbDisk = to<uint16_t>(buffer + 4);
0057 nbDiskCd = to<uint16_t>(buffer + 6);
0058 nbCdRecD = to<uint16_t>(buffer + 8);
0059 nbCdRec = to<uint16_t>(buffer + 10);
0060 cdSize = to<uint32_t>(buffer + 12);
0061 cdOffset = to<uint32_t>(buffer + 16);
0062 commentLength = to<uint16_t>(buffer + 20);
0063 if(maxSize > 0 && (uint32_t)(eocdBaseSize + commentLength) > maxSize)
0064 throw bad_data();
0065 comment = std::string( buffer + 22, commentLength );
0066
0067 eocdSize = eocdBaseSize + commentLength;
0068 useZip64= false;
0069 }
0070
0071
0072
0073
0074 EOCD( uint64_t cdoff, uint32_t cdcnt, uint32_t cdsize ):
0075 nbDisk( 0 ),
0076 nbDiskCd( 0 ),
0077 commentLength( 0 ),
0078 useZip64( false )
0079 {
0080 if( cdcnt >= ovrflw<uint16_t>::value )
0081 {
0082 nbCdRecD = ovrflw<uint16_t>::value;
0083 nbCdRec = ovrflw<uint16_t>::value;
0084 }
0085 else
0086 {
0087 nbCdRecD = cdcnt;
0088 nbCdRec = cdcnt;
0089 }
0090
0091 cdSize = cdsize;
0092
0093 if( cdoff >= ovrflw<uint32_t>::value )
0094 {
0095 cdOffset = ovrflw<uint32_t>::value;
0096 useZip64 = true;
0097 }
0098 else
0099 cdOffset = cdoff;
0100
0101 eocdSize = eocdBaseSize + commentLength;
0102 }
0103
0104
0105
0106
0107 void Serialize( buffer_t &buffer )
0108 {
0109 copy_bytes( eocdSign, buffer );
0110 copy_bytes( nbDisk, buffer );
0111 copy_bytes( nbDiskCd, buffer );
0112 copy_bytes( nbCdRecD, buffer );
0113 copy_bytes( nbCdRec, buffer );
0114 copy_bytes( cdSize, buffer );
0115 copy_bytes( cdOffset, buffer );
0116 copy_bytes( commentLength, buffer );
0117
0118 std::copy( comment.begin(), comment.end(), std::back_inserter( buffer ) );
0119 }
0120
0121
0122
0123
0124 std::string ToString()
0125 {
0126 std::stringstream ss;
0127 ss << "{nbDisk=" << nbDisk;
0128 ss << ";nbDiskCd=" << nbDiskCd;
0129 ss << ";nbCdRecD=" << nbCdRecD;
0130 ss << ";nbCdRec=" << nbCdRec;
0131 ss << ";cdSize" << cdSize;
0132 ss << ";cdOffset=" << cdOffset;
0133 ss << ";commentLength=" << commentLength;
0134 ss << ";comment=" << comment << '}';
0135 return ss.str();
0136 }
0137
0138 uint16_t nbDisk;
0139 uint16_t nbDiskCd;
0140 uint16_t nbCdRecD;
0141 uint16_t nbCdRec;
0142 uint32_t cdSize;
0143 uint32_t cdOffset;
0144 uint16_t commentLength;
0145 std::string comment;
0146 uint16_t eocdSize;
0147 bool useZip64;
0148
0149
0150
0151
0152 static const uint32_t eocdSign = 0x06054b50;
0153 static const uint16_t eocdBaseSize = 22;
0154 static const uint16_t maxCommentLength = 65535;
0155 };
0156
0157 }
0158
0159 #endif