Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 10:10:59

0001 //------------------------------------------------------------------------------
0002 // Copyright (c) 2011-2017 by European Organization for Nuclear Research (CERN)
0003 // Author: Krzysztof Jamrog <krzysztof.piotr.jamrog@cern.ch>,
0004 //         Michal Simon <michal.simon@cern.ch>
0005 //------------------------------------------------------------------------------
0006 // This file is part of the XRootD software suite.
0007 //
0008 // XRootD is free software: you can redistribute it and/or modify
0009 // it under the terms of the GNU Lesser General Public License as published by
0010 // the Free Software Foundation, either version 3 of the License, or
0011 // (at your option) any later version.
0012 //
0013 // XRootD is distributed in the hope that it will be useful,
0014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016 // GNU General Public License for more details.
0017 //
0018 // You should have received a copy of the GNU Lesser General Public License
0019 // along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
0020 //
0021 // In applying this licence, CERN does not waive the privileges and immunities
0022 // granted to it by virtue of its status as an Intergovernmental Organization
0023 // or submit itself to any jurisdiction.
0024 //------------------------------------------------------------------------------
0025 
0026 #ifndef __XRD_CL_FILE_OPERATIONS_HH__
0027 #define __XRD_CL_FILE_OPERATIONS_HH__
0028 
0029 #include "XrdCl/XrdClFile.hh"
0030 #include "XrdCl/XrdClOperations.hh"
0031 #include "XrdCl/XrdClOperationHandlers.hh"
0032 #include "XrdCl/XrdClCtx.hh"
0033 
0034 namespace XrdCl
0035 {
0036 
0037   //----------------------------------------------------------------------------
0038   //! Base class for all file related operations
0039   //!
0040   //! @arg Derived : the class that derives from this template (CRTP)
0041   //! @arg HasHndl : true if operation has a handler, false otherwise
0042   //! @arg Args    : operation arguments
0043   //----------------------------------------------------------------------------
0044   template<template<bool> class Derived, bool HasHndl, typename Response, typename ... Arguments>
0045   class FileOperation: public ConcreteOperation<Derived, HasHndl, Response, Arguments...>
0046   {
0047 
0048       template<template<bool> class, bool, typename, typename ...> friend class FileOperation;
0049 
0050     public:
0051       //------------------------------------------------------------------------
0052       //! Constructor
0053       //!
0054       //! @param f    : file on which the operation will be performed
0055       //! @param args : file operation arguments
0056       //------------------------------------------------------------------------
0057       FileOperation( Ctx<File> f, Arguments... args): ConcreteOperation<Derived, false, Response, Arguments...>( std::move( args )... ), file( std::move( f ) )
0058       {
0059       }
0060 
0061       //------------------------------------------------------------------------
0062       //! Move constructor from other states
0063       //!
0064       //! @arg from : state from which the object is being converted
0065       //!
0066       //! @param op : the object that is being converted
0067       //------------------------------------------------------------------------
0068       template<bool from>
0069       FileOperation( FileOperation<Derived, from, Response, Arguments...> && op ) :
0070         ConcreteOperation<Derived, HasHndl, Response, Arguments...>( std::move( op ) ), file( op.file )
0071       {
0072 
0073       }
0074 
0075       //------------------------------------------------------------------------
0076       //! Destructor
0077       //------------------------------------------------------------------------
0078       virtual ~FileOperation()
0079       {
0080 
0081       }
0082 
0083     protected:
0084 
0085       //------------------------------------------------------------------------
0086       //! The file object itself
0087       //------------------------------------------------------------------------
0088       Ctx<File> file;
0089   };
0090 
0091   //----------------------------------------------------------------------------
0092   //! Open operation (@see FileOperation)
0093   //----------------------------------------------------------------------------
0094   template<bool HasHndl>
0095   class OpenImpl: public FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>,
0096       Arg<OpenFlags::Flags>, Arg<Access::Mode>>
0097   {
0098       //------------------------------------------------------------------------
0099       //! Helper for extending the operator>> capabilities.
0100       //!
0101       //! In addition to standard overloads for std::function adds:
0102       //! - void( XRootDStatus&, StatInfo& )
0103       //! - void( XRootDStatus&, StatInfo&, OperationContext& )
0104       //------------------------------------------------------------------------
0105       struct ExResp : public Resp<void>
0106       {
0107           //--------------------------------------------------------------------
0108           //! Constructor
0109           //!
0110           //! @param file : the underlying XrdCl::File object
0111           //--------------------------------------------------------------------
0112           ExResp( const Ctx<File> &file ): file( file )
0113           {
0114           }
0115 
0116           //--------------------------------------------------------------------
0117           //! A factory method
0118           //!
0119           //! @param func : the function/functor/lambda that should be wrapped
0120           //! @return     : ResponseHandler instance
0121           //--------------------------------------------------------------------
0122           inline ResponseHandler* Create( std::function<void( XRootDStatus&,
0123               StatInfo& )> func )
0124           {
0125             return new ExOpenFuncWrapper( this->file, func );
0126           }
0127 
0128           //--------------------------------------------------------------------
0129           //! Make other overloads of Create visible
0130           //--------------------------------------------------------------------
0131           using Resp<void>::Create;
0132 
0133           //--------------------------------------------------------------------
0134           //! The underlying XrdCl::File object
0135           //--------------------------------------------------------------------
0136           Ctx<File> file;
0137       };
0138 
0139     public:
0140 
0141       //------------------------------------------------------------------------
0142       //! Constructor (@see FileOperation)
0143       //------------------------------------------------------------------------
0144       OpenImpl( Ctx<File> f, Arg<std::string> url, Arg<OpenFlags::Flags> flags,
0145                 Arg<Access::Mode> mode = Access::None ) :
0146           FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>,
0147             Arg<Access::Mode>>( std::move( f ), std::move( url ), std::move( flags ),
0148             std::move( mode ) )
0149       {
0150       }
0151 
0152       //------------------------------------------------------------------------
0153       //! Move constructor from other states
0154       //!
0155       //! @arg from : state from which the object is being converted
0156       //!
0157       //! @param open : the object that is being converted
0158       //------------------------------------------------------------------------
0159       template<bool from>
0160       OpenImpl( OpenImpl<from> && open ) :
0161           FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>,
0162             Arg<Access::Mode>>( std::move( open ) )
0163       {
0164       }
0165 
0166 
0167       //------------------------------------------------------------------------
0168       //! Argument indexes in the args tuple
0169       //------------------------------------------------------------------------
0170       enum { UrlArg, FlagsArg, ModeArg };
0171 
0172       //------------------------------------------------------------------------
0173       //! Overload of operator>> defined in ConcreteOperation, we're adding
0174       //! additional capabilities by using ExResp factory (@see ExResp).
0175       //!
0176       //! @param hdlr : function/functor/lambda
0177       //------------------------------------------------------------------------
0178       template<typename Hdlr>
0179       OpenImpl<true> operator>>( Hdlr &&hdlr )
0180       {
0181         ExResp factory( *this->file );
0182         return this->StreamImpl( factory.Create( hdlr ) );
0183       }
0184 
0185       //------------------------------------------------------------------------
0186       //! @return : name of the operation (@see Operation)
0187       //------------------------------------------------------------------------
0188       std::string ToString()
0189       {
0190         return "Open";
0191       }
0192 
0193     protected:
0194 
0195       //------------------------------------------------------------------------
0196       //! RunImpl operation (@see Operation)
0197       //!
0198       //! @param pipelineTimeout : pipeline timeout
0199       //! @return                : status of the operation
0200       //------------------------------------------------------------------------
0201       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0202       {
0203         const std::string &url     = std::get<UrlArg>( this->args );
0204         OpenFlags::Flags   flags   = std::get<FlagsArg>( this->args );
0205         Access::Mode       mode    = std::get<ModeArg>( this->args );
0206         uint16_t           timeout = pipelineTimeout < this->timeout ?
0207                                      pipelineTimeout : this->timeout;
0208         return this->file->Open( url, flags, mode, handler, timeout );
0209       }
0210   };
0211 
0212   //----------------------------------------------------------------------------
0213   //! Factory for creating ReadImpl objects
0214   //----------------------------------------------------------------------------
0215   inline OpenImpl<false> Open( Ctx<File> file, Arg<std::string> url, Arg<OpenFlags::Flags> flags,
0216                                Arg<Access::Mode> mode = Access::None, uint16_t timeout = 0 )
0217   {
0218     return OpenImpl<false>( std::move( file ), std::move( url ), std::move( flags ),
0219                             std::move( mode ) ).Timeout( timeout );
0220   }
0221 
0222   //----------------------------------------------------------------------------
0223   //! Read operation (@see FileOperation)
0224   //----------------------------------------------------------------------------
0225   template<bool HasHndl>
0226   class ReadImpl: public FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>,
0227       Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>
0228   {
0229     public:
0230 
0231       //------------------------------------------------------------------------
0232       //! Inherit constructors from FileOperation (@see FileOperation)
0233       //------------------------------------------------------------------------
0234       using FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>, Arg<uint64_t>,
0235                           Arg<uint32_t>, Arg<void*>>::FileOperation;
0236 
0237       //------------------------------------------------------------------------
0238       //! Argument indexes in the args tuple
0239       //------------------------------------------------------------------------
0240       enum { OffsetArg, SizeArg, BufferArg };
0241 
0242       //------------------------------------------------------------------------
0243       //! @return : name of the operation (@see Operation)
0244       //------------------------------------------------------------------------
0245       std::string ToString()
0246       {
0247         return "Read";
0248       }
0249 
0250     protected:
0251 
0252       //------------------------------------------------------------------------
0253       //! RunImpl operation (@see Operation)
0254       //!
0255       //! @param params :  container with parameters forwarded from
0256       //!                  previous operation
0257       //! @return       :  status of the operation
0258       //------------------------------------------------------------------------
0259       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0260       {
0261         uint64_t  offset  = std::get<OffsetArg>( this->args ).Get();
0262         uint32_t  size    = std::get<SizeArg>( this->args ).Get();
0263         void     *buffer  = std::get<BufferArg>( this->args ).Get();
0264         uint16_t  timeout = pipelineTimeout < this->timeout ?
0265                             pipelineTimeout : this->timeout;
0266         return this->file->Read( offset, size, buffer, handler, timeout );
0267       }
0268   };
0269 
0270   //----------------------------------------------------------------------------
0271   //! Factory for creating ReadImpl objects
0272   //----------------------------------------------------------------------------
0273   inline ReadImpl<false> Read( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size,
0274                                Arg<void*> buffer, uint16_t timeout = 0 )
0275   {
0276     return ReadImpl<false>( std::move( file ), std::move( offset ), std::move( size ),
0277                             std::move( buffer ) ).Timeout( timeout );
0278   }
0279 
0280   //----------------------------------------------------------------------------
0281   //! PgRead operation (@see FileOperation)
0282   //----------------------------------------------------------------------------
0283   template<bool HasHndl>
0284   class PgReadImpl: public FileOperation<PgReadImpl, HasHndl, Resp<PageInfo>,
0285       Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>
0286   {
0287     public:
0288 
0289       //------------------------------------------------------------------------
0290       //! Inherit constructors from FileOperation (@see FileOperation)
0291       //------------------------------------------------------------------------
0292       using FileOperation<PgReadImpl, HasHndl, Resp<PageInfo>, Arg<uint64_t>,
0293                           Arg<uint32_t>, Arg<void*>>::FileOperation;
0294 
0295       //------------------------------------------------------------------------
0296       //! Argument indexes in the args tuple
0297       //------------------------------------------------------------------------
0298       enum { OffsetArg, SizeArg, BufferArg };
0299 
0300       //------------------------------------------------------------------------
0301       //! @return : name of the operation (@see Operation)
0302       //------------------------------------------------------------------------
0303       std::string ToString()
0304       {
0305         return "PgRead";
0306       }
0307 
0308     protected:
0309 
0310       //------------------------------------------------------------------------
0311       //! RunImpl operation (@see Operation)
0312       //!
0313       //! @param params :  container with parameters forwarded from
0314       //!                  previous operation
0315       //! @return       :  status of the operation
0316       //------------------------------------------------------------------------
0317       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0318       {
0319         uint64_t  offset  = std::get<OffsetArg>( this->args ).Get();
0320         uint32_t  size    = std::get<SizeArg>( this->args ).Get();
0321         void     *buffer  = std::get<BufferArg>( this->args ).Get();
0322         uint16_t  timeout = pipelineTimeout < this->timeout ?
0323                             pipelineTimeout : this->timeout;
0324         return this->file->PgRead( offset, size, buffer, handler, timeout );
0325       }
0326   };
0327 
0328   //----------------------------------------------------------------------------
0329   //! Factory for creating PgReadImpl objects
0330   //----------------------------------------------------------------------------
0331   inline PgReadImpl<false> PgRead( Ctx<File> file, Arg<uint64_t> offset,
0332                                  Arg<uint32_t> size, Arg<void*> buffer,
0333                                  uint16_t timeout = 0 )
0334   {
0335     return PgReadImpl<false>( std::move( file ), std::move( offset ), std::move( size ),
0336                             std::move( buffer ) ).Timeout( timeout );
0337   }
0338 
0339   //----------------------------------------------------------------------------
0340   //! RdWithRsp: factory for creating ReadImpl/PgReadImpl objects
0341   //----------------------------------------------------------------------------
0342   template<typename RSP> struct ReadTrait { };
0343 
0344   template<> struct ReadTrait<ChunkInfo> { using RET = ReadImpl<false>; };
0345 
0346   template<> struct ReadTrait<PageInfo> { using RET = PgReadImpl<false>; };
0347 
0348   template<typename RSP> inline typename ReadTrait<RSP>::RET
0349   RdWithRsp( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size,
0350              Arg<void*> buffer, uint16_t timeout = 0 );
0351 
0352   template<> inline ReadImpl<false>
0353   RdWithRsp<ChunkInfo>( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size,
0354                         Arg<void*> buffer, uint16_t timeout )
0355   {
0356     return Read( std::move( file ), std::move( offset ), std::move( size ),
0357                  std::move( buffer ), timeout );
0358   }
0359 
0360   template<> inline PgReadImpl<false>
0361   RdWithRsp<PageInfo>( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size,
0362                        Arg<void*> buffer, uint16_t timeout )
0363   {
0364     return PgRead( std::move( file ), std::move( offset ), std::move( size ),
0365                    std::move( buffer ), timeout );
0366   }
0367 
0368   //----------------------------------------------------------------------------
0369   //! PgWrite operation (@see FileOperation)
0370   //----------------------------------------------------------------------------
0371   template<bool HasHndl>
0372   class PgWriteImpl: public FileOperation<PgWriteImpl, HasHndl, Resp<void>,
0373       Arg<uint64_t>, Arg<uint32_t>, Arg<void*>, Arg<std::vector<uint32_t>>>
0374   {
0375     public:
0376 
0377       //------------------------------------------------------------------------
0378       //! Inherit constructors from FileOperation (@see FileOperation)
0379       //------------------------------------------------------------------------
0380       using FileOperation<PgWriteImpl, HasHndl, Resp<void>, Arg<uint64_t>,
0381                           Arg<uint32_t>, Arg<void*>, Arg<std::vector<uint32_t>>>::FileOperation;
0382 
0383       //------------------------------------------------------------------------
0384       //! Argument indexes in the args tuple
0385       //------------------------------------------------------------------------
0386       enum { OffsetArg, SizeArg, BufferArg, CksumsArg };
0387 
0388       //------------------------------------------------------------------------
0389       //! @return : name of the operation (@see Operation)
0390       //------------------------------------------------------------------------
0391       std::string ToString()
0392       {
0393         return "PgWrite";
0394       }
0395 
0396     protected:
0397 
0398       //------------------------------------------------------------------------
0399       //! RunImpl operation (@see Operation)
0400       //!
0401       //! @param params :  container with parameters forwarded from
0402       //!                  previous operation
0403       //! @return       :  status of the operation
0404       //------------------------------------------------------------------------
0405       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0406       {
0407         uint64_t               offset = std::get<OffsetArg>( this->args ).Get();
0408         uint32_t               size   = std::get<SizeArg>( this->args ).Get();
0409         void                  *buffer = std::get<BufferArg>( this->args ).Get();
0410         std::vector<uint32_t>  cksums = std::get<CksumsArg>( this->args ).Get();
0411         uint16_t  timeout = pipelineTimeout < this->timeout ?
0412                             pipelineTimeout : this->timeout;
0413         return this->file->PgWrite( offset, size, buffer, cksums, handler, timeout );
0414       }
0415   };
0416 
0417   //----------------------------------------------------------------------------
0418   //! Factory for creating PgReadImpl objects
0419   //----------------------------------------------------------------------------
0420   inline PgWriteImpl<false> PgWrite( Ctx<File> file, Arg<uint64_t> offset,
0421                                     Arg<uint32_t> size, Arg<void*> buffer,
0422                                     Arg<std::vector<uint32_t>> cksums,
0423                                     uint16_t timeout = 0 )
0424   {
0425     return PgWriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ),
0426                                std::move( buffer ), std::move( cksums ) ).Timeout( timeout );
0427   }
0428 
0429   //----------------------------------------------------------------------------
0430   //! Factory for creating PgReadImpl objects
0431   //----------------------------------------------------------------------------
0432   inline PgWriteImpl<false> PgWrite( Ctx<File> file, Arg<uint64_t> offset,
0433                                     Arg<uint32_t> size, Arg<void*> buffer,
0434                                     uint16_t timeout = 0 )
0435   {
0436     std::vector<uint32_t> cksums;
0437     return PgWriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ),
0438                                std::move( buffer ), std::move( cksums ) ).Timeout( timeout );
0439   }
0440 
0441   //----------------------------------------------------------------------------
0442   //! Close operation (@see FileOperation)
0443   //----------------------------------------------------------------------------
0444   template<bool HasHndl>
0445   class CloseImpl: public FileOperation<CloseImpl, HasHndl, Resp<void>>
0446   {
0447     public:
0448 
0449       //------------------------------------------------------------------------
0450       //! Inherit constructors from FileOperation (@see FileOperation)
0451       //------------------------------------------------------------------------
0452       using FileOperation<CloseImpl, HasHndl, Resp<void>>::FileOperation;
0453 
0454       //------------------------------------------------------------------------
0455       //! @return : name of the operation (@see Operation)
0456       //------------------------------------------------------------------------
0457       std::string ToString()
0458       {
0459         return "Close";
0460       }
0461 
0462     protected:
0463 
0464       //------------------------------------------------------------------------
0465       //! RunImpl operation (@see Operation)
0466       //!
0467       //! @param params :  container with parameters forwarded from
0468       //!                  previous operation
0469       //! @return       :  status of the operation
0470       //------------------------------------------------------------------------
0471       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0472       {
0473         uint16_t timeout = pipelineTimeout < this->timeout ?
0474                            pipelineTimeout : this->timeout;
0475         return this->file->Close( handler, timeout );
0476       }
0477   };
0478 
0479   //----------------------------------------------------------------------------
0480   //! Factory for creating CloseImpl objects
0481   //----------------------------------------------------------------------------
0482   inline CloseImpl<false> Close( Ctx<File> file, uint16_t timeout = 0 )
0483   {
0484     return CloseImpl<false>( std::move( file ) ).Timeout( timeout );
0485   }
0486 
0487   //----------------------------------------------------------------------------
0488   //! Stat operation (@see FileOperation)
0489   //----------------------------------------------------------------------------
0490   template<bool HasHndl>
0491   class StatImpl: public FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>
0492   {
0493     public:
0494 
0495       //------------------------------------------------------------------------
0496       //! Inherit constructors from FileOperation (@see FileOperation)
0497       //------------------------------------------------------------------------
0498       using FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>::FileOperation;
0499 
0500       //------------------------------------------------------------------------
0501       //! Argument indexes in the args tuple
0502       //------------------------------------------------------------------------
0503       enum { ForceArg };
0504 
0505       //------------------------------------------------------------------------
0506       //! @return : name of the operation (@see Operation)
0507       //------------------------------------------------------------------------
0508       std::string ToString()
0509       {
0510         return "Stat";
0511       }
0512 
0513     protected:
0514 
0515       //------------------------------------------------------------------------
0516       //! RunImpl operation (@see Operation)
0517       //!
0518       //! @param params :  container with parameters forwarded from
0519       //!                  previous operation
0520       //! @return       :  status of the operation
0521       //------------------------------------------------------------------------
0522       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0523       {
0524         bool     force   = std::get<ForceArg>( this->args ).Get();
0525         uint16_t timeout = pipelineTimeout < this->timeout ?
0526                            pipelineTimeout : this->timeout;
0527         return this->file->Stat( force, handler, timeout );
0528       }
0529   };
0530 
0531   //----------------------------------------------------------------------------
0532   //! Factory for creating StatImpl objects (as there is another Stat in
0533   //! FileSystem there would be a clash of typenames).
0534   //----------------------------------------------------------------------------
0535   inline StatImpl<false> Stat( Ctx<File> file, Arg<bool> force, uint16_t timeout = 0 )
0536   {
0537     return StatImpl<false>( std::move( file ), std::move( force ) ).Timeout( timeout );
0538   }
0539 
0540   //----------------------------------------------------------------------------
0541   //! Write operation (@see FileOperation)
0542   //----------------------------------------------------------------------------
0543   template<bool HasHndl>
0544   class WriteImpl: public FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>,
0545       Arg<uint32_t>, Arg<const void*>>
0546   {
0547     public:
0548 
0549       //------------------------------------------------------------------------
0550       //! Inherit constructors from FileOperation (@see FileOperation)
0551       //------------------------------------------------------------------------
0552       using FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>,
0553                           Arg<const void*>>::FileOperation;
0554 
0555       //------------------------------------------------------------------------
0556       //! Argument indexes in the args tuple
0557       //------------------------------------------------------------------------
0558       enum { OffsetArg, SizeArg, BufferArg };
0559 
0560       //------------------------------------------------------------------------
0561       //! @return : name of the operation (@see Operation)
0562       //------------------------------------------------------------------------
0563       std::string ToString()
0564       {
0565         return "Write";
0566       }
0567 
0568     protected:
0569 
0570       //------------------------------------------------------------------------
0571       //! RunImpl operation (@see Operation)
0572       //!
0573       //! @param params :  container with parameters forwarded from
0574       //!                  previous operation
0575       //! @return       :  status of the operation
0576       //------------------------------------------------------------------------
0577       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0578       {
0579         uint64_t    offset = std::get<OffsetArg>( this->args ).Get();
0580         uint32_t    size   = std::get<SizeArg>( this->args ).Get();
0581         const void *buffer = std::get<BufferArg>( this->args ).Get();
0582         uint16_t    timeout = pipelineTimeout < this->timeout ?
0583                             pipelineTimeout : this->timeout;
0584         return this->file->Write( offset, size, buffer, handler, timeout );
0585       }
0586   };
0587 
0588   //----------------------------------------------------------------------------
0589   //! Factory for creating WriteImpl objects
0590   //----------------------------------------------------------------------------
0591   inline WriteImpl<false> Write( Ctx<File> file, Arg<uint64_t> offset, Arg<uint32_t> size,
0592                                  Arg<const void*> buffer, uint16_t timeout = 0 )
0593   {
0594     return WriteImpl<false>( std::move( file ), std::move( offset ), std::move( size ),
0595                              std::move( buffer ) ).Timeout( timeout );
0596   }
0597 
0598   //----------------------------------------------------------------------------
0599   //! Sync operation (@see FileOperation)
0600   //----------------------------------------------------------------------------
0601   template<bool HasHndl>
0602   class SyncImpl: public FileOperation<SyncImpl, HasHndl, Resp<void>>
0603   {
0604     public:
0605 
0606       //------------------------------------------------------------------------
0607       //! Inherit constructors from FileOperation (@see FileOperation)
0608       //------------------------------------------------------------------------
0609       using FileOperation<SyncImpl, HasHndl, Resp<void>>::FileOperation;
0610 
0611       //------------------------------------------------------------------------
0612       //! @return : name of the operation (@see Operation)
0613       //------------------------------------------------------------------------
0614       std::string ToString()
0615       {
0616         return "Sync";
0617       }
0618 
0619     protected:
0620 
0621       //------------------------------------------------------------------------
0622       //! RunImpl operation (@see Operation)
0623       //!
0624       //! @param params :  container with parameters forwarded from
0625       //!                  previous operation
0626       //! @return       :  status of the operation
0627       //------------------------------------------------------------------------
0628       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0629       {
0630         uint16_t timeout = pipelineTimeout < this->timeout ?
0631                            pipelineTimeout : this->timeout;
0632         return this->file->Sync( handler, timeout );
0633       }
0634   };
0635 
0636   //----------------------------------------------------------------------------
0637   //! Factory for creating SyncImpl objects
0638   //----------------------------------------------------------------------------
0639   inline SyncImpl<false> Sync( Ctx<File> file, uint16_t timeout = 0 )
0640   {
0641     return SyncImpl<false>( std::move( file ) ).Timeout( timeout );
0642   }
0643 
0644   //----------------------------------------------------------------------------
0645   //! Truncate operation (@see FileOperation)
0646   //----------------------------------------------------------------------------
0647   template<bool HasHndl>
0648   class TruncateImpl: public FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>
0649   {
0650     public:
0651 
0652       //------------------------------------------------------------------------
0653       //! Inherit constructors from FileOperation (@see FileOperation)
0654       //------------------------------------------------------------------------
0655       using FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>::FileOperation;
0656 
0657       //------------------------------------------------------------------------
0658       //! Argument indexes in the args tuple
0659       //------------------------------------------------------------------------
0660       enum { SizeArg };
0661 
0662       //------------------------------------------------------------------------
0663       //! @return : name of the operation (@see Operation)
0664       //------------------------------------------------------------------------
0665       std::string ToString()
0666       {
0667         return "Truncate";
0668       }
0669 
0670     protected:
0671 
0672       //------------------------------------------------------------------------
0673       //! RunImpl operation (@see Operation)
0674       //!
0675       //! @param params :  container with parameters forwarded from
0676       //!                  previous operation
0677       //! @return       :  status of the operation
0678       //------------------------------------------------------------------------
0679       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0680       {
0681         uint64_t size    = std::get<SizeArg>( this->args ).Get();
0682         uint16_t timeout = pipelineTimeout < this->timeout ?
0683                            pipelineTimeout : this->timeout;
0684         return this->file->Truncate( size, handler, timeout );
0685       }
0686   };
0687 
0688   //----------------------------------------------------------------------------
0689   //! Factory for creating TruncateImpl objects (as there is another Stat in
0690   //! FileSystem there would be a clash of typenames).
0691   //----------------------------------------------------------------------------
0692   inline TruncateImpl<false> Truncate( Ctx<File> file, Arg<uint64_t> size, uint16_t timeout )
0693   {
0694     return TruncateImpl<false>( std::move( file ), std::move( size ) ).Timeout( timeout );
0695   }
0696 
0697   //----------------------------------------------------------------------------
0698   //! VectorRead operation (@see FileOperation)
0699   //----------------------------------------------------------------------------
0700   template<bool HasHndl>
0701   class VectorReadImpl: public FileOperation<VectorReadImpl, HasHndl,
0702       Resp<VectorReadInfo>, Arg<ChunkList>, Arg<void*>>
0703   {
0704     public:
0705 
0706       //------------------------------------------------------------------------
0707       //! Inherit constructors from FileOperation (@see FileOperation)
0708       //------------------------------------------------------------------------
0709       using FileOperation<VectorReadImpl, HasHndl, Resp<VectorReadInfo>, Arg<ChunkList>,
0710                           Arg<void*>>::FileOperation;
0711 
0712       //------------------------------------------------------------------------
0713       //! Argument indexes in the args tuple
0714       //------------------------------------------------------------------------
0715       enum { ChunksArg, BufferArg };
0716 
0717       //------------------------------------------------------------------------
0718       //! @return : name of the operation (@see Operation)
0719       //------------------------------------------------------------------------
0720       std::string ToString()
0721       {
0722         return "VectorRead";
0723       }
0724 
0725     protected:
0726 
0727       //------------------------------------------------------------------------
0728       //! RunImpl operation (@see Operation)
0729       //!
0730       //! @param params :  container with parameters forwarded from
0731       //!                  previous operation
0732       //! @return       :  status of the operation
0733       //------------------------------------------------------------------------
0734       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0735       {
0736         ChunkList &chunks  = std::get<ChunksArg>( this->args ).Get();
0737         void      *buffer  = std::get<BufferArg>( this->args ).Get();
0738         uint16_t   timeout = pipelineTimeout < this->timeout ?
0739                              pipelineTimeout : this->timeout;
0740         return this->file->VectorRead( chunks, buffer, handler, timeout );
0741       }
0742   };
0743 
0744   //----------------------------------------------------------------------------
0745   //! Factory for creating VectorReadImpl objects
0746   //----------------------------------------------------------------------------
0747   inline VectorReadImpl<false> VectorRead( Ctx<File> file, Arg<ChunkList> chunks,
0748                                            Arg<void*> buffer, uint16_t timeout = 0 )
0749   {
0750     return VectorReadImpl<false>( std::move( file ), std::move( chunks ), std::move( buffer ) ).Timeout( timeout );
0751   }
0752 
0753   inline VectorReadImpl<false> VectorRead( Ctx<File> file, Arg<ChunkList> chunks,
0754                                            uint16_t timeout = 0 )
0755   {
0756     return VectorReadImpl<false>( std::move( file ), std::move( chunks ), nullptr ).Timeout( timeout );
0757   }
0758 
0759   //----------------------------------------------------------------------------
0760   //! VectorWrite operation (@see FileOperation)
0761   //----------------------------------------------------------------------------
0762   template<bool HasHndl>
0763   class VectorWriteImpl: public FileOperation<VectorWriteImpl, HasHndl, Resp<void>,
0764       Arg<ChunkList>>
0765   {
0766     public:
0767 
0768       //------------------------------------------------------------------------
0769       //! Inherit constructors from FileOperation (@see FileOperation)
0770       //------------------------------------------------------------------------
0771       using FileOperation<VectorWriteImpl, HasHndl, Resp<void>, Arg<ChunkList>>::FileOperation;
0772 
0773       //------------------------------------------------------------------------
0774       //! Argument indexes in the args tuple
0775       //------------------------------------------------------------------------
0776       enum { ChunksArg };
0777 
0778       //------------------------------------------------------------------------
0779       //! @return : name of the operation (@see Operation)
0780       //------------------------------------------------------------------------
0781       std::string ToString()
0782       {
0783         return "VectorWrite";
0784       }
0785 
0786     protected:
0787 
0788       //------------------------------------------------------------------------
0789       //! RunImpl operation (@see Operation)
0790       //!
0791       //! @param params :  container with parameters forwarded from
0792       //!                  previous operation
0793       //! @return       :  status of the operation
0794       //------------------------------------------------------------------------
0795       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0796       {
0797         const ChunkList &chunks  = std::get<ChunksArg>( this->args ).Get();
0798         uint16_t         timeout = pipelineTimeout < this->timeout ?
0799                                    pipelineTimeout : this->timeout;
0800         return this->file->VectorWrite( chunks, handler, timeout );
0801       }
0802   };
0803 
0804   //----------------------------------------------------------------------------
0805   //! Factory for creating VectorWriteImpl objects
0806   //----------------------------------------------------------------------------
0807   inline VectorWriteImpl<false> VectorWrite( Ctx<File> file, Arg<ChunkList> chunks,
0808                                              uint16_t timeout = 0 )
0809   {
0810     return VectorWriteImpl<false>( std::move( file ), std::move( chunks ) ).Timeout( timeout );
0811   }
0812 
0813   //----------------------------------------------------------------------------
0814   //! WriteV operation (@see FileOperation)
0815   //----------------------------------------------------------------------------
0816   template<bool HasHndl>
0817   class WriteVImpl: public FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
0818                                          Arg<std::vector<iovec>>>
0819   {
0820     public:
0821 
0822       //------------------------------------------------------------------------
0823       //! Inherit constructors from FileOperation (@see FileOperation)
0824       //------------------------------------------------------------------------
0825       using FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
0826                           Arg<std::vector<iovec>>>::FileOperation;
0827 
0828       //------------------------------------------------------------------------
0829       //! Argument indexes in the args tuple
0830       //------------------------------------------------------------------------
0831       enum { OffsetArg, IovArg };
0832 
0833       //------------------------------------------------------------------------
0834       //! @return : name of the operation (@see Operation)
0835       //------------------------------------------------------------------------
0836       std::string ToString()
0837       {
0838         return "WriteV";
0839       }
0840 
0841     protected:
0842 
0843       //------------------------------------------------------------------------
0844       //! RunImpl operation (@see Operation)
0845       //!
0846       //! @param params :  container with parameters forwarded from
0847       //!                  previous operation
0848       //! @return       :  status of the operation
0849       //------------------------------------------------------------------------
0850       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0851       {
0852         uint64_t            offset  = std::get<OffsetArg>( this->args ).Get();
0853         std::vector<iovec> &stdiov  = std::get<IovArg>( this->args ).Get();
0854         uint16_t            timeout = pipelineTimeout < this->timeout ?
0855                                       pipelineTimeout : this->timeout;
0856 
0857         int iovcnt = stdiov.size();
0858         iovec iov[iovcnt];
0859         for( size_t i = 0; i < stdiov.size(); ++i )
0860         {
0861           iov[i].iov_base = stdiov[i].iov_base;
0862           iov[i].iov_len  = stdiov[i].iov_len;
0863         }
0864 
0865         return this->file->WriteV( offset, iov, iovcnt, handler, timeout );
0866       }
0867   };
0868 
0869   //----------------------------------------------------------------------------
0870   //! Factory for creating WriteVImpl objects
0871   //----------------------------------------------------------------------------
0872   inline WriteVImpl<false> WriteV( Ctx<File> file, Arg<uint64_t> offset,
0873                                    Arg<std::vector<iovec>> iov, uint16_t timeout = 0 )
0874   {
0875     return WriteVImpl<false>( std::move( file ), std::move( offset ),
0876                               std::move( iov ) ).Timeout( timeout );
0877   }
0878 
0879   //----------------------------------------------------------------------------
0880   //! Fcntl operation (@see FileOperation)
0881   //----------------------------------------------------------------------------
0882   template<bool HasHndl>
0883   class FcntlImpl: public FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>
0884   {
0885     public:
0886 
0887       //------------------------------------------------------------------------
0888       //! Inherit constructors from FileOperation (@see FileOperation)
0889       //------------------------------------------------------------------------
0890       using FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>::FileOperation;
0891 
0892       //------------------------------------------------------------------------
0893       //! Argument indexes in the args tuple
0894       //------------------------------------------------------------------------
0895       enum { BufferArg };
0896 
0897       //------------------------------------------------------------------------
0898       //! @return : name of the operation (@see Operation)
0899       //------------------------------------------------------------------------
0900       std::string ToString()
0901       {
0902         return "Fcntl";
0903       }
0904 
0905     protected:
0906 
0907       //------------------------------------------------------------------------
0908       //! RunImpl operation (@see Operation)
0909       //!
0910       //! @param params :  container with parameters forwarded from
0911       //!                  previous operation
0912       //! @return       :  status of the operation
0913       //------------------------------------------------------------------------
0914       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0915       {
0916         Buffer   &arg     = std::get<BufferArg>( this->args ).Get();
0917         uint16_t  timeout = pipelineTimeout < this->timeout ?
0918                             pipelineTimeout : this->timeout;
0919         return this->file->Fcntl( arg, handler, timeout );
0920       }
0921   };
0922   typedef FcntlImpl<false> Fcntl;
0923 
0924   //----------------------------------------------------------------------------
0925   //! Visa operation (@see FileOperation)
0926   //----------------------------------------------------------------------------
0927   template<bool HasHndl>
0928   class VisaImpl: public FileOperation<VisaImpl, HasHndl, Resp<Buffer>>
0929   {
0930     public:
0931 
0932       //------------------------------------------------------------------------
0933       //! Inherit constructors from FileOperation (@see FileOperation)
0934       //------------------------------------------------------------------------
0935       using FileOperation<VisaImpl, HasHndl, Resp<Buffer>>::FileOperation;
0936 
0937       //------------------------------------------------------------------------
0938       //! @return : name of the operation (@see Operation)
0939       //------------------------------------------------------------------------
0940       std::string ToString()
0941       {
0942         return "Visa";
0943       }
0944 
0945     protected:
0946 
0947       //------------------------------------------------------------------------
0948       //! RunImpl operation (@see Operation)
0949       //!
0950       //! @param params :  container with parameters forwarded from
0951       //!                  previous operation
0952       //! @return       :  status of the operation
0953       //------------------------------------------------------------------------
0954       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
0955       {
0956         uint16_t timeout = pipelineTimeout < this->timeout ?
0957                            pipelineTimeout : this->timeout;
0958         return this->file->Visa( handler, timeout );
0959       }
0960   };
0961   typedef VisaImpl<false> Visa;
0962 
0963   //----------------------------------------------------------------------------
0964   //! SetXAttr operation (@see FileOperation)
0965   //----------------------------------------------------------------------------
0966   template<bool HasHndl>
0967   class SetXAttrImpl: public FileOperation<SetXAttrImpl, HasHndl, Resp<void>,
0968       Arg<std::string>, Arg<std::string>>
0969   {
0970     public:
0971 
0972       //------------------------------------------------------------------------
0973       //! Inherit constructors from FileOperation (@see FileOperation)
0974       //------------------------------------------------------------------------
0975       using FileOperation<SetXAttrImpl, HasHndl, Resp<void>,
0976                           Arg<std::string>, Arg<std::string>>::FileOperation;
0977 
0978       //------------------------------------------------------------------------
0979       //! Argument indexes in the args tuple
0980       //------------------------------------------------------------------------
0981       enum { NameArg, ValueArg };
0982 
0983       //------------------------------------------------------------------------
0984       //! @return : name of the operation (@see Operation)
0985       //------------------------------------------------------------------------
0986       std::string ToString()
0987       {
0988         return "SetXAttrImpl";
0989       }
0990 
0991     protected:
0992 
0993       //------------------------------------------------------------------------
0994       //! RunImpl operation (@see Operation)
0995       //!
0996       //! @param params :  container with parameters forwarded from
0997       //!                  previous operation
0998       //! @return       :  status of the operation
0999       //------------------------------------------------------------------------
1000       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1001       {
1002         std::string &name  = std::get<NameArg>( this->args ).Get();
1003         std::string &value = std::get<ValueArg>( this->args ).Get();
1004         // wrap the arguments with a vector
1005         std::vector<xattr_t> attrs;
1006         attrs.push_back( xattr_t( name, value ) );
1007         // wrap the PipelineHandler so the response gets unpacked properly
1008         UnpackXAttrStatus *h = new UnpackXAttrStatus( handler );
1009         uint16_t     timeout = pipelineTimeout < this->timeout ?
1010                                      pipelineTimeout : this->timeout;
1011         XRootDStatus st = this->file->SetXAttr( attrs, h, timeout );
1012         if( !st.IsOK() ) delete h;
1013         return st;
1014       }
1015   };
1016 
1017   //----------------------------------------------------------------------------
1018   //! Factory for creating SetXAttrImpl objects (as there is another SetXAttr in
1019   //! FileSystem there would be a clash of typenames).
1020   //----------------------------------------------------------------------------
1021   inline SetXAttrImpl<false> SetXAttr( Ctx<File> file, Arg<std::string> name, Arg<std::string> value )
1022   {
1023     return SetXAttrImpl<false>( std::move( file ), std::move( name ), std::move( value ) );
1024   }
1025 
1026   //----------------------------------------------------------------------------
1027   //! SetXAttr bulk operation (@see FileOperation)
1028   //----------------------------------------------------------------------------
1029   template<bool HasHndl>
1030   class SetXAttrBulkImpl: public FileOperation<SetXAttrBulkImpl, HasHndl,
1031       Resp<std::vector<XAttrStatus>>, Arg<std::vector<xattr_t>>>
1032   {
1033     public:
1034 
1035       //------------------------------------------------------------------------
1036       //! Inherit constructors from FileOperation (@see FileOperation)
1037       //------------------------------------------------------------------------
1038       using FileOperation<SetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>,
1039                           Arg<std::vector<xattr_t>>>::FileOperation;
1040 
1041       //------------------------------------------------------------------------
1042       //! Argument indexes in the args tuple
1043       //------------------------------------------------------------------------
1044       enum { AttrsArg };
1045 
1046       //------------------------------------------------------------------------
1047       //! @return : name of the operation (@see Operation)
1048       //------------------------------------------------------------------------
1049       std::string ToString()
1050       {
1051         return "SetXAttrBulkImpl";
1052       }
1053 
1054 
1055     protected:
1056 
1057       //------------------------------------------------------------------------
1058       //! RunImpl operation (@see Operation)
1059       //!
1060       //! @param params :  container with parameters forwarded from
1061       //!                  previous operation
1062       //! @return       :  status of the operation
1063       //------------------------------------------------------------------------
1064       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1065       {
1066         std::vector<xattr_t> &attrs   = std::get<AttrsArg>( this->args ).Get();
1067         uint16_t              timeout = pipelineTimeout < this->timeout ?
1068                                         pipelineTimeout : this->timeout;
1069         return this->file->SetXAttr( attrs, handler, timeout );
1070       }
1071   };
1072 
1073   //----------------------------------------------------------------------------
1074   //! Factory for creating SetXAttrBulkImpl objects (as there is another SetXAttr
1075   //! in FileSystem there would be a clash of typenames).
1076   //----------------------------------------------------------------------------
1077   inline SetXAttrBulkImpl<false> SetXAttr( Ctx<File> file, Arg<std::vector<xattr_t>> attrs )
1078   {
1079     return SetXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) );
1080   }
1081 
1082   //----------------------------------------------------------------------------
1083   //! GetXAttr operation (@see FileOperation)
1084   //----------------------------------------------------------------------------
1085   template<bool HasHndl>
1086   class GetXAttrImpl: public FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>,
1087       Arg<std::string>>
1088   {
1089     public:
1090 
1091       //------------------------------------------------------------------------
1092       //! Inherit constructors from FileOperation (@see FileOperation)
1093       //------------------------------------------------------------------------
1094       using FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>,
1095                           Arg<std::string>>::FileOperation;
1096 
1097       //------------------------------------------------------------------------
1098       //! Argument indexes in the args tuple
1099       //------------------------------------------------------------------------
1100       enum { NameArg };
1101 
1102       //------------------------------------------------------------------------
1103       //! @return : name of the operation (@see Operation)
1104       //------------------------------------------------------------------------
1105       std::string ToString()
1106       {
1107         return "GetXAttrImpl";
1108       }
1109 
1110     protected:
1111 
1112       //------------------------------------------------------------------------
1113       //! RunImpl operation (@see Operation)
1114       //!
1115       //! @param params :  container with parameters forwarded from
1116       //!                  previous operation
1117       //! @return       :  status of the operation
1118       //------------------------------------------------------------------------
1119       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1120       {
1121         std::string &name = std::get<NameArg>( this->args ).Get();
1122         // wrap the argument with a vector
1123         std::vector<std::string> attrs;
1124         attrs.push_back( name );
1125         // wrap the PipelineHandler so the response gets unpacked properly
1126         UnpackXAttr   *h = new UnpackXAttr( handler );
1127         uint16_t timeout = pipelineTimeout < this->timeout ?
1128                            pipelineTimeout : this->timeout;
1129         XRootDStatus st = this->file->GetXAttr( attrs, h, timeout );
1130         if( !st.IsOK() ) delete h;
1131         return st;
1132       }
1133   };
1134 
1135   //----------------------------------------------------------------------------
1136   //! Factory for creating GetXAttrImpl objects (as there is another GetXAttr in
1137   //! FileSystem there would be a clash of typenames).
1138   //----------------------------------------------------------------------------
1139   inline GetXAttrImpl<false> GetXAttr( Ctx<File> file, Arg<std::string> name )
1140   {
1141     return GetXAttrImpl<false>( std::move( file ), std::move( name ) );
1142   }
1143 
1144   //----------------------------------------------------------------------------
1145   //! GetXAttr bulk operation (@see FileOperation)
1146   //----------------------------------------------------------------------------
1147   template<bool HasHndl>
1148   class GetXAttrBulkImpl: public FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>,
1149       Arg<std::vector<std::string>>>
1150   {
1151     public:
1152 
1153       //------------------------------------------------------------------------
1154       //! Inherit constructors from FileOperation (@see FileOperation)
1155       //------------------------------------------------------------------------
1156       using FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>,
1157                           Arg<std::vector<std::string>>>::FileOperation;
1158 
1159       //------------------------------------------------------------------------
1160       //! Argument indexes in the args tuple
1161       //------------------------------------------------------------------------
1162       enum { NamesArg };
1163 
1164       //------------------------------------------------------------------------
1165       //! @return : name of the operation (@see Operation)
1166       //------------------------------------------------------------------------
1167       std::string ToString()
1168       {
1169         return "GetXAttrBulkImpl";
1170       }
1171 
1172 
1173     protected:
1174 
1175       //------------------------------------------------------------------------
1176       //! RunImpl operation (@see Operation)
1177       //!
1178       //! @param params :  container with parameters forwarded from
1179       //!                  previous operation
1180       //! @return       :  status of the operation
1181       //------------------------------------------------------------------------
1182       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1183       {
1184         std::vector<std::string> &attrs   = std::get<NamesArg>( this->args ).Get();
1185         uint16_t                  timeout = pipelineTimeout < this->timeout ?
1186                                             pipelineTimeout : this->timeout;
1187         return this->file->GetXAttr( attrs, handler, timeout );
1188       }
1189   };
1190 
1191   //----------------------------------------------------------------------------
1192   //! Factory for creating GetXAttrBulkImpl objects (as there is another GetXAttr in
1193   //! FileSystem there would be a clash of typenames).
1194   //----------------------------------------------------------------------------
1195   inline GetXAttrBulkImpl<false> GetXAttr( Ctx<File> file, Arg<std::vector<std::string>> attrs )
1196   {
1197     return GetXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) );
1198   }
1199 
1200   //----------------------------------------------------------------------------
1201   //! DelXAttr operation (@see FileOperation)
1202   //----------------------------------------------------------------------------
1203   template<bool HasHndl>
1204   class DelXAttrImpl: public FileOperation<DelXAttrImpl, HasHndl, Resp<void>,
1205       Arg<std::string>>
1206   {
1207     public:
1208 
1209       //------------------------------------------------------------------------
1210       //! Inherit constructors from FileOperation (@see FileOperation)
1211       //------------------------------------------------------------------------
1212       using FileOperation<DelXAttrImpl, HasHndl, Resp<void>, Arg<std::string>>::FileOperation;
1213 
1214       //------------------------------------------------------------------------
1215       //! Argument indexes in the args tuple
1216       //------------------------------------------------------------------------
1217       enum { NameArg };
1218 
1219       //------------------------------------------------------------------------
1220       //! @return : name of the operation (@see Operation)
1221       //------------------------------------------------------------------------
1222       std::string ToString()
1223       {
1224         return "DelXAttrImpl";
1225       }
1226 
1227     protected:
1228 
1229       //------------------------------------------------------------------------
1230       //! RunImpl operation (@see Operation)
1231       //!
1232       //! @param params :  container with parameters forwarded from
1233       //!                  previous operation
1234       //! @return       :  status of the operation
1235       //------------------------------------------------------------------------
1236       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1237       {
1238         std::string &name = std::get<NameArg>( this->args ).Get();
1239         // wrap the argument with a vector
1240         std::vector<std::string> attrs;
1241         attrs.push_back( name );
1242         // wrap the PipelineHandler so the response gets unpacked properly
1243         UnpackXAttrStatus *h = new UnpackXAttrStatus( handler );
1244         uint16_t     timeout = pipelineTimeout < this->timeout ?
1245                                pipelineTimeout : this->timeout;
1246         XRootDStatus st = this->file->DelXAttr( attrs, h, timeout );
1247         if( !st.IsOK() ) delete h;
1248         return st;
1249       }
1250   };
1251 
1252   //----------------------------------------------------------------------------
1253   //! Factory for creating DelXAttrImpl objects (as there is another DelXAttr in
1254   //! FileSystem there would be a clash of typenames).
1255   //----------------------------------------------------------------------------
1256   inline DelXAttrImpl<false> DelXAttr( Ctx<File> file, Arg<std::string> name )
1257   {
1258     return DelXAttrImpl<false>( std::move( file ), std::move( name ) );
1259   }
1260 
1261   //----------------------------------------------------------------------------
1262   //! DelXAttr bulk operation (@see FileOperation)
1263   //----------------------------------------------------------------------------
1264   template<bool HasHndl>
1265   class DelXAttrBulkImpl: public FileOperation<DelXAttrBulkImpl, HasHndl,
1266       Resp<std::vector<XAttrStatus>>, Arg<std::vector<std::string>>>
1267   {
1268     public:
1269 
1270       //------------------------------------------------------------------------
1271       //! Inherit constructors from FileOperation (@see FileOperation)
1272       //------------------------------------------------------------------------
1273       using FileOperation<DelXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>,
1274                           Arg<std::vector<std::string>>>::FileOperation;
1275 
1276       //------------------------------------------------------------------------
1277       //! Argument indexes in the args tuple
1278       //------------------------------------------------------------------------
1279       enum { NamesArg };
1280 
1281       //------------------------------------------------------------------------
1282       //! @return : name of the operation (@see Operation)
1283       //------------------------------------------------------------------------
1284       std::string ToString()
1285       {
1286         return "DelXAttrBulkImpl";
1287       }
1288 
1289 
1290     protected:
1291 
1292       //------------------------------------------------------------------------
1293       //! RunImpl operation (@see Operation)
1294       //!
1295       //! @param params :  container with parameters forwarded from
1296       //!                  previous operation
1297       //! @return       :  status of the operation
1298       //------------------------------------------------------------------------
1299       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1300       {
1301         std::vector<std::string> &attrs   = std::get<NamesArg>( this->args ).Get();
1302         uint16_t                  timeout = pipelineTimeout < this->timeout ?
1303                                             pipelineTimeout : this->timeout;
1304         return this->file->DelXAttr( attrs, handler, timeout );
1305       }
1306   };
1307 
1308   //----------------------------------------------------------------------------
1309   //! Factory for creating DelXAttrBulkImpl objects (as there is another DelXAttr
1310   //! in FileSystem there would be a clash of typenames).
1311   //----------------------------------------------------------------------------
1312   inline DelXAttrBulkImpl<false> DelXAttr( Ctx<File> file, Arg<std::vector<std::string>> attrs )
1313   {
1314     return DelXAttrBulkImpl<false>( std::move( file ), std::move( attrs ) );
1315   }
1316 
1317   //----------------------------------------------------------------------------
1318   //! ListXAttr bulk operation (@see FileOperation)
1319   //----------------------------------------------------------------------------
1320   template<bool HasHndl>
1321   class ListXAttrImpl: public FileOperation<ListXAttrImpl, HasHndl,
1322       Resp<std::vector<XAttr>>>
1323   {
1324     public:
1325 
1326       //------------------------------------------------------------------------
1327       //! Inherit constructors from FileOperation (@see FileOperation)
1328       //------------------------------------------------------------------------
1329       using FileOperation<ListXAttrImpl, HasHndl, Resp<std::vector<XAttr>>>::FileOperation;
1330 
1331       //------------------------------------------------------------------------
1332       //! @return : name of the operation (@see Operation)
1333       //------------------------------------------------------------------------
1334       std::string ToString()
1335       {
1336         return "ListXAttrImpl";
1337       }
1338 
1339 
1340     protected:
1341 
1342       //------------------------------------------------------------------------
1343       //! RunImpl operation (@see Operation)
1344       //!
1345       //! @param params :  container with parameters forwarded from
1346       //!                  previous operation
1347       //! @return       :  status of the operation
1348       //------------------------------------------------------------------------
1349       XRootDStatus RunImpl( PipelineHandler *handler, uint16_t pipelineTimeout )
1350       {
1351         uint16_t timeout = pipelineTimeout < this->timeout ?
1352                            pipelineTimeout : this->timeout;
1353         return this->file->ListXAttr( handler, timeout );
1354       }
1355   };
1356 
1357   //----------------------------------------------------------------------------
1358   //! Factory for creating ListXAttrImpl objects (as there is another ListXAttr
1359   //! in FileSystem there would be a clash of typenames).
1360   //----------------------------------------------------------------------------
1361   inline ListXAttrImpl<false> ListXAttr( Ctx<File> file )
1362   {
1363     return ListXAttrImpl<false>( std::move( file ) );
1364   }
1365 }
1366 
1367 #endif // __XRD_CL_FILE_OPERATIONS_HH__
1368