Back to home page

EIC code displayed by LXR

 
 

    


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

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_XRDZIPARCHIVE_HH_
0026 #define SRC_XRDZIP_XRDZIPARCHIVE_HH_
0027 
0028 #include "XrdCl/XrdClFile.hh"
0029 #include "XrdCl/XrdClResponseJob.hh"
0030 #include "XrdCl/XrdClJobManager.hh"
0031 #include "XrdCl/XrdClDefaultEnv.hh"
0032 #include "XrdCl/XrdClPostMaster.hh"
0033 #include "XrdZip/XrdZipEOCD.hh"
0034 #include "XrdZip/XrdZipCDFH.hh"
0035 #include "XrdZip/XrdZipZIP64EOCD.hh"
0036 #include "XrdZip/XrdZipLFH.hh"
0037 #include "XrdCl/XrdClZipCache.hh"
0038 
0039 #include <memory>
0040 #include <unordered_map>
0041 
0042 //-----------------------------------------------------------------------------
0043 // Forward declaration needed for friendship
0044 //-----------------------------------------------------------------------------
0045 namespace XrdEc{ class StrmWriter; class Reader; template<bool> class OpenOnlyImpl; };
0046 class MicroTest;
0047 class XrdEcTests;
0048 
0049 namespace XrdCl
0050 {
0051   using namespace XrdZip;
0052 
0053   //---------------------------------------------------------------------------
0054   // ZipArchive provides following functionalities:
0055   // - parsing of existing ZIP archive
0056   // - reading data from existing ZIP archive
0057   // - appending data to existing ZIP archive
0058   // - querying stat info and checksum for given file in ZIP archive
0059   //---------------------------------------------------------------------------
0060   class ZipArchive
0061   {
0062     friend class XrdEc::StrmWriter;
0063     friend class XrdEc::Reader;
0064     template<bool>
0065     friend class XrdEc::OpenOnlyImpl;
0066     friend class ::MicroTest;
0067     friend class ::XrdEcTests;
0068 
0069     template<typename RSP>
0070     friend XRootDStatus ReadFromImpl( ZipArchive&, const std::string&, uint64_t, uint32_t, void*, ResponseHandler*, uint16_t );
0071 
0072     public:
0073       //-----------------------------------------------------------------------
0074       //! Constructor
0075       //-----------------------------------------------------------------------
0076       ZipArchive( bool enablePlugIns = true );
0077 
0078       //-----------------------------------------------------------------------
0079       //! Destructor
0080       //-----------------------------------------------------------------------
0081       virtual ~ZipArchive();
0082 
0083       //-----------------------------------------------------------------------
0084       //! Open ZIP Archive (and parse the Central Directory)
0085       //!
0086       //! @param url     : the URL of the ZIP archive
0087       //! @param flags   : open flags to be used when openning the file
0088       //! @param handler : user callback
0089       //! @param timeout : operation timeout
0090       //! @return        : the status of the operation
0091       //-----------------------------------------------------------------------
0092       XRootDStatus OpenArchive( const std::string  &url,
0093                                 OpenFlags::Flags    flags,
0094                                 ResponseHandler    *handler,
0095                                 uint16_t            timeout = 0 );
0096 
0097       //-----------------------------------------------------------------------
0098       //! Open a file within the ZIP Archive
0099       //!
0100       //! @param fn    : file name to be opened
0101       //! @param flags : open flags (either 'Read' or 'New | Write')
0102       //! @param size  : file size (to be included in the LFH)
0103       //! @param crc32 : file crc32 (to be included in the LFH)
0104       //! @return        : the status of the operation
0105       //-----------------------------------------------------------------------
0106       XRootDStatus OpenFile( const std::string  &fn,
0107                              OpenFlags::Flags    flags = OpenFlags::None,
0108                              uint64_t            size  = 0,
0109                              uint32_t            crc32 = 0 );
0110 
0111       //-----------------------------------------------------------------------
0112       //! Read data from an open file
0113       //!
0114       //! @param offset  : offset within the file to read at
0115       //! @param size    : number of bytes to be read
0116       //! @param buffer  : the buffer for the data
0117       //! @param handler : user callback
0118       //! @param timeout : operation timeout
0119       //! @return        : the status of the operation
0120       //-----------------------------------------------------------------------
0121       inline
0122       XRootDStatus Read( uint64_t         offset,
0123                          uint32_t         size,
0124                          void            *buffer,
0125                          ResponseHandler *handler,
0126                          uint16_t         timeout = 0 )
0127       {
0128         if( openfn.empty() ) return XRootDStatus( stError, errInvalidOp );
0129         return ReadFrom( openfn, offset, size, buffer, handler, timeout );
0130       }
0131 
0132       //-----------------------------------------------------------------------
0133       //! PgRead data from an open file
0134       //!
0135       //! @param offset  : offset within the file to read at
0136       //! @param size    : number of bytes to be read
0137       //! @param buffer  : the buffer for the data
0138       //! @param handler : user callback
0139       //! @param timeout : operation timeout
0140       //! @return        : the status of the operation
0141       //-----------------------------------------------------------------------
0142       inline
0143       XRootDStatus PgRead( uint64_t         offset,
0144                            uint32_t         size,
0145                            void            *buffer,
0146                            ResponseHandler *handler,
0147                            uint16_t         timeout = 0 )
0148       {
0149         if( openfn.empty() ) return XRootDStatus( stError, errInvalidOp );
0150         return PgReadFrom( openfn, offset, size, buffer, handler, timeout );
0151       }
0152 
0153       //-----------------------------------------------------------------------
0154       //! Read data from a given file
0155       //!
0156       //! @param fn      : the name of the file from which we are going to read
0157       //! @param offset  : offset within the file to read at
0158       //! @param size    : number of bytes to be read
0159       //! @param buffer  : the buffer for the data
0160       //! @param handler : user callback
0161       //! @param timeout : operation timeout
0162       //! @return        : the status of the operation
0163       //-----------------------------------------------------------------------
0164       XRootDStatus ReadFrom( const std::string &fn,
0165                              uint64_t           offset,
0166                              uint32_t           size,
0167                              void              *buffer,
0168                              ResponseHandler   *handler,
0169                              uint16_t           timeout = 0 );
0170 
0171       //-----------------------------------------------------------------------
0172       //! PgRead data from a given file
0173       //!
0174       //! @param fn      : the name of the file from which we are going to read
0175       //! @param offset  : offset within the file to read at
0176       //! @param size    : number of bytes to be read
0177       //! @param buffer  : the buffer for the data
0178       //! @param handler : user callback
0179       //! @param timeout : operation timeout
0180       //! @return        : the status of the operation
0181       //-----------------------------------------------------------------------
0182       XRootDStatus PgReadFrom( const std::string &fn,
0183                                uint64_t           offset,
0184                                uint32_t           size,
0185                                void              *buffer,
0186                                ResponseHandler   *handler,
0187                                uint16_t           timeout = 0 );
0188 
0189       //-----------------------------------------------------------------------
0190       //! Append data to a new file
0191       //!
0192       //! @param size    : number of bytes to be appended
0193       //! @param buffer  : the buffer with the data to be appended
0194       //! @param handler : user callback
0195       //! @param timeout : operation timeout
0196       //! @return        : the status of the operation
0197       //-----------------------------------------------------------------------
0198       inline XRootDStatus Write( uint32_t          size,
0199                                  const void       *buffer,
0200                                  ResponseHandler  *handler,
0201                                  uint16_t          timeout = 0 )
0202       {
0203         if( openstage != Done || openfn.empty() )
0204           return XRootDStatus( stError, errInvalidOp, 0, "Archive not opened." );
0205 
0206         return WriteImpl( size, buffer, handler, timeout );
0207       }
0208 
0209       //-----------------------------------------------------------------------
0210       //! Update the metadata of the currently open file
0211       //!
0212       //! @param crc32   : the crc32 checksum
0213       //! @return        : the status of the operation
0214       //-----------------------------------------------------------------------
0215       XRootDStatus UpdateMetadata( uint32_t crc32 );
0216 
0217       //-----------------------------------------------------------------------
0218       //! Create a new file in the ZIP archive and append the data
0219       //!
0220       //! @param fn      : the name of the new file to be created
0221       //! @param crc32   : the crc32 of the file
0222       //! @param size    : the size of the file
0223       //! @param buffer  : the buffer with the data
0224       //! @param handler : user callback
0225       //! @param timeout : operation timeout
0226       //! @return        : the status of the operation
0227       //-----------------------------------------------------------------------
0228       XRootDStatus AppendFile( const std::string &fn,
0229                                uint32_t           crc32,
0230                                uint32_t           size,
0231                                const void        *buffer,
0232                                ResponseHandler   *handler,
0233                                uint16_t           timeout = 0 );
0234 
0235       //-----------------------------------------------------------------------
0236       //! Get stat info for given file
0237       //!
0238       //! @param fn   : the name of the file
0239       //! @param info : output parameter
0240       //! @return     : the status of the operation
0241       //-----------------------------------------------------------------------
0242       inline XRootDStatus Stat( const std::string &fn, StatInfo *&info )
0243       { // make sure archive has been opened and CD has been parsed
0244         if( openstage != Done )
0245           return XRootDStatus( stError, errInvalidOp );
0246         // make sure the file is part of the archive
0247         auto cditr = cdmap.find( fn );
0248         if( cditr == cdmap.end() )
0249           return XRootDStatus( stError, errNotFound );
0250         // create the result
0251         info = make_stat( fn );
0252         if (info) 
0253           return XRootDStatus();
0254         else // have difficult to access the openned archive.
0255           return XRootDStatus( stError, errNotFound );
0256       }
0257 
0258       //-----------------------------------------------------------------------
0259       //! Get stat info for an open file
0260       //!
0261       //! @param info : output parameter
0262       //! @return     : the status of the operation
0263       //-----------------------------------------------------------------------
0264       inline XRootDStatus Stat( StatInfo *&info )
0265       {
0266         if( openfn.empty() )
0267           return XRootDStatus( stError, errInvalidOp );
0268         return Stat( openfn, info );
0269       }
0270 
0271       //-----------------------------------------------------------------------
0272       //! Get crc32 for a given file
0273       //!
0274       //! @param fn    : file name
0275       //! @param cksum : output parameter
0276       //! @return      : the status of the operation
0277       //-----------------------------------------------------------------------
0278       inline XRootDStatus GetCRC32( const std::string &fn, uint32_t &cksum )
0279       { // make sure archive has been opened and CD has been parsed
0280         if( openstage != Done )
0281           return XRootDStatus( stError, errInvalidOp );
0282         // make sure the file is part of the archive
0283         auto cditr = cdmap.find( fn );
0284         if( cditr == cdmap.end() )
0285           return XRootDStatus( stError, errNotFound );
0286         cksum = cdvec[cditr->second]->ZCRC32;
0287         return XRootDStatus();
0288       }
0289 
0290       inline XRootDStatus GetOffset( const std::string &fn, uint64_t &offset){
0291           if( openstage != XrdCl::ZipArchive::Done || !archive.IsOpen() )
0292                     return XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errInvalidOp );
0293 
0294                   auto cditr = cdmap.find( fn );
0295                   if( cditr == cdmap.end() )
0296                     return XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errNotFound,
0297                             XrdCl::errNotFound, "File not found." );
0298 
0299                   XrdCl::CDFH *cdfh = cdvec[cditr->second].get();
0300 
0301                   // check if the file is compressed, for now we only support uncompressed and inflate/deflate compression
0302                   if( cdfh->compressionMethod != 0 && cdfh->compressionMethod != Z_DEFLATED )
0303                     return XrdCl::XRootDStatus( XrdCl::stError, XrdCl::errNotSupported,
0304                                          0, "The compression algorithm is not supported!" );
0305 
0306                   // Now the problem is that at the beginning of our
0307                   // file there is the Local-file-header, which size
0308                   // is not known because of the variable size 'extra'
0309                   // field, so we need to know the offset of the next
0310                   // record and shift it by the file size.
0311                   // The next record is either the next LFH (next file)
0312                   // or the start of the Central-directory.
0313                   uint64_t cdOffset = zip64eocd ? zip64eocd->cdOffset : eocd->cdOffset;
0314                   uint64_t nextRecordOffset = ( cditr->second + 1 < cdvec.size() ) ?
0315                           XrdCl::CDFH::GetOffset( *cdvec[cditr->second + 1] ) : cdOffset;
0316                   uint64_t filesize = cdfh->compressedSize;
0317                   if( filesize == std::numeric_limits<uint32_t>::max() && cdfh->extra )
0318                     filesize = cdfh->extra->compressedSize;
0319                   uint16_t descsize = cdfh->HasDataDescriptor() ?
0320                           XrdCl::DataDescriptor::GetSize( cdfh->IsZIP64() ) : 0;
0321                   offset  = nextRecordOffset - filesize - descsize;
0322                   return XrdCl::XRootDStatus();
0323       }
0324 
0325       //-----------------------------------------------------------------------
0326       //! Create the central directory at the end of ZIP archive and close it
0327       //
0328       //! @param handler : user callback
0329       //! @param timeout : operation timeout
0330       //! @return        : the status of the operation
0331       //-----------------------------------------------------------------------
0332       XRootDStatus CloseArchive( ResponseHandler *handler,
0333                                  uint16_t         timeout = 0 );
0334 
0335       //-----------------------------------------------------------------------
0336       //! Close an open file within the ZIP archive
0337       //! @return : the status of the operation
0338       //-----------------------------------------------------------------------
0339       inline XRootDStatus CloseFile()
0340       {
0341         if( openstage != Done || openfn.empty() )
0342           return XRootDStatus( stError, errInvalidOp,
0343                                0, "Archive not opened." );
0344         openfn.clear();
0345         lfh.reset();
0346         return XRootDStatus();
0347       }
0348 
0349       //-----------------------------------------------------------------------
0350       //! List files in the ZIP archive
0351       //! @return : the status of the operation
0352       //-----------------------------------------------------------------------
0353       XRootDStatus List( DirectoryList *&list );
0354 
0355       //-----------------------------------------------------------------------
0356       //! @return : true if ZIP archive has been successfully opened
0357       //-----------------------------------------------------------------------
0358       inline bool IsOpen()
0359       {
0360         return openstage == Done;
0361       }
0362 
0363       //------------------------------------------------------------------------
0364       //! Check if the underlying file is using an encrypted connection
0365       //------------------------------------------------------------------------
0366       inline bool IsSecure()
0367       {
0368         return archive.IsSecure();
0369       }
0370 
0371       //-----------------------------------------------------------------------
0372       //! Set property on the underlying File object
0373       //-----------------------------------------------------------------------
0374       inline bool SetProperty( const std::string &name, const std::string &value )
0375       {
0376         return archive.SetProperty( name, value );
0377       }
0378 
0379       //-----------------------------------------------------------------------
0380       //! Get property on the underlying File object
0381       //-----------------------------------------------------------------------
0382       inline bool GetProperty( const std::string &name, std::string &value )
0383       {
0384         return archive.GetProperty( name, value );
0385       }
0386 
0387       //-----------------------------------------------------------------------
0388       //! Get the underlying File object
0389       //-----------------------------------------------------------------------
0390       inline File& GetFile()
0391       {
0392         return archive;
0393       }
0394 
0395     private:
0396 
0397       //-----------------------------------------------------------------------
0398       //! Append data to a new file, implementation
0399       //!
0400       //! @param size    : number of bytes to be appended
0401       //! @param buffer  : the buffer with the data to be appended
0402       //! @param handler : user callback
0403       //! @param timeout : operation timeout
0404       //! @return        : the status of the operation
0405       //-----------------------------------------------------------------------
0406       XRootDStatus WriteImpl( uint32_t               size,
0407                               const void            *buffer,
0408                               ResponseHandler       *handler,
0409                               uint16_t               timeout );
0410 
0411       //-----------------------------------------------------------------------
0412       //! Open the ZIP archive in read-only mode without parsing the central
0413       //! directory.
0414       //!
0415       //! @param url     : url of the ZIP archive
0416       //! @param handler : user callback
0417       //! @param timeout : operation timeout
0418       //! @return        : operation status
0419       //-----------------------------------------------------------------------
0420       XRootDStatus OpenOnly( const std::string  &url,
0421                              bool                update,
0422                              ResponseHandler    *handler,
0423                              uint16_t            timeout = 0 );
0424 
0425       //-----------------------------------------------------------------------
0426       //! Get a buffer with central directory of the ZIP archive
0427       //!
0428       //! @return : buffer with central directory
0429       //-----------------------------------------------------------------------
0430       buffer_t GetCD();
0431 
0432       //-----------------------------------------------------------------------
0433       //! Set central directory for the ZIP archive
0434       //!
0435       //! @param buffer : a buffer with the central directory to be set
0436       //-----------------------------------------------------------------------
0437       void SetCD( const buffer_t &buffer );
0438 
0439       //-----------------------------------------------------------------------
0440       //! Package a response into AnyObject (erase the type)
0441       //!
0442       //! @param rsp : the response to be packaged
0443       //! @return    : AnyObject with the response
0444       //-----------------------------------------------------------------------
0445       template<typename Response>
0446       inline static AnyObject* PkgRsp( Response *rsp )
0447       {
0448         if( !rsp ) return nullptr;
0449         AnyObject *pkg = new AnyObject();
0450         pkg->Set( rsp );
0451         return pkg;
0452       }
0453 
0454       //-----------------------------------------------------------------------
0455       //! Free status and response
0456       //-----------------------------------------------------------------------
0457       template<typename Response>
0458       inline static void Free( XRootDStatus *st, Response *rsp )
0459       {
0460         delete st;
0461         delete rsp;
0462       }
0463 
0464       //-----------------------------------------------------------------------
0465       //! Schedule a user callback to be executed in the thread-pool with given
0466       //! status and response.
0467       //!
0468       //! @param handler : user callback to be scheduled
0469       //! @param st      : status to be passed to the callback
0470       //! @param rsp     : response to be passed to the callback
0471       //-----------------------------------------------------------------------
0472       template<typename Response>
0473       inline static void Schedule( ResponseHandler *handler, XRootDStatus *st, Response *rsp = nullptr )
0474       {
0475         if( !handler ) return Free( st, rsp );
0476         ResponseJob *job = new ResponseJob( handler, st, PkgRsp( rsp ), 0 );
0477         DefaultEnv::GetPostMaster()->GetJobManager()->QueueJob( job );
0478       }
0479 
0480       //-----------------------------------------------------------------------
0481       //! Create a StatInfo object from ZIP archive stat info and the file size.
0482       //!
0483       //! @param starch : ZIP archive stat info
0484       //! @param size   : file size
0485       //! @return       : StatInfo object
0486       //-----------------------------------------------------------------------
0487       inline static StatInfo* make_stat( const StatInfo &starch, uint64_t size )
0488       {
0489         StatInfo *info = new StatInfo( starch );
0490         uint32_t flags = info->GetFlags();
0491         info->SetFlags( flags & ( ~StatInfo::IsWritable ) ); // make sure it is not listed as writable
0492         info->SetSize( size );
0493         return info;
0494       }
0495 
0496       //-----------------------------------------------------------------------
0497       //! Create a StatInfo object for a given file within the ZIP archive.
0498       //!
0499       //! @param fn : file name
0500       //! @return   : StatInfo object for the given file
0501       //-----------------------------------------------------------------------
0502       inline StatInfo* make_stat( const std::string &fn )
0503       {
0504         StatInfo *infoptr = 0;
0505         XRootDStatus st = archive.Stat( false, infoptr );
0506         if (!st.IsOK()) return nullptr;
0507         std::unique_ptr<StatInfo> stinfo( infoptr );
0508         auto itr = cdmap.find( fn );
0509         if( itr == cdmap.end() ) return nullptr;
0510         size_t index = itr->second;
0511         uint64_t uncompressedSize = cdvec[index]->uncompressedSize;
0512         if( cdvec[index]->extra && uncompressedSize == std::numeric_limits<uint32_t>::max() )
0513           uncompressedSize = cdvec[index]->extra->uncompressedSize;
0514         return make_stat( *stinfo, uncompressedSize );
0515       }
0516 
0517       //-----------------------------------------------------------------------
0518       //! Allocate new XRootDStatus object
0519       //-----------------------------------------------------------------------
0520       inline static XRootDStatus* make_status( const XRootDStatus &status = XRootDStatus() )
0521       {
0522         return new XRootDStatus( status );
0523       }
0524 
0525       //-----------------------------------------------------------------------
0526       //! Clear internal ZipArchive objects
0527       //-----------------------------------------------------------------------
0528       inline void Clear()
0529       {
0530         buffer.reset();
0531         eocd.reset();
0532         cdvec.clear();
0533         cdmap.clear();
0534         zip64eocd.reset();
0535         openstage = None;
0536       }
0537 
0538       //-----------------------------------------------------------------------
0539       //! Stages of opening and parsing a ZIP archive
0540       //-----------------------------------------------------------------------
0541       enum OpenStages
0542       {
0543         None = 0,          //< opening/parsing not started
0544         HaveEocdBlk,       //< we have the End of Central Directory record
0545         HaveZip64EocdlBlk, //< we have the ZIP64 End of Central Directory locator record
0546         HaveZip64EocdBlk,  //< we have the ZIP64 End of Central Directory record
0547         HaveCdRecords,     //< we have Central Directory records
0548         Done,              //< we are done parsing the Central Directory
0549         Error,             //< opening/parsing failed
0550         NotParsed          //< the ZIP archive has been opened but Central Directory is not parsed
0551       };
0552 
0553       //-----------------------------------------------------------------------
0554       //! LFH of a newly appended file (in case it needs to be overwritten)
0555       //-----------------------------------------------------------------------
0556       struct NewFile
0557       {
0558         NewFile( uint64_t offset, std::unique_ptr<LFH> lfh ) : offset( offset ),
0559                                                                lfh( std::move( lfh ) ),
0560                                                                overwrt( false )
0561         {
0562         }
0563 
0564         NewFile( NewFile && nf ) : offset( nf.offset ),
0565                                    lfh( std::move( nf.lfh ) ),
0566                                    overwrt( nf.overwrt )
0567         {
0568         }
0569 
0570         uint64_t             offset;  // the offset of the LFH of the file
0571         std::unique_ptr<LFH> lfh;     // LFH of the file
0572         bool                 overwrt; // if true the LFH needs to be overwritten on close
0573       };
0574 
0575       //-----------------------------------------------------------------------
0576       //! Type that maps file name to its cache
0577       //-----------------------------------------------------------------------
0578       typedef std::unordered_map<std::string, ZipCache> zipcache_t;
0579       typedef std::unordered_map<std::string, NewFile>  new_files_t;
0580 
0581       File                        archive;   //> File object for handling the ZIP archive
0582       uint64_t                    archsize;  //> size of the ZIP archive
0583       bool                        cdexists;  //> true if Central Directory exists, false otherwise
0584       bool                        updated;   //> true if the ZIP archive has been updated, false otherwise
0585       std::unique_ptr<char[]>     buffer;    //> buffer for keeping the data to be parsed or raw data
0586       std::unique_ptr<EOCD>       eocd;      //> End of Central Directory record
0587       cdvec_t                     cdvec;     //> vector of Central Directory File Headers
0588       cdmap_t                     cdmap;     //> mapping of file name to CDFH index
0589       uint64_t                    cdoff;     //> Central Directory offset
0590       uint32_t                    orgcdsz;   //> original CD size
0591       uint32_t                    orgcdcnt;  //> original number CDFH records
0592       buffer_t                    orgcdbuf;  //> buffer with the original CDFH records
0593       std::unique_ptr<ZIP64_EOCD> zip64eocd; //> ZIP64 End of Central Directory record
0594       OpenStages                  openstage; //> stage of opening / parsing a ZIP archive
0595       std::string                 openfn;    //> file name of opened file
0596       zipcache_t                  zipcache;  //> cache for inflating compressed data
0597       std::unique_ptr<LFH>        lfh;       //> Local File Header record for the newly appended file
0598       bool                        ckpinit;   //> a flag indicating whether a checkpoint has been initialized
0599       new_files_t                 newfiles;  //> all newly appended files
0600   };
0601 
0602 } /* namespace XrdZip */
0603 
0604 #endif /* SRC_XRDZIP_XRDZIPARCHIVE_HH_ */