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_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   // A data structure representing the End of Central Directory record
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     //! Constructor from buffer
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     //! Constructor from last LFH + CDFH
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     //! Serialize the object into a buffer
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     //! Convert the EOCD into a string for logging purposes
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;        //< number of this disk
0139     uint16_t    nbDiskCd;      //< number of the disk with the start of the central directory
0140     uint16_t    nbCdRecD;      //< total number of entries in the central directory on this disk
0141     uint16_t    nbCdRec;       //< total number of entries in the central directory
0142     uint32_t    cdSize;        //< size of the central directory
0143     uint32_t    cdOffset;      //< offset of start of central directory
0144     uint16_t    commentLength; //< comment length
0145     std::string comment;       //< user comment
0146     uint16_t    eocdSize;      //< size of the record
0147     bool        useZip64;      //< true if ZIP64 format is to be used, false otherwise
0148 
0149     //-------------------------------------------------------------------------
0150     // the End of Central Directory signature
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 /* SRC_XRDZIP_XRDZIPEOCD_HH_ */