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 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
00200
00201
00202
00203 constexpr bool own = !IsResponseHandler<Hdlr>::value;
00204 ExResp factory( *this->file );
00205 return this->StreamImpl( factory.Create( hdlr ), own );
00206 }
00207
00208
00210
00211 std::string ToString()
00212 {
00213 return "Open";
00214 }
00215
00216 protected:
00217
00218
00224
00225 XRootDStatus RunImpl()
00226 {
00227 try
00228 {
00229 std::string url = std::get<UrlArg>( this->args ).Get();
00230 OpenFlags::Flags flags = std::get<FlagsArg>( this->args ).Get();
00231 Access::Mode mode = std::get<ModeArg>( this->args ).Get();
00232 return this->file->Open( url, flags, mode, this->handler.get() );
00233 }
00234 catch( const PipelineException& ex )
00235 {
00236 return ex.GetError();
00237 }
00238 catch( const std::exception& ex )
00239 {
00240 return XRootDStatus( stError, ex.what() );
00241 }
00242 }
00243 };
00244 typedef OpenImpl<false> Open;
00245
00246
00248
00249 template<bool HasHndl>
00250 class ReadImpl: public FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>,
00251 Arg<uint64_t>, Arg<uint32_t>, Arg<void*>>
00252 {
00253 public:
00254
00255
00257
00258 using FileOperation<ReadImpl, HasHndl, Resp<ChunkInfo>, Arg<uint64_t>,
00259 Arg<uint32_t>, Arg<void*>>::FileOperation;
00260
00261
00263
00264 enum { OffsetArg, SizeArg, BufferArg };
00265
00266
00268
00269 std::string ToString()
00270 {
00271 return "Read";
00272 }
00273
00274 protected:
00275
00276
00282
00283 XRootDStatus RunImpl()
00284 {
00285 try
00286 {
00287 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00288 uint32_t size = std::get<SizeArg>( this->args ).Get();
00289 void *buffer = std::get<BufferArg>( this->args ).Get();
00290 return this->file->Read( offset, size, buffer, this->handler.get() );
00291 }
00292 catch( const PipelineException& ex )
00293 {
00294 return ex.GetError();
00295 }
00296 catch( const std::exception& ex )
00297 {
00298 return XRootDStatus( stError, ex.what() );
00299 }
00300 }
00301 };
00302 typedef ReadImpl<false> Read;
00303
00304
00306
00307 template<bool HasHndl>
00308 class CloseImpl: public FileOperation<CloseImpl, HasHndl, Resp<void>>
00309 {
00310 public:
00311
00312
00314
00315 using FileOperation<CloseImpl, HasHndl, Resp<void>>::FileOperation;
00316
00317
00319
00320 std::string ToString()
00321 {
00322 return "Close";
00323 }
00324
00325 protected:
00326
00327
00333
00334 XRootDStatus RunImpl()
00335 {
00336 return this->file->Close( this->handler.get() );
00337 }
00338 };
00339 typedef CloseImpl<false> Close;
00340
00341
00343
00344 template<bool HasHndl>
00345 class StatImpl: public FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>
00346 {
00347 public:
00348
00349
00351
00352 using FileOperation<StatImpl, HasHndl, Resp<StatInfo>, Arg<bool>>::FileOperation;
00353
00354
00356
00357 enum { ForceArg };
00358
00359
00361
00362 std::string ToString()
00363 {
00364 return "Stat";
00365 }
00366
00367 protected:
00368
00369
00375
00376 XRootDStatus RunImpl()
00377 {
00378 try
00379 {
00380 bool force = std::get<ForceArg>( this->args ).Get();
00381 return this->file->Stat( force, this->handler.get() );
00382 }
00383 catch( const PipelineException& ex )
00384 {
00385 return ex.GetError();
00386 }
00387 catch( const std::exception& ex )
00388 {
00389 return XRootDStatus( stError, ex.what() );
00390 }
00391 }
00392 };
00393
00394
00397
00398 StatImpl<false> Stat( File *file, Arg<bool> force )
00399 {
00400 return StatImpl<false>( file, std::move( force ) );
00401 }
00402
00403
00406
00407 StatImpl<false> Stat( File &file, Arg<bool> force )
00408 {
00409 return StatImpl<false>( file, std::move( force ) );
00410 }
00411
00412
00414
00415 template<bool HasHndl>
00416 class WriteImpl: public FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00417 Arg<uint32_t>, Arg<void*>>
00418 {
00419 public:
00420
00421
00423
00424 using FileOperation<WriteImpl, HasHndl, Resp<void>, Arg<uint64_t>, Arg<uint32_t>,
00425 Arg<void*>>::FileOperation;
00426
00427
00429
00430 enum { OffsetArg, SizeArg, BufferArg };
00431
00432
00434
00435 std::string ToString()
00436 {
00437 return "Write";
00438 }
00439
00440 protected:
00441
00442
00448
00449 XRootDStatus RunImpl()
00450 {
00451 try
00452 {
00453 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00454 uint32_t size = std::get<SizeArg>( this->args ).Get();
00455 void *buffer = std::get<BufferArg>( this->args ).Get();
00456 return this->file->Write( offset, size, buffer, this->handler.get() );
00457 }
00458 catch( const PipelineException& ex )
00459 {
00460 return ex.GetError();
00461 }
00462 catch( const std::exception& ex )
00463 {
00464 return XRootDStatus( stError, ex.what() );
00465 }
00466 }
00467 };
00468 typedef WriteImpl<false> Write;
00469
00470
00472
00473 template<bool HasHndl>
00474 class SyncImpl: public FileOperation<SyncImpl, HasHndl, Resp<void>>
00475 {
00476 public:
00477
00478
00480
00481 using FileOperation<SyncImpl, HasHndl, Resp<void>>::FileOperation;
00482
00483
00485
00486 std::string ToString()
00487 {
00488 return "Sync";
00489 }
00490
00491 protected:
00492
00493
00499
00500 XRootDStatus RunImpl()
00501 {
00502 return this->file->Sync( this->handler.get() );
00503 }
00504 };
00505 typedef SyncImpl<false> Sync;
00506
00507
00509
00510 template<bool HasHndl>
00511 class TruncateImpl: public FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>
00512 {
00513 public:
00514
00515
00517
00518 using FileOperation<TruncateImpl, HasHndl, Resp<void>, Arg<uint64_t>>::FileOperation;
00519
00520
00522
00523 enum { SizeArg };
00524
00525
00527
00528 std::string ToString()
00529 {
00530 return "Truncate";
00531 }
00532
00533 protected:
00534
00535
00541
00542 XRootDStatus RunImpl()
00543 {
00544 try
00545 {
00546 uint64_t size = std::get<SizeArg>( this->args ).Get();
00547 return this->file->Truncate( size, this->handler.get() );
00548 }
00549 catch( const PipelineException& ex )
00550 {
00551 return ex.GetError();
00552 }
00553 catch( const std::exception& ex )
00554 {
00555 return XRootDStatus( stError, ex.what() );
00556 }
00557 }
00558 };
00559
00560
00563
00564 TruncateImpl<false> Truncate( File *file, Arg<uint64_t> size )
00565 {
00566 return TruncateImpl<false>( file, std::move( size ) );
00567 }
00568
00569
00572
00573 TruncateImpl<false> Truncate( File &file, Arg<uint64_t> size )
00574 {
00575 return TruncateImpl<false>( file, std::move( size ) );
00576 }
00577
00578
00580
00581 template<bool HasHndl>
00582 class VectorReadImpl: public FileOperation<VectorReadImpl, HasHndl,
00583 Resp<VectorReadInfo>, Arg<ChunkList>, Arg<void*>>
00584 {
00585 public:
00586
00587
00589
00590 using FileOperation<VectorReadImpl, HasHndl, Resp<VectorReadInfo>, Arg<ChunkList>,
00591 Arg<void*>>::FileOperation;
00592
00593
00595
00596 enum { ChunksArg, BufferArg };
00597
00598
00600
00601 std::string ToString()
00602 {
00603 return "VectorRead";
00604 }
00605
00606 protected:
00607
00608
00614
00615 XRootDStatus RunImpl()
00616 {
00617 try
00618 {
00619 ChunkList chunks( std::get<ChunksArg>( this->args ).Get() );
00620 void *buffer = std::get<BufferArg>( this->args ).Get();
00621 return this->file->VectorRead( chunks, buffer, this->handler.get() );
00622 }
00623 catch( const PipelineException& ex )
00624 {
00625 return ex.GetError();
00626 }
00627 catch( const std::exception& ex )
00628 {
00629 return XRootDStatus( stError, ex.what() );
00630 }
00631 }
00632 };
00633 typedef VectorReadImpl<false> VectorRead;
00634
00635
00637
00638 template<bool HasHndl>
00639 class VectorWriteImpl: public FileOperation<VectorWriteImpl, HasHndl, Resp<void>,
00640 Arg<ChunkList>>
00641 {
00642 public:
00643
00644
00646
00647 using FileOperation<VectorWriteImpl, HasHndl, Resp<void>, Arg<ChunkList>>::FileOperation;
00648
00649
00651
00652 enum { ChunksArg };
00653
00654
00656
00657 std::string ToString()
00658 {
00659 return "VectorWrite";
00660 }
00661
00662 protected:
00663
00664
00670
00671 XRootDStatus RunImpl()
00672 {
00673 try
00674 {
00675 const ChunkList chunks( std::get<ChunksArg>( this->args ).Get() );
00676 return this->file->VectorWrite( chunks, this->handler.get() );
00677 }
00678 catch( const PipelineException& ex )
00679 {
00680 return ex.GetError();
00681 }
00682 catch( const std::exception& ex )
00683 {
00684 return XRootDStatus( stError, ex.what() );
00685 }
00686 }
00687 };
00688 typedef VectorWriteImpl<false> VectorWrite;
00689
00690
00692
00693 template<bool HasHndl>
00694 class WriteVImpl: public FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00695 Arg<struct iovec*>, Arg<int>>
00696 {
00697 public:
00698
00699
00701
00702 using FileOperation<WriteVImpl, HasHndl, Resp<void>, Arg<uint64_t>,
00703 Arg<struct iovec*>, Arg<int>>::FileOperation;
00704
00705
00707
00708 enum { OffsetArg, IovArg, IovcntArg };
00709
00710
00712
00713 std::string ToString()
00714 {
00715 return "WriteV";
00716 }
00717
00718 protected:
00719
00720
00726
00727 XRootDStatus RunImpl()
00728 {
00729 try
00730 {
00731 uint64_t offset = std::get<OffsetArg>( this->args ).Get();
00732 const struct iovec *iov = std::get<IovArg>( this->args ).Get();
00733 int iovcnt = std::get<IovcntArg>( this->args ).Get();
00734 return this->file->WriteV( offset, iov, iovcnt, this->handler.get() );
00735 }
00736 catch( const PipelineException& ex )
00737 {
00738 return ex.GetError();
00739 }
00740 catch( const std::exception& ex )
00741 {
00742 return XRootDStatus( stError, ex.what() );
00743 }
00744 }
00745 };
00746 typedef WriteVImpl<false> WriteV;
00747
00748
00750
00751 template<bool HasHndl>
00752 class FcntlImpl: public FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>
00753 {
00754 public:
00755
00756
00758
00759 using FileOperation<FcntlImpl, HasHndl, Resp<Buffer>, Arg<Buffer>>::FileOperation;
00760
00761
00763
00764 enum { BufferArg };
00765
00766
00768
00769 std::string ToString()
00770 {
00771 return "Fcntl";
00772 }
00773
00774 protected:
00775
00776
00782
00783 XRootDStatus RunImpl()
00784 {
00785 try
00786 {
00787 Buffer arg( std::get<BufferArg>( this->args ).Get() );
00788 return this->file->Fcntl( arg, this->handler.get() );
00789 }
00790 catch( const PipelineException& ex )
00791 {
00792 return ex.GetError();
00793 }
00794 catch( const std::exception& ex )
00795 {
00796 return XRootDStatus( stError, ex.what() );
00797 }
00798 }
00799 };
00800 typedef FcntlImpl<false> Fcntl;
00801
00802
00804
00805 template<bool HasHndl>
00806 class VisaImpl: public FileOperation<VisaImpl, HasHndl, Resp<Buffer>>
00807 {
00808 public:
00809
00810
00812
00813 using FileOperation<VisaImpl, HasHndl, Resp<Buffer>>::FileOperation;
00814
00815
00817
00818 std::string ToString()
00819 {
00820 return "Visa";
00821 }
00822
00823 protected:
00824
00825
00831
00832 XRootDStatus RunImpl()
00833 {
00834 return this->file->Visa( this->handler.get() );
00835 }
00836 };
00837 typedef VisaImpl<false> Visa;
00838 }
00839
00840 #endif // __XRD_CL_FILE_OPERATIONS_HH__
00841