00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef __XRD_CL_FILE_OPERATIONS_HH__
00027 #define __XRD_CL_FILE_OPERATIONS_HH__
00028
00029 #include "XrdCl/XrdClFile.hh"
00030 #include "XrdCl/XrdClOperations.hh"
00031 #include "XrdCl/XrdClOperationHandlers.hh"
00032
00033 namespace XrdCl
00034 {
00035
00036
00042
00043 template<template<bool> class Derived, bool HasHndl, typename Response, typename ... Arguments>
00044 class FileOperation: public ConcreteOperation<Derived, HasHndl, Response, Arguments...>
00045 {
00046
00047 template<template<bool> class, bool, typename, typename ...> friend class FileOperation;
00048
00049 public:
00050
00055
00056 FileOperation( File *f, Arguments... args): ConcreteOperation<Derived, false, Response, Arguments...>( std::move( args )... ), file(f)
00057 {
00058 }
00059
00060
00065
00066 FileOperation( File &f, Arguments... args): FileOperation( &f, std::move( args )... )
00067 {
00068 }
00069
00070
00076
00077 template<bool from>
00078 FileOperation( FileOperation<Derived, from, Response, Arguments...> && op ) :
00079 ConcreteOperation<Derived, HasHndl, Response, Arguments...>( std::move( op ) ), file( op.file )
00080 {
00081
00082 }
00083
00084
00086
00087 virtual ~FileOperation()
00088 {
00089
00090 }
00091
00092 protected:
00093
00094
00096
00097 File *file;
00098 };
00099
00100
00102
00103 template<bool HasHndl>
00104 class OpenImpl: public FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>,
00105 Arg<OpenFlags::Flags>, Arg<Access::Mode>>
00106 {
00107
00113
00114 struct ExResp : public Resp<void>
00115 {
00116
00120
00121 ExResp( XrdCl::File &file ): file( file )
00122 {
00123 }
00124
00125
00130
00131 inline ResponseHandler* Create( std::function<void( XRootDStatus&,
00132 StatInfo& )> func )
00133 {
00134 return make_finalized( new ExOpenFuncWrapper( this->file, func ) );
00135 }
00136
00137
00139
00140 using Resp<void>::Create;
00141
00142
00144
00145 XrdCl::File &file;
00146 };
00147
00148 public:
00149
00150
00152
00153 OpenImpl( File *f, Arg<std::string> url, Arg<OpenFlags::Flags> flags,
00154 Arg<Access::Mode> mode = Access::None ) :
00155 FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>,
00156 Arg<Access::Mode>>( f, std::move( url ), std::move( flags ), std::move( mode ) )
00157 {
00158 }
00159
00160
00162
00163 OpenImpl( File &f, Arg<std::string> url, Arg<OpenFlags::Flags> flags,
00164 Arg<Access::Mode> mode = Access::None ) :
00165 FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>, Arg<OpenFlags::Flags>,
00166 Arg<Access::Mode>>( &f, std::move( url ), std::move( flags ), std::move( mode ) )
00167 {
00168 }
00169
00170
00176
00177 template<bool from>
00178 OpenImpl( OpenImpl<from> && open ) :
00179 FileOperation<OpenImpl, HasHndl, Resp<void>, Arg<std::string>,
00180 Arg<OpenFlags::Flags>, Arg<Access::Mode>>( std::move( open ) )
00181 {
00182 }
00183
00184
00185
00187
00188 enum { UrlArg, FlagsArg, ModeArg };
00189
00190
00195
00196 template<typename Hdlr>
00197 OpenImpl<true> operator>>( Hdlr &&hdlr )
00198 {
00199 ExResp factory( *this->file );
00200 return this->StreamImpl( factory.Create( hdlr ) );
00201 }
00202
00203
00205
00206 std::string ToString()
00207 {
00208 return "Open";
00209 }
00210
00211 protected:
00212
00213
00219
00220 XRootDStatus RunImpl()
00221 {
00222 try
00223 {
00224 std::string url = std::get<UrlArg>( this->args ).Get();
00225 OpenFlags::Flags flags = std::get<FlagsArg>( this->args ).Get();
00226 Access::Mode mode = std::get<ModeArg>( this->args ).Get();
00227 return this->file->Open( url, flags, mode, this->handler.get() );
00228 }
00229 catch( const PipelineException& ex )
00230 {
00231 return ex.GetError();
00232 }
00233 catch( const std::exception& ex )
00234 {
00235 return XRootDStatus( stError, ex.what() );
00236 }
00237 }
00238 };
00239 typedef OpenImpl<false> Open;
00240
00241
00243
00244 template<bool HasHndl>
00245 class ReadImpl: public FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>,
00246 Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>
00247 {
00248 public:
00249
00250
00252
00253 using FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>, Arg<uint64_t>,
00254 Arg<uint32_t>, Arg<void*>>::FileOperation;
00255
00256
00258
00259 enum { OffsetArg, SizeArg, BufferArg };
00260
00261
00263
00264 std::string ToString()
00265 {
00266 return "Read";
00267 }
00268
00269 protected:
00270
00271
00277
00278 XRootDStatus RunImpl()
00279 {
00280 try
00281 {
00282 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00283 uint32_t size = std::get<SizeArg>( this->args ).Get();
00284 void *buffer = std::get<BufferArg>( this->args ).Get();
00285 return this->file->Read( offset, size, buffer, this->handler.get() );
00286 }
00287 catch( const PipelineException& ex )
00288 {
00289 return ex.GetError();
00290 }
00291 catch( const std::exception& ex )
00292 {
00293 return XRootDStatus( stError, ex.what() );
00294 }
00295 }
00296 };
00297 typedef ReadImpl<false> Read;
00298
00299
00301
00302 template<bool HasHndl>
00303 class CloseImpl: public FileOperation<CloseImpl, HasHndl, Resp<void>>
00304 {
00305 public:
00306
00307
00309
00310 using FileOperation<CloseImpl, HasHndl, Resp<void>>::FileOperation;
00311
00312
00314
00315 std::string ToString()
00316 {
00317 return "Close";
00318 }
00319
00320 protected:
00321
00322
00328
00329 XRootDStatus RunImpl()
00330 {
00331 return this->file->Close( this->handler.get() );
00332 }
00333 };
00334 typedef CloseImpl<false> Close;
00335
00336
00338
00339 template<bool HasHndl>
00340 class StatImpl: public FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>
00341 {
00342 public:
00343
00344
00346
00347 using FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>::FileOperation;
00348
00349
00351
00352 enum { ForceArg };
00353
00354
00356
00357 std::string ToString()
00358 {
00359 return "Stat";
00360 }
00361
00362 protected:
00363
00364
00370
00371 XRootDStatus RunImpl()
00372 {
00373 try
00374 {
00375 bool force = std::get<ForceArg>( this->args ).Get();
00376 return this->file->Stat( force, this->handler.get() );
00377 }
00378 catch( const PipelineException& ex )
00379 {
00380 return ex.GetError();
00381 }
00382 catch( const std::exception& ex )
00383 {
00384 return XRootDStatus( stError, ex.what() );
00385 }
00386 }
00387 };
00388
00389
00392
00393 inline StatImpl<false> Stat( File *file, Arg<bool> force )
00394 {
00395 return StatImpl<false>( file, std::move( force ) );
00396 }
00397
00398
00401
00402 inline StatImpl<false> Stat( File &file, Arg<bool> force )
00403 {
00404 return StatImpl<false>( file, std::move( force ) );
00405 }
00406
00407
00409
00410 template<bool HasHndl>
00411 class WriteImpl: public FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00412 Arg<uint32_t>, Arg<void*>>
00413 {
00414 public:
00415
00416
00418
00419 using FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>,
00420 Arg<void*>>::FileOperation;
00421
00422
00424
00425 enum { OffsetArg, SizeArg, BufferArg };
00426
00427
00429
00430 std::string ToString()
00431 {
00432 return "Write";
00433 }
00434
00435 protected:
00436
00437
00443
00444 XRootDStatus RunImpl()
00445 {
00446 try
00447 {
00448 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00449 uint32_t size = std::get<SizeArg>( this->args ).Get();
00450 void *buffer = std::get<BufferArg>( this->args ).Get();
00451 return this->file->Write( offset, size, buffer, this->handler.get() );
00452 }
00453 catch( const PipelineException& ex )
00454 {
00455 return ex.GetError();
00456 }
00457 catch( const std::exception& ex )
00458 {
00459 return XRootDStatus( stError, ex.what() );
00460 }
00461 }
00462 };
00463 typedef WriteImpl<false> Write;
00464
00465
00467
00468 template<bool HasHndl>
00469 class SyncImpl: public FileOperation<SyncImpl, HasHndl, Resp<void>>
00470 {
00471 public:
00472
00473
00475
00476 using FileOperation<SyncImpl, HasHndl, Resp<void>>::FileOperation;
00477
00478
00480
00481 std::string ToString()
00482 {
00483 return "Sync";
00484 }
00485
00486 protected:
00487
00488
00494
00495 XRootDStatus RunImpl()
00496 {
00497 return this->file->Sync( this->handler.get() );
00498 }
00499 };
00500 typedef SyncImpl<false> Sync;
00501
00502
00504
00505 template<bool HasHndl>
00506 class TruncateImpl: public FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>
00507 {
00508 public:
00509
00510
00512
00513 using FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>::FileOperation;
00514
00515
00517
00518 enum { SizeArg };
00519
00520
00522
00523 std::string ToString()
00524 {
00525 return "Truncate";
00526 }
00527
00528 protected:
00529
00530
00536
00537 XRootDStatus RunImpl()
00538 {
00539 try
00540 {
00541 uint64_t size = std::get<SizeArg>( this->args ).Get();
00542 return this->file->Truncate( size, this->handler.get() );
00543 }
00544 catch( const PipelineException& ex )
00545 {
00546 return ex.GetError();
00547 }
00548 catch( const std::exception& ex )
00549 {
00550 return XRootDStatus( stError, ex.what() );
00551 }
00552 }
00553 };
00554
00555
00558
00559 inline TruncateImpl<false> Truncate( File *file, Arg<uint64_t> size )
00560 {
00561 return TruncateImpl<false>( file, std::move( size ) );
00562 }
00563
00564
00567
00568 inline TruncateImpl<false> Truncate( File &file, Arg<uint64_t> size )
00569 {
00570 return TruncateImpl<false>( file, std::move( size ) );
00571 }
00572
00573
00575
00576 template<bool HasHndl>
00577 class VectorReadImpl: public FileOperation<VectorReadImpl, HasHndl,
00578 Resp<VectorReadInfo>, Arg<ChunkList>, Arg<void*>>
00579 {
00580 public:
00581
00582
00584
00585 using FileOperation<VectorReadImpl, HasHndl, Resp<VectorReadInfo>, Arg<ChunkList>,
00586 Arg<void*>>::FileOperation;
00587
00588
00590
00591 enum { ChunksArg, BufferArg };
00592
00593
00595
00596 std::string ToString()
00597 {
00598 return "VectorRead";
00599 }
00600
00601 protected:
00602
00603
00609
00610 XRootDStatus RunImpl()
00611 {
00612 try
00613 {
00614 ChunkList chunks( std::get<ChunksArg>( this->args ).Get() );
00615 void *buffer = std::get<BufferArg>( this->args ).Get();
00616 return this->file->VectorRead( chunks, buffer, this->handler.get() );
00617 }
00618 catch( const PipelineException& ex )
00619 {
00620 return ex.GetError();
00621 }
00622 catch( const std::exception& ex )
00623 {
00624 return XRootDStatus( stError, ex.what() );
00625 }
00626 }
00627 };
00628 typedef VectorReadImpl<false> VectorRead;
00629
00630
00632
00633 template<bool HasHndl>
00634 class VectorWriteImpl: public FileOperation<VectorWriteImpl, HasHndl, Resp<void>,
00635 Arg<ChunkList>>
00636 {
00637 public:
00638
00639
00641
00642 using FileOperation<VectorWriteImpl, HasHndl, Resp<void>, Arg<ChunkList>>::FileOperation;
00643
00644
00646
00647 enum { ChunksArg };
00648
00649
00651
00652 std::string ToString()
00653 {
00654 return "VectorWrite";
00655 }
00656
00657 protected:
00658
00659
00665
00666 XRootDStatus RunImpl()
00667 {
00668 try
00669 {
00670 const ChunkList chunks( std::get<ChunksArg>( this->args ).Get() );
00671 return this->file->VectorWrite( chunks, this->handler.get() );
00672 }
00673 catch( const PipelineException& ex )
00674 {
00675 return ex.GetError();
00676 }
00677 catch( const std::exception& ex )
00678 {
00679 return XRootDStatus( stError, ex.what() );
00680 }
00681 }
00682 };
00683 typedef VectorWriteImpl<false> VectorWrite;
00684
00685
00687
00688 template<bool HasHndl>
00689 class WriteVImpl: public FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00690 Arg<struct iovec*>, Arg<int>>
00691 {
00692 public:
00693
00694
00696
00697 using FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00698 Arg<struct iovec*>, Arg<int>>::FileOperation;
00699
00700
00702
00703 enum { OffsetArg, IovArg, IovcntArg };
00704
00705
00707
00708 std::string ToString()
00709 {
00710 return "WriteV";
00711 }
00712
00713 protected:
00714
00715
00721
00722 XRootDStatus RunImpl()
00723 {
00724 try
00725 {
00726 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00727 const struct iovec *iov = std::get<IovArg>( this->args ).Get();
00728 int iovcnt = std::get<IovcntArg>( this->args ).Get();
00729 return this->file->WriteV( offset, iov, iovcnt, this->handler.get() );
00730 }
00731 catch( const PipelineException& ex )
00732 {
00733 return ex.GetError();
00734 }
00735 catch( const std::exception& ex )
00736 {
00737 return XRootDStatus( stError, ex.what() );
00738 }
00739 }
00740 };
00741 typedef WriteVImpl<false> WriteV;
00742
00743
00745
00746 template<bool HasHndl>
00747 class FcntlImpl: public FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>
00748 {
00749 public:
00750
00751
00753
00754 using FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>::FileOperation;
00755
00756
00758
00759 enum { BufferArg };
00760
00761
00763
00764 std::string ToString()
00765 {
00766 return "Fcntl";
00767 }
00768
00769 protected:
00770
00771
00777
00778 XRootDStatus RunImpl()
00779 {
00780 try
00781 {
00782 Buffer arg( std::get<BufferArg>( this->args ).Get() );
00783 return this->file->Fcntl( arg, this->handler.get() );
00784 }
00785 catch( const PipelineException& ex )
00786 {
00787 return ex.GetError();
00788 }
00789 catch( const std::exception& ex )
00790 {
00791 return XRootDStatus( stError, ex.what() );
00792 }
00793 }
00794 };
00795 typedef FcntlImpl<false> Fcntl;
00796
00797
00799
00800 template<bool HasHndl>
00801 class VisaImpl: public FileOperation<VisaImpl, HasHndl, Resp<Buffer>>
00802 {
00803 public:
00804
00805
00807
00808 using FileOperation<VisaImpl, HasHndl, Resp<Buffer>>::FileOperation;
00809
00810
00812
00813 std::string ToString()
00814 {
00815 return "Visa";
00816 }
00817
00818 protected:
00819
00820
00826
00827 XRootDStatus RunImpl()
00828 {
00829 return this->file->Visa( this->handler.get() );
00830 }
00831 };
00832 typedef VisaImpl<false> Visa;
00833
00834
00836
00837 template<bool HasHndl>
00838 class SetXAttrImpl: public FileOperation<SetXAttrImpl, HasHndl, Resp<void>,
00839 Arg<std::string>, Arg<std::string>>
00840 {
00841 public:
00842
00843
00845
00846 using FileOperation<SetXAttrImpl, HasHndl, Resp<void>,
00847 Arg<std::string>, Arg<std::string>>::FileOperation;
00848
00849
00851
00852 enum { NameArg, ValueArg };
00853
00854
00856
00857 std::string ToString()
00858 {
00859 return "SetXAttrImpl";
00860 }
00861
00862 protected:
00863
00864
00870
00871 XRootDStatus RunImpl()
00872 {
00873 try
00874 {
00875 std::string name = std::get<NameArg>( this->args ).Get();
00876 std::string value = std::get<ValueArg>( this->args ).Get();
00877
00878 std::vector<xattr_t> attrs;
00879 attrs.push_back( xattr_t( std::move( name ), std::move( value ) ) );
00880
00881 UnpackXAttrStatus *handler = new UnpackXAttrStatus( this->handler.get() );
00882 XRootDStatus st = this->file->SetXAttr( attrs, handler );
00883 if( !st.IsOK() ) delete handler;
00884 return st;
00885 }
00886 catch( const PipelineException& ex )
00887 {
00888 return ex.GetError();
00889 }
00890 catch( const std::exception& ex )
00891 {
00892 return XRootDStatus( stError, ex.what() );
00893 }
00894 }
00895 };
00896
00897
00900
00901 inline SetXAttrImpl<false> SetXAttr( File *file, Arg<std::string> name, Arg<std::string> value )
00902 {
00903 return SetXAttrImpl<false>( file, std::move( name ), std::move( value ) );
00904 }
00905
00906
00909
00910 inline SetXAttrImpl<false> SetXAttr( File &file, Arg<std::string> name, Arg<std::string> value )
00911 {
00912 return SetXAttrImpl<false>( file, std::move( name ), std::move( value ) );
00913 }
00914
00915
00917
00918 template<bool HasHndl>
00919 class SetXAttrBulkImpl: public FileOperation<SetXAttrBulkImpl, HasHndl,
00920 Resp<std::vector<XAttrStatus>>, Arg<std::vector<xattr_t>>>
00921 {
00922 public:
00923
00924
00926
00927 using FileOperation<SetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>,
00928 Arg<std::vector<xattr_t>>>::FileOperation;
00929
00930
00932
00933 enum { AttrsArg };
00934
00935
00937
00938 std::string ToString()
00939 {
00940 return "SetXAttrBulkImpl";
00941 }
00942
00943
00944 protected:
00945
00946
00952
00953 XRootDStatus RunImpl()
00954 {
00955 try
00956 {
00957 std::vector<xattr_t> attrs = std::get<AttrsArg>( this->args ).Get();
00958 return this->file->SetXAttr( attrs, this->handler.get() );
00959 }
00960 catch( const PipelineException& ex )
00961 {
00962 return ex.GetError();
00963 }
00964 catch( const std::exception& ex )
00965 {
00966 return XRootDStatus( stError, ex.what() );
00967 }
00968 }
00969 };
00970
00971
00974
00975 inline SetXAttrBulkImpl<false> SetXAttr( File *file, Arg<std::vector<xattr_t>> attrs )
00976 {
00977 return SetXAttrBulkImpl<false>( file, std::move( attrs ) );
00978 }
00979
00980
00983
00984 inline SetXAttrBulkImpl<false> SetXAttr( File &file, Arg<std::vector<xattr_t>> attrs )
00985 {
00986 return SetXAttrBulkImpl<false>( file, std::move( attrs ) );
00987 }
00988
00989
00991
00992 template<bool HasHndl>
00993 class GetXAttrImpl: public FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>,
00994 Arg<std::string>>
00995 {
00996 public:
00997
00998
01000
01001 using FileOperation<GetXAttrImpl, HasHndl, Resp<std::string>,
01002 Arg<std::string>>::FileOperation;
01003
01004
01006
01007 enum { NameArg };
01008
01009
01011
01012 std::string ToString()
01013 {
01014 return "GetXAttrImpl";
01015 }
01016
01017 protected:
01018
01019
01025
01026 XRootDStatus RunImpl()
01027 {
01028 try
01029 {
01030 std::string name = std::get<NameArg>( this->args ).Get();
01031
01032 std::vector<std::string> attrs;
01033 attrs.push_back( std::move( name ) );
01034
01035 UnpackXAttr *handler = new UnpackXAttr( this->handler.get() );
01036 XRootDStatus st = this->file->GetXAttr( attrs, handler );
01037 if( !st.IsOK() ) delete handler;
01038 return st;
01039 }
01040 catch( const PipelineException& ex )
01041 {
01042 return ex.GetError();
01043 }
01044 catch( const std::exception& ex )
01045 {
01046 return XRootDStatus( stError, ex.what() );
01047 }
01048 }
01049 };
01050
01051
01054
01055 inline GetXAttrImpl<false> GetXAttr( File *file, Arg<std::string> name )
01056 {
01057 return GetXAttrImpl<false>( file, std::move( name ) );
01058 }
01059
01060
01063
01064 inline GetXAttrImpl<false> GetXAttr( File &file, Arg<std::string> name )
01065 {
01066 return GetXAttrImpl<false>( file, std::move( name ) );
01067 }
01068
01069
01071
01072 template<bool HasHndl>
01073 class GetXAttrBulkImpl: public FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>,
01074 Arg<std::vector<std::string>>>
01075 {
01076 public:
01077
01078
01080
01081 using FileOperation<GetXAttrBulkImpl, HasHndl, Resp<std::vector<XAttr>>,
01082 Arg<std::vector<std::string>>>::FileOperation;
01083
01084
01086
01087 enum { NamesArg };
01088
01089
01091
01092 std::string ToString()
01093 {
01094 return "GetXAttrBulkImpl";
01095 }
01096
01097
01098 protected:
01099
01100
01106
01107 XRootDStatus RunImpl()
01108 {
01109 try
01110 {
01111 std::vector<std::string> attrs = std::get<NamesArg>( this->args ).Get();
01112 return this->file->GetXAttr( attrs, this->handler.get() );
01113 }
01114 catch( const PipelineException& ex )
01115 {
01116 return ex.GetError();
01117 }
01118 catch( const std::exception& ex )
01119 {
01120 return XRootDStatus( stError, ex.what() );
01121 }
01122 }
01123 };
01124
01125
01128
01129 inline GetXAttrBulkImpl<false> GetXAttr( File *file, Arg<std::vector<std::string>> attrs )
01130 {
01131 return GetXAttrBulkImpl<false>( file, std::move( attrs ) );
01132 }
01133
01134
01137
01138 inline GetXAttrBulkImpl<false> GetXAttr( File &file, Arg<std::vector<std::string>> attrs )
01139 {
01140 return GetXAttrBulkImpl<false>( file, std::move( attrs ) );
01141 }
01142
01143
01145
01146 template<bool HasHndl>
01147 class DelXAttrImpl: public FileOperation<DelXAttrImpl, HasHndl, Resp<void>,
01148 Arg<std::string>>
01149 {
01150 public:
01151
01152
01154
01155 using FileOperation<DelXAttrImpl, HasHndl, Resp<void>, Arg<std::string>>::FileOperation;
01156
01157
01159
01160 enum { NameArg };
01161
01162
01164
01165 std::string ToString()
01166 {
01167 return "DelXAttrImpl";
01168 }
01169
01170 protected:
01171
01172
01178
01179 XRootDStatus RunImpl()
01180 {
01181 try
01182 {
01183 std::string name = std::get<NameArg>( this->args ).Get();
01184
01185 std::vector<std::string> attrs;
01186 attrs.push_back( std::move( name ) );
01187
01188 UnpackXAttrStatus *handler = new UnpackXAttrStatus( this->handler.get() );
01189 XRootDStatus st = this->file->DelXAttr( attrs, handler );
01190 if( !st.IsOK() ) delete handler;
01191 return st;
01192 }
01193 catch( const PipelineException& ex )
01194 {
01195 return ex.GetError();
01196 }
01197 catch( const std::exception& ex )
01198 {
01199 return XRootDStatus( stError, ex.what() );
01200 }
01201 }
01202 };
01203
01204
01207
01208 inline DelXAttrImpl<false> DelXAttr( File *file, Arg<std::string> name )
01209 {
01210 return DelXAttrImpl<false>( file, std::move( name ) );
01211 }
01212
01213
01216
01217 inline DelXAttrImpl<false> DelXAttr( File &file, Arg<std::string> name )
01218 {
01219 return DelXAttrImpl<false>( file, std::move( name ) );
01220 }
01221
01222
01224
01225 template<bool HasHndl>
01226 class DelXAttrBulkImpl: public FileOperation<DelXAttrBulkImpl, HasHndl,
01227 Resp<std::vector<XAttrStatus>>, Arg<std::vector<std::string>>>
01228 {
01229 public:
01230
01231
01233
01234 using FileOperation<DelXAttrBulkImpl, HasHndl, Resp<std::vector<XAttrStatus>>,
01235 Arg<std::vector<std::string>>>::FileOperation;
01236
01237
01239
01240 enum { NamesArg };
01241
01242
01244
01245 std::string ToString()
01246 {
01247 return "DelXAttrBulkImpl";
01248 }
01249
01250
01251 protected:
01252
01253
01259
01260 XRootDStatus RunImpl()
01261 {
01262 try
01263 {
01264 std::vector<std::string> attrs = std::get<NamesArg>( this->args ).Get();
01265 return this->file->DelXAttr( attrs, this->handler.get() );
01266 }
01267 catch( const PipelineException& ex )
01268 {
01269 return ex.GetError();
01270 }
01271 catch( const std::exception& ex )
01272 {
01273 return XRootDStatus( stError, ex.what() );
01274 }
01275 }
01276 };
01277
01278
01281
01282 inline DelXAttrBulkImpl<false> DelXAttr( File *file, Arg<std::vector<std::string>> attrs )
01283 {
01284 return DelXAttrBulkImpl<false>( file, std::move( attrs ) );
01285 }
01286
01287
01290
01291 inline DelXAttrBulkImpl<false> DelXAttr( File &file, Arg<std::vector<std::string>> attrs )
01292 {
01293 return DelXAttrBulkImpl<false>( file, std::move( attrs ) );
01294 }
01295
01296
01298
01299 template<bool HasHndl>
01300 class ListXAttrImpl: public FileOperation<ListXAttrImpl, HasHndl,
01301 Resp<std::vector<XAttr>>>
01302 {
01303 public:
01304
01305
01307
01308 using FileOperation<ListXAttrImpl, HasHndl, Resp<std::vector<XAttr>>>::FileOperation;
01309
01310
01312
01313 std::string ToString()
01314 {
01315 return "ListXAttrImpl";
01316 }
01317
01318
01319 protected:
01320
01321
01327
01328 XRootDStatus RunImpl()
01329 {
01330 return this->file->ListXAttr( this->handler.get() );
01331 }
01332 };
01333
01334
01337
01338 inline ListXAttrImpl<false> ListXAttr( File *file )
01339 {
01340 return ListXAttrImpl<false>( file );
01341 }
01342
01343
01346
01347 inline ListXAttrImpl<false> ListXAttr( File &file )
01348 {
01349 return ListXAttrImpl<false>( file );
01350 }
01351 }
01352
01353 #endif // __XRD_CL_FILE_OPERATIONS_HH__
01354