//------------------------------------------------------------------------------ // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN) // Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>, // Michal Simon <michal.simon@cern.ch> //------------------------------------------------------------------------------ // This file is part of the XRootD software suite. // // XRootD is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // XRootD is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with XRootD. If not, see <http://www.gnu.org/licenses/>. // // In applying this licence, CERN does not waive the privileges and immunities // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. //------------------------------------------------------------------------------ #ifndef __XRD_CL_FILE_OPERATIONS_HH__ #define __XRD_CL_FILE_OPERATIONS_HH__ #include "XrdCl/XrdClFile.hh" #include "XrdCl/XrdClOperations.hh" #include "XrdCl/XrdClOperationHandlers.hh" #include "XrdCl/XrdClCtx.hh" namespace XrdCl { //---------------------------------------------------------------------------- //! Base class for all file 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<template<bool> class Derived, bool HasHndl, typename Response, typename ... Arguments> class FileOperation: public ConcreteOperation<Derived, HasHndl, Response, Arguments...> { template<template<bool> class, bool, typename, typename ...> friend class FileOperation; public: //------------------------------------------------------------------------ //! Constructor //! //! @param f : file on which the operation will be performed //! @param args : file operation arguments //------------------------------------------------------------------------ FileOperation( Ctx<File> f, Arguments... args): ConcreteOperation<Derived, false, Response, Arguments...>( std::move( args )... ), file( std::move( f ) ) { } //------------------------------------------------------------------------ //! Move constructor from other states //! //! @arg from : state from which the object is being converted //! //! @param op : the object that is being converted //------------------------------------------------------------------------ template<bool from> FileOperation( FileOperation<Derived, from, Response, Arguments...> && op ) : ConcreteOperation<Derived, HasHndl, Response, Arguments...>( std::move( op ) ), file( op.file ) { } //------------------------------------------------------------------------ //! Destructor //------------------------------------------------------------------------ virtual ~FileOperation() { } protected: //------------------------------------------------------------------------ //! The file object itself //------------------------------------------------------------------------ Ctx<File> file; }; //---------------------------------------------------------------------------- //! Open operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class OpenImpl: public FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>, Arg<Access::Mode>> { //------------------------------------------------------------------------ //! Helper for extending the operator>> capabilities. //! //! In addition to standard overloads for std::function adds: //! - void( XRootDStatus&, StatInfo& ) //! - void( XRootDStatus&, StatInfo&, OperationContext& ) //------------------------------------------------------------------------ struct ExResp : public Resp<void> { //-------------------------------------------------------------------- //! Constructor //! //! @param file : the underlying XrdCl::File object //-------------------------------------------------------------------- ExResp( const Ctx<File> &file ): file( file ) { } //-------------------------------------------------------------------- //! A factory method //! //! @param func : the function/functor/lambda that should be wrapped //! @return : ResponseHandler instance //-------------------------------------------------------------------- inline ResponseHandler* Create( std::function<void( XRootDStatus&, StatInfo& )> func ) { return new ExOpenFuncWrapper( this->file, func ); } //-------------------------------------------------------------------- //! Make other overloads of Create visible //-------------------------------------------------------------------- using Resp<void>::Create; //-------------------------------------------------------------------- //! The underlying XrdCl::File object //-------------------------------------------------------------------- Ctx<File> file; }; public: //------------------------------------------------------------------------ //! Constructor (@see FileOperation) //------------------------------------------------------------------------ OpenImpl( Ctx<File> f, Arg<std::string> url, Arg<OpenFlags::Flags> flags, Arg<Access::Mode> mode = Access::None ) : FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>, Arg<Access::Mode>>( std::move( f ), std::move( url ), std::move( flags ), std::move( mode ) ) { } //------------------------------------------------------------------------ //! Move constructor from other states //! //! @arg from : state from which the object is being converted //! //! @param open : the object that is being converted //------------------------------------------------------------------------ template<bool from> OpenImpl( OpenImpl<from> && open ) : FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>, Arg<Access::Mode>>( std::move( open ) ) { } //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { UrlArg, FlagsArg, ModeArg }; //------------------------------------------------------------------------ //! Overload of operator>> defined in ConcreteOperation, we're adding //! additional capabilities by using ExResp factory (@see ExResp). //! //! @param hdlr : function/functor/lambda //------------------------------------------------------------------------ template<typename Hdlr> OpenImpl<true> operator>>( Hdlr &&hdlr ) { ExResp factory( *this->file ); return this->StreamImpl( factory.Create( hdlr ) ); } //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Open"; } protected: //------------------------------------------------------------------------ //! RunImpl operation (@see Operation) //! //! @param pipelineTimeout : pipeline timeout //! @return : status of the operation //------------------------------------------------------------------------ XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout ) { const std::string &url = std::get<UrlArg>( this->args ); OpenFlags::Flags flags = std::get<FlagsArg>( this->args ); Access::Mode mode = std::get<ModeArg>( this->args ); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Open( url, flags, mode, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ReadImpl objects //---------------------------------------------------------------------------- inline OpenImpl<false> Open( Ctx<File> file, Arg<std::string> url, Arg<OpenFlags::Flags> flags, Arg<Access::Mode> mode = Access::None, uint16_t timeout = 0 ) { return OpenImpl<false>( std::move( file ), std::move( url ), std::move( flags ), std::move( mode ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Read operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class ReadImpl: public FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Read"; } 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<OffsetArg>( this->args ).Get(); uint32_t size = std::get<SizeArg>( this->args ).Get(); void *buffer = std::get<BufferArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Read( offset, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ReadImpl objects //---------------------------------------------------------------------------- inline ReadImpl<false> Read( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout = 0 ) { return ReadImpl<false>( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! PgRead operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class PgReadImpl: public FileOperation<PgReadImpl, HasHndl, Resp<PageInfo>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<PgReadImpl, HasHndl, Resp<PageInfo>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "PgRead"; } 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<OffsetArg>( this->args ).Get(); uint32_t size = std::get<SizeArg>( this->args ).Get(); void *buffer = std::get<BufferArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->PgRead( offset, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating PgReadImpl objects //---------------------------------------------------------------------------- inline PgReadImpl<false> PgRead( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout = 0 ) { return PgReadImpl<false>( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! RdWithRsp: factory for creating ReadImpl/PgReadImpl objects //---------------------------------------------------------------------------- template<typename RSP> struct ReadTrait { }; template<> struct ReadTrait<ChunkInfo> { using RET = ReadImpl<false>; }; template<> struct ReadTrait<PageInfo> { using RET = PgReadImpl<false>; }; template<typename RSP> inline typename ReadTrait<RSP>::RET RdWithRsp( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout = 0 ); template<> inline ReadImpl<false> RdWithRsp<ChunkInfo>( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout ) { return Read( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ), timeout ); } template<> inline PgReadImpl<false> RdWithRsp<PageInfo>( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout ) { return PgRead( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ), timeout ); } //---------------------------------------------------------------------------- //! PgWrite operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class PgWriteImpl: public FileOperation<PgWriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>, Arg<std::vector<uint32_t>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<PgWriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>, Arg<void*>, Arg<std::vector<uint32_t>>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, SizeArg, BufferArg, CksumsArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "PgWrite"; } 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<OffsetArg>( this->args ).Get(); uint32_t size = std::get<SizeArg>( this->args ).Get(); void *buffer = std::get<BufferArg>( this->args ).Get(); std::vector<uint32_t> cksums = std::get<CksumsArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->PgWrite( offset, size, buffer, cksums, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating PgReadImpl objects //---------------------------------------------------------------------------- inline PgWriteImpl<false> PgWrite( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, Arg<std::vector<uint32_t>> cksums, uint16_t timeout = 0 ) { return PgWriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ), std::move( cksums ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Factory for creating PgReadImpl objects //---------------------------------------------------------------------------- inline PgWriteImpl<false> PgWrite( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<void*> buffer, uint16_t timeout = 0 ) { std::vector<uint32_t> cksums; return PgWriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ), std::move( cksums ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Close operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class CloseImpl: public FileOperation<CloseImpl, HasHndl, Resp<void>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<CloseImpl, HasHndl, Resp<void>>::FileOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Close"; } 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->file->Close( handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating CloseImpl objects //---------------------------------------------------------------------------- inline CloseImpl<false> Close( Ctx<File> file, uint16_t timeout = 0 ) { return CloseImpl<false>( std::move( file ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Stat operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class StatImpl: public FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { ForceArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Stat"; } 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 ) { bool force = std::get<ForceArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Stat( force, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating StatImpl objects (as there is another Stat in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline StatImpl<false> Stat( Ctx<File> file, Arg<bool> force, uint16_t timeout = 0 ) { return StatImpl<false>( std::move( file ), std::move( force ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Write operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class WriteImpl: public FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>, Arg<const void*>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>, Arg<const void*>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, SizeArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Write"; } 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<OffsetArg>( this->args ).Get(); uint32_t size = std::get<SizeArg>( this->args ).Get(); const void *buffer = std::get<BufferArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Write( offset, size, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating WriteImpl objects //---------------------------------------------------------------------------- inline WriteImpl<false> Write( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size, Arg<const void*> buffer, uint16_t timeout = 0 ) { return WriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ), std::move( buffer ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Sync operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class SyncImpl: public FileOperation<SyncImpl, HasHndl, Resp<void>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<SyncImpl, HasHndl, Resp<void>>::FileOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Sync"; } 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->file->Sync( handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating SyncImpl objects //---------------------------------------------------------------------------- inline SyncImpl<false> Sync( Ctx<File> file, uint16_t timeout = 0 ) { return SyncImpl<false>( std::move( file ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Truncate operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class TruncateImpl: public FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { SizeArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Truncate"; } 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 size = std::get<SizeArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Truncate( size, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating TruncateImpl objects (as there is another Stat in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline TruncateImpl<false> Truncate( Ctx<File> file, Arg<uint64_t> size, uint16_t timeout ) { return TruncateImpl<false>( std::move( file ), std::move( size ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! VectorRead operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class VectorReadImpl: public FileOperation<VectorReadImpl, HasHndl, Resp<VectorReadInfo>, Arg<ChunkList>, Arg<void*>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<VectorReadImpl, HasHndl, Resp<VectorReadInfo>, Arg<ChunkList>, Arg<void*>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { ChunksArg, BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "VectorRead"; } 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 ) { ChunkList &chunks = std::get<ChunksArg>( this->args ).Get(); void *buffer = std::get<BufferArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->VectorRead( chunks, buffer, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating VectorReadImpl objects //---------------------------------------------------------------------------- inline VectorReadImpl<false> VectorRead( Ctx<File> file, Arg<ChunkList> chunks, Arg<void*> buffer, uint16_t timeout = 0 ) { return VectorReadImpl<false>( std::move( file ), std::move( chunks ), std::move( buffer ) ).Timeout( timeout ); } inline VectorReadImpl<false> VectorRead( Ctx<File> file, Arg<ChunkList> chunks, uint16_t timeout = 0 ) { return VectorReadImpl<false>( std::move( file ), std::move( chunks ), nullptr ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! VectorWrite operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class VectorWriteImpl: public FileOperation<VectorWriteImpl, HasHndl, Resp<void>, Arg<ChunkList>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<VectorWriteImpl, HasHndl, Resp<void>, Arg<ChunkList>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { ChunksArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "VectorWrite"; } 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 ) { const ChunkList &chunks = std::get<ChunksArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->VectorWrite( chunks, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating VectorWriteImpl objects //---------------------------------------------------------------------------- inline VectorWriteImpl<false> VectorWrite( Ctx<File> file, Arg<ChunkList> chunks, uint16_t timeout = 0 ) { return VectorWriteImpl<false>( std::move( file ), std::move( chunks ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! WriteV operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class WriteVImpl: public FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<std::vector<iovec>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<std::vector<iovec>>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { OffsetArg, IovArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "WriteV"; } 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<OffsetArg>( this->args ).Get(); std::vector<iovec> &stdiov = std::get<IovArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; int iovcnt = stdiov.size(); iovec iov[iovcnt]; for( size_t i = 0; i < stdiov.size(); ++i ) { iov[i].iov_base = stdiov[i].iov_base; iov[i].iov_len = stdiov[i].iov_len; } return this->file->WriteV( offset, iov, iovcnt, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating WriteVImpl objects //---------------------------------------------------------------------------- inline WriteVImpl<false> WriteV( Ctx<File> file, Arg<uint64_t> offset, Arg<std::vector<iovec>> iov, uint16_t timeout = 0 ) { return WriteVImpl<false>( std::move( file ), std::move( offset ), std::move( iov ) ).Timeout( timeout ); } //---------------------------------------------------------------------------- //! Fcntl operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class FcntlImpl: public FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { BufferArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Fcntl"; } 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 ) { Buffer &arg = std::get<BufferArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->Fcntl( arg, handler, timeout ); } }; typedef FcntlImpl<false> Fcntl; //---------------------------------------------------------------------------- //! Visa operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class VisaImpl: public FileOperation<VisaImpl, HasHndl, Resp<Buffer>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<VisaImpl, HasHndl, Resp<Buffer>>::FileOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "Visa"; } 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->file->Visa( handler, timeout ); } }; typedef VisaImpl<false> Visa; //---------------------------------------------------------------------------- //! SetXAttr operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class SetXAttrImpl: public FileOperation<SetXAttrImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<std::string>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<SetXAttrImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<std::string>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { NameArg, ValueArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "SetXAttrImpl"; } 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 &name = std::get<NameArg>( this->args ).Get(); std::string &value = std::get<ValueArg>( this->args ).Get(); // wrap the arguments with a vector std::vector<xattr_t> attrs; attrs.push_back( xattr_t( name, value ) ); // wrap the PipelineHandler so the response gets unpacked properly UnpackXAttrStatus *h = new UnpackXAttrStatus( handler ); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; XRootDStatus st = this->file->SetXAttr( attrs, h, timeout ); if( !st.IsOK() ) delete h; return st; } }; //---------------------------------------------------------------------------- //! Factory for creating SetXAttrImpl objects (as there is another SetXAttr in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline SetXAttrImpl<false> SetXAttr( Ctx<File> file, Arg<std::string> name, Arg<std::string> value ) { return SetXAttrImpl<false>( std::move( file ), std::move( name ), std::move( value ) ); } //---------------------------------------------------------------------------- //! SetXAttr bulk operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class SetXAttrBulkImpl: public FileOperation<SetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>, Arg<std::vector<xattr_t>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<SetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>, Arg<std::vector<xattr_t>>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { AttrsArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "SetXAttrBulkImpl"; } 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::vector<xattr_t> &attrs = std::get<AttrsArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->SetXAttr( attrs, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating SetXAttrBulkImpl objects (as there is another SetXAttr //! in FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline SetXAttrBulkImpl<false> SetXAttr( Ctx<File> file, Arg<std::vector<xattr_t>> attrs ) { return SetXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) ); } //---------------------------------------------------------------------------- //! GetXAttr operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class GetXAttrImpl: public FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>, Arg<std::string>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>, Arg<std::string>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { NameArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "GetXAttrImpl"; } 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 &name = std::get<NameArg>( this->args ).Get(); // wrap the argument with a vector std::vector<std::string> attrs; attrs.push_back( name ); // wrap the PipelineHandler so the response gets unpacked properly UnpackXAttr *h = new UnpackXAttr( handler ); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; XRootDStatus st = this->file->GetXAttr( attrs, h, timeout ); if( !st.IsOK() ) delete h; return st; } }; //---------------------------------------------------------------------------- //! Factory for creating GetXAttrImpl objects (as there is another GetXAttr in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline GetXAttrImpl<false> GetXAttr( Ctx<File> file, Arg<std::string> name ) { return GetXAttrImpl<false>( std::move( file ), std::move( name ) ); } //---------------------------------------------------------------------------- //! GetXAttr bulk operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class GetXAttrBulkImpl: public FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>, Arg<std::vector<std::string>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>, Arg<std::vector<std::string>>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { NamesArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "GetXAttrBulkImpl"; } 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::vector<std::string> &attrs = std::get<NamesArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->GetXAttr( attrs, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating GetXAttrBulkImpl objects (as there is another GetXAttr in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline GetXAttrBulkImpl<false> GetXAttr( Ctx<File> file, Arg<std::vector<std::string>> attrs ) { return GetXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) ); } //---------------------------------------------------------------------------- //! DelXAttr operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class DelXAttrImpl: public FileOperation<DelXAttrImpl, HasHndl, Resp<void>, Arg<std::string>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<DelXAttrImpl, HasHndl, Resp<void>, Arg<std::string>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { NameArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "DelXAttrImpl"; } 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 &name = std::get<NameArg>( this->args ).Get(); // wrap the argument with a vector std::vector<std::string> attrs; attrs.push_back( name ); // wrap the PipelineHandler so the response gets unpacked properly UnpackXAttrStatus *h = new UnpackXAttrStatus( handler ); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; XRootDStatus st = this->file->DelXAttr( attrs, h, timeout ); if( !st.IsOK() ) delete h; return st; } }; //---------------------------------------------------------------------------- //! Factory for creating DelXAttrImpl objects (as there is another DelXAttr in //! FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline DelXAttrImpl<false> DelXAttr( Ctx<File> file, Arg<std::string> name ) { return DelXAttrImpl<false>( std::move( file ), std::move( name ) ); } //---------------------------------------------------------------------------- //! DelXAttr bulk operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class DelXAttrBulkImpl: public FileOperation<DelXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>, Arg<std::vector<std::string>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<DelXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>, Arg<std::vector<std::string>>>::FileOperation; //------------------------------------------------------------------------ //! Argument indexes in the args tuple //------------------------------------------------------------------------ enum { NamesArg }; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "DelXAttrBulkImpl"; } 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::vector<std::string> &attrs = std::get<NamesArg>( this->args ).Get(); uint16_t timeout = pipelineTimeout < this->timeout ? pipelineTimeout : this->timeout; return this->file->DelXAttr( attrs, handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating DelXAttrBulkImpl objects (as there is another DelXAttr //! in FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline DelXAttrBulkImpl<false> DelXAttr( Ctx<File> file, Arg<std::vector<std::string>> attrs ) { return DelXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) ); } //---------------------------------------------------------------------------- //! ListXAttr bulk operation (@see FileOperation) //---------------------------------------------------------------------------- template<bool HasHndl> class ListXAttrImpl: public FileOperation<ListXAttrImpl, HasHndl, Resp<std::vector<XAttr>>> { public: //------------------------------------------------------------------------ //! Inherit constructors from FileOperation (@see FileOperation) //------------------------------------------------------------------------ using FileOperation<ListXAttrImpl, HasHndl, Resp<std::vector<XAttr>>>::FileOperation; //------------------------------------------------------------------------ //! @return : name of the operation (@see Operation) //------------------------------------------------------------------------ std::string ToString() { return "ListXAttrImpl"; } 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->file->ListXAttr( handler, timeout ); } }; //---------------------------------------------------------------------------- //! Factory for creating ListXAttrImpl objects (as there is another ListXAttr //! in FileSystem there would be a clash of typenames). //---------------------------------------------------------------------------- inline ListXAttrImpl<false> ListXAttr( Ctx<File> file ) { return ListXAttrImpl<false>( std::move( file ) ); } } #endif // __XRD_CL_FILE_OPERATIONS_HH__