/* * XrdClZipOperations.hh * * Created on: 26 Nov 2020 * Author: simonm */ #ifndef SRC_XRDCL_XRDCLZIPOPERATIONS_HH_ #define SRC_XRDCL_XRDCLZIPOPERATIONS_HH_ #include "XrdCl/XrdClZipArchive.hh" #include "XrdCl/XrdClOperations.hh" #include "XrdCl/XrdClOperationHandlers.hh" #include "XrdCl/XrdClCtx.hh" namespace XrdCl { //---------------------------------------------------------------------------- //! Base class for all zip archive related operations //! //! @arg Derived : the class that derives from this template (CRTP) //! @arg HasHndl : true if operation has a handler, false otherwise //! @arg Args : operation arguments //---------------------------------------------------------------------------- template class Derived, bool HasHndl, typename Response, typename ... Arguments> class ZipOperation: public ConcreteOperation { template class, bool, typename, typename ...> friend class ZipOperation; public: //------------------------------------------------------------------------ //! Constructor //! //! @param zip : file on which the operation will be performed //! @param args : file operation arguments //------------------------------------------------------------------------ ZipOperation( Ctx zip, Arguments... args): ConcreteOperation( std::move( args )... ), zip( std::move( zip ) ) { } //------------------------------------------------------------------------ //! Move constructor from other states //! //! @arg from : state from which the object is being converted //! //! @param op : the object that is being converted //------------------------------------------------------------------------ template ZipOperation( ZipOperation && op ) : ConcreteOperation( std::move( op ) ), zip( op.zip ) { } //------------------------------------------------------------------------ //! Destructor //------------------------------------------------------------------------ virtual ~ZipOperation() { } protected: //------------------------------------------------------------------------ //! The file object itself //------------------------------------------------------------------------ Ctx zip; }; //---------------------------------------------------------------------------- //! OpenArchive operation (@see ZipOperation) //---------------------------------------------------------------------------- template class OpenArchiveImpl: public ZipOperation, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { UrlArg, FlagsArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipOpen"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { std::string &url = std::get( this->args ).Get(); OpenFlags::Flags flags = std::get( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->OpenArchive( url, flags, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating OpenArchiveImpl objects //---------------------------------------------------------------------------- inline OpenArchiveImpl OpenArchive( Ctx zip, Arg fn, Arg flags, uint16_t timeout = 0 ) { return OpenArchiveImpl( std::move( zip ), std::move( fn ), std::move( flags ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! OpenFile operation (@see ZipOperation) //---------------------------------------------------------------------------- template class OpenFileImpl: public ZipOperation, Arg, Arg, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { FnArg, FlagsArg, SizeArg, Crc32Arg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipOpenFile"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { std::string &fn = std::get( this->args ).Get(); OpenFlags::Flags flags = std::get( this->args ).Get(); uint64_t size = std::get( this->args ).Get(); uint32_t crc32 = std::get( this->args ).Get(); XRootDStatus st = this->zip->OpenFile( fn, flags, size, crc32 ); if( !st.IsOK() ) return st; handler->HandleResponse( new XRootDStatus(), nullptr ); return XRootDStatus(); } }; //---------------------------------------------------------------------------- //! Factory for creating OpenFileImpl objects //---------------------------------------------------------------------------- inline OpenFileImpl OpenFile( Ctx zip, Arg fn, Arg flags = OpenFlags::None, Arg size = 0, Arg crc32 = 0, uint16_t timeout = 0 ) { return OpenFileImpl( std::move( zip ), std::move( fn ), std::move( flags ), std::move( size ), std::move( crc32 ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Read operation (@see ZipOperation) //---------------------------------------------------------------------------- template class ZipReadImpl: public ZipOperation, Arg, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipRead"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { uint64_t offset = std::get( this->args ).Get(); uint32_t size = std::get( this->args ).Get(); void *buffer = std::get( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->Read( offset, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ArchiveReadImpl objects //---------------------------------------------------------------------------- inline ZipReadImpl Read( Ctx zip, Arg offset, Arg size, Arg buffer, uint16_t timeout = 0 ) { return ZipReadImpl( std::move( zip ), std::move( offset ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Read operation (@see ZipOperation) //---------------------------------------------------------------------------- template class ZipReadFromImpl: public ZipOperation, Arg, Arg, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { FileNameArg, OffsetArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipReadFrom"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { std::string &fn = std::get( this->args ).Get(); uint64_t offset = std::get( this->args ).Get(); uint32_t size = std::get( this->args ).Get(); void *buffer = std::get( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->ReadFrom( fn, offset, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ArchiveReadImpl objects //---------------------------------------------------------------------------- inline ZipReadFromImpl ReadFrom( Ctx zip, Arg fn, Arg offset, Arg size, Arg buffer, uint16_t timeout = 0 ) { return ZipReadFromImpl( std::move( zip ), std::move( fn ), std::move( offset ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Write operation (@see ZipOperation) //---------------------------------------------------------------------------- template class ZipWriteImpl: public ZipOperation, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipWrite"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { uint32_t size = std::get( this->args ).Get(); const void *buffer = std::get( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->Write( size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ArchiveReadImpl objects //---------------------------------------------------------------------------- inline ZipWriteImpl Write( Ctx zip, Arg size, Arg buffer, uint16_t timeout = 0 ) { return ZipWriteImpl( std::move( zip ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! AppendFile operation (@see ZipOperation) //---------------------------------------------------------------------------- template class AppendFileImpl: public ZipOperation, Arg, Arg, Arg, Arg> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation, Arg, Arg, Arg, Arg>::ZipOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { FnArg, CrcArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "AppendFile"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { std::string &fn = std::get( this->args ).Get(); uint32_t crc32 = std::get( this->args ).Get(); uint32_t size = std::get( this->args ).Get(); const void *buffer = std::get( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->AppendFile( fn, crc32, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ArchiveReadImpl objects //---------------------------------------------------------------------------- inline AppendFileImpl AppendFile( Ctx zip, Arg fn, Arg crc32, Arg size, Arg buffer, uint16_t timeout = 0 ) { return AppendFileImpl( std::move( zip ), std::move( fn ), std::move( crc32 ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! CloseFile operation (@see ZipOperation) //---------------------------------------------------------------------------- template class CloseFileImpl: public ZipOperation> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation>::ZipOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipCloseFile"; } private: //------------------------------------------------------------------------ // this is not an async operation so we don't need a handler //------------------------------------------------------------------------ using ZipOperation>::operator>>; protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { XRootDStatus st = this->zip->CloseFile(); if( !st.IsOK() ) return st; handler->HandleResponse( new XRootDStatus(), nullptr ); return XRootDStatus(); } }; typedef CloseFileImpl CloseFile; //---------------------------------------------------------------------------- //! ZipStat operation (@see ZipOperation) //---------------------------------------------------------------------------- template class ZipStatImpl: public ZipOperation> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation>::ZipOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipStat"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { StatInfo *info = nullptr; XRootDStatus st = this->zip->Stat( info ); if( !st.IsOK() ) return st; AnyObject *rsp = new AnyObject(); rsp->Set( info ); handler->HandleResponse( new XRootDStatus(), rsp ); return XRootDStatus(); } }; //---------------------------------------------------------------------------- //! Factory for creating ZipStatImpl objects //---------------------------------------------------------------------------- inline ZipStatImpl Stat( Ctx zip ) { return ZipStatImpl( std::move( zip ) ); } //---------------------------------------------------------------------------- //! ZipList operation (@see ZipOperation) //---------------------------------------------------------------------------- template class ZipListImpl: public ZipOperation> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation>::ZipOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipStat"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { DirectoryList *list = nullptr; XRootDStatus st = this->zip->List( list ); if( !st.IsOK() ) return st; AnyObject *rsp = new AnyObject(); rsp->Set( list ); handler->HandleResponse( new XRootDStatus(), rsp ); return XRootDStatus(); } }; //---------------------------------------------------------------------------- //! Factory for creating ZipStatImpl objects //---------------------------------------------------------------------------- inline ZipListImpl List( Ctx zip ) { return ZipListImpl( std::move( zip ) ); } //---------------------------------------------------------------------------- //! CloseArchive operation (@see ZipOperation) //---------------------------------------------------------------------------- template class CloseArchiveImpl: public ZipOperation> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using ZipOperation>::ZipOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ZipClose"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param params : container with parameters forwarded from //! previous operation //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->zip->CloseArchive( handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating CloseFileImpl objects //---------------------------------------------------------------------------- inline CloseArchiveImpl CloseArchive( Ctx zip, uint16_t timeout = 0 ) { return CloseArchiveImpl( std::move( zip ) ).Timeout( timeout ); } } #endif /* SRC_XRDCL_XRDCLZIPOPERATIONS_HH_ */