File indexing completed on 2025-02-21 10:00:31
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #ifndef GAUDIKERNEL_IFILEMGR_H
0018 #define GAUDIKERNEL_IFILEMGR_H 1
0019
0020 #include "GaudiKernel/ClassID.h"
0021 #include "GaudiKernel/IService.h"
0022
0023 #include <bitset>
0024 #include <fcntl.h>
0025 #include <functional>
0026 #include <map>
0027 #include <string>
0028 #include <vector>
0029
0030 namespace Io {
0031
0032
0033
0034
0035
0036 enum IoFlag {
0037 READ = O_RDONLY,
0038 WRITE = O_WRONLY,
0039 RDWR = O_RDWR,
0040
0041 CREATE = O_CREAT,
0042 EXCL = O_EXCL,
0043 TRUNC = O_TRUNC,
0044
0045 APPEND = O_APPEND,
0046
0047 INVALID = 1 << 31
0048 };
0049
0050 class IoFlags final {
0051 public:
0052 IoFlags() = default;
0053 IoFlags( int i ) : _f( i ){};
0054
0055 int f() const { return _f; }
0056
0057 bool operator==( const IoFlags& fa ) const { return ( _f == fa.f() ); }
0058 bool operator==( const int& fa ) const { return ( _f == fa ); }
0059
0060 IoFlags operator|( const IoFlags& fa ) const { return ( _f | fa.f() ); }
0061 IoFlags operator|( const int& fa ) const { return ( _f | fa ); }
0062
0063 operator int() const { return _f; }
0064
0065 bool isRead() const { return ( _f == READ ); }
0066 bool isWrite() const { return ( ( _f & WRITE ) != 0 ); }
0067 bool isRdWr() const { return ( ( _f & RDWR ) != 0 ); }
0068 bool isInvalid() const { return ( ( _f & INVALID ) != 0 ); }
0069
0070 bool match( const IoFlags& fa, bool strict = true ) const {
0071 if ( strict ) { return ( _f == fa ); }
0072
0073 return ( ( _f & 3 ) == ( fa & 3 ) );
0074 }
0075
0076 std::string bits() const {
0077 std::string s;
0078 int f( _f );
0079 const int SHIFT = 8 * sizeof( int ) - 1;
0080 const unsigned MASK = 1 << SHIFT;
0081
0082 for ( int i = 1; i <= SHIFT + 1; ++i ) {
0083 s += ( f & MASK ? '1' : '0' );
0084 f <<= 1;
0085 if ( i % 8 == 0 ) s += ' ';
0086 }
0087 return s;
0088 }
0089
0090 private:
0091 int _f = INVALID;
0092 };
0093
0094 static std::string IoFlagName( IoFlags f ) {
0095 static const std::map<IoFlag, std::string> s_names = { { { READ, "READ" },
0096 { WRITE, "WRITE" },
0097 { RDWR, "RDWR" },
0098 { CREATE, "CREATE" },
0099 { EXCL, "EXCL" },
0100 { TRUNC, "TRUNC" },
0101 { APPEND, "APPEND" },
0102 { INVALID, "INVALID" } } };
0103 if ( f.isRead() ) return s_names.at( READ );
0104
0105 std::string ff;
0106 for ( int i = 0; i < 32; ++i ) {
0107 auto b = ( 1 << i );
0108 if ( b & f ) ff += s_names.at( (IoFlag)( b ) ) + "|";
0109 }
0110 ff.erase( ff.length() - 1 );
0111 return ff;
0112 }
0113
0114 inline IoFlags IoFlagFromName( const std::string& f ) {
0115 static const std::map<std::string, IoFlag> s_n = { { { "READ", Io::READ },
0116 { "WRITE", Io::WRITE },
0117 { "RDWR", Io::RDWR },
0118 { "CREATE", Io::CREATE },
0119 { "EXCL", Io::EXCL },
0120 { "TRUNC", Io::TRUNC },
0121 { "APPEND", Io::APPEND },
0122 { "INVALID", Io::INVALID } } };
0123
0124 IoFlags fl( Io::INVALID );
0125 size_t j( 0 ), k( 0 );
0126 std::string fs;
0127 while ( ( k = f.find( "|", j ) ) != std::string::npos ) {
0128 fs = f.substr( j, k - j );
0129 if ( s_n.find( fs ) == s_n.end() ) { return Io::INVALID; }
0130 if ( fl.isInvalid() ) {
0131 fl = s_n.at( fs );
0132 } else {
0133 fl = fl | s_n.at( fs );
0134 }
0135 j = k + 1;
0136 }
0137 fs = f.substr( j );
0138 if ( s_n.find( fs ) == s_n.end() ) { return Io::INVALID; }
0139 if ( fl.isInvalid() ) {
0140 fl = s_n.at( fs );
0141 } else {
0142 fl = fl | s_n.at( fs );
0143 }
0144 return fl;
0145 }
0146
0147 inline std::ostream& operator<<( std::ostream& s, const IoFlag& f ) { return s << IoFlagName( f ); }
0148 inline std::ostream& operator<<( std::ostream& s, const IoFlags& f ) { return s << IoFlagName( f ); }
0149
0150
0151
0152
0153
0154
0155
0156 enum IoTech { UNKNOWN, POSIX, ROOT, BS, HDF5, SQLITE };
0157
0158 inline std::ostream& operator<<( std::ostream& s, const IoTech& t ) {
0159 static const std::array<const char*, SQLITE + 1> tbl = { { "UNKNOWN", "POSIX", "ROOT", "BS", "HDF5", "SQLITE" } };
0160 return t < tbl.size() ? s << tbl[t] : s;
0161 }
0162
0163
0164
0165
0166
0167
0168
0169 typedef int Fd;
0170
0171 class FileAttr final {
0172 public:
0173 FileAttr() = default;
0174 FileAttr( Fd f, std::string n, std::string d, IoTech t, IoFlags fa, void* p, bool o, bool s = false )
0175 : m_fd( f )
0176 , m_name( std::move( n ) )
0177 , m_desc( std::move( d ) )
0178 , m_tech( t )
0179 , m_flags( fa )
0180 , m_iflags( fa )
0181 , m_fptr( p )
0182 , m_isOpen( o )
0183 , m_shared( s ){};
0184
0185 Fd fd() const { return m_fd; }
0186 const std::string& name() const { return m_name; }
0187 const std::string& desc() const { return m_desc; }
0188 IoTech tech() const { return m_tech; }
0189 IoFlags flags() const { return m_flags; }
0190 IoFlags iflags() const { return m_iflags; }
0191 void* fptr() const { return m_fptr; }
0192 bool isOpen() const { return m_isOpen; }
0193 bool isShared() const { return m_shared; }
0194
0195 void fd( Fd f ) { m_fd = f; }
0196 void name( const std::string& n ) { m_name = n; }
0197 void desc( const std::string& d ) { m_desc = d; }
0198 void tech( const IoTech& t ) { m_tech = t; }
0199 void flags( const IoFlags& f ) { m_flags = f; }
0200 void iflags( const IoFlags& f ) { m_iflags = f; }
0201 void fptr( void* v ) { m_fptr = v; }
0202 void isOpen( bool b ) { m_isOpen = b; }
0203 void isShared( bool s ) { m_shared = s; }
0204
0205 friend std::ostream& operator<<( std::ostream& os, const FileAttr& fa ) {
0206 os << "name: \"" << fa.name() << "\" tech: " << fa.tech() << " desc: " << fa.desc()
0207 << " flags: " << IoFlagName( fa.flags() ) << " i_flags: " << IoFlagName( fa.iflags() ) << " Fd: " << fa.fd()
0208 << " ptr: " << fa.fptr() << ( fa.isOpen() ? " [o]" : " [c]" ) << ( fa.isShared() ? " [s]" : " [u]" );
0209 return os;
0210 }
0211
0212 bool operator==( const FileAttr& fa ) const {
0213 return ( m_fd == fa.fd() && m_name == fa.name() && m_desc == fa.desc() && m_tech == fa.tech() &&
0214 m_flags == fa.flags() && m_fptr == fa.fptr() && m_isOpen == fa.isOpen() && m_shared == fa.isShared() );
0215 }
0216
0217 bool operator<( const FileAttr& rhs ) const {
0218 if ( m_name != rhs.name() ) {
0219 return ( m_name < rhs.name() );
0220 } else {
0221 return ( m_flags < rhs.iflags() );
0222 }
0223 }
0224
0225 private:
0226 Fd m_fd = -1;
0227 std::string m_name;
0228 std::string m_desc;
0229 IoTech m_tech = UNKNOWN;
0230 IoFlags m_flags = INVALID;
0231 IoFlags m_iflags = INVALID;
0232 void* m_fptr = nullptr;
0233 bool m_isOpen = false;
0234 bool m_shared = false;
0235 };
0236
0237
0238
0239
0240
0241
0242
0243 typedef int open_t;
0244 typedef int close_t;
0245 typedef int reopen_t;
0246
0247 typedef std::function<Io::open_t( const std::string&, Io::IoFlags, const std::string&, Io::Fd&, void*& )> bfcn_open_t;
0248 typedef std::function<Io::close_t( Io::Fd )> bfcn_close_t;
0249 typedef std::function<Io::close_t( void* )> bfcn_closeP_t;
0250 typedef std::function<Io::reopen_t( Io::Fd, Io::IoFlags )> bfcn_reopen_t;
0251 typedef std::function<Io::reopen_t( void*, Io::IoFlags )> bfcn_reopenP_t;
0252
0253
0254 struct FileHdlr final {
0255 IoTech tech = UNKNOWN;
0256
0257 bfcn_open_t b_open_fcn;
0258 bfcn_close_t b_close_fcn;
0259 bfcn_closeP_t b_closeP_fcn;
0260 bfcn_reopen_t b_reopen_fcn;
0261 bfcn_reopenP_t b_reopenP_fcn;
0262
0263 FileHdlr() = default;
0264 FileHdlr( IoTech t, bfcn_open_t o, bfcn_close_t c, bfcn_reopen_t r )
0265 : tech( t ), b_open_fcn( o ), b_close_fcn( c ), b_reopen_fcn( r ){};
0266 FileHdlr( IoTech t, bfcn_open_t o, bfcn_closeP_t c, bfcn_reopenP_t r )
0267 : tech( t ), b_open_fcn( o ), b_closeP_fcn( c ), b_reopenP_fcn( r ){};
0268 FileHdlr( IoTech t, bfcn_open_t o, bfcn_close_t c1, bfcn_closeP_t c2, bfcn_reopen_t r1, bfcn_reopenP_t r2 )
0269 : tech( t ), b_open_fcn( o ), b_close_fcn( c1 ), b_closeP_fcn( c2 ), b_reopen_fcn( r1 ), b_reopenP_fcn( r2 ){};
0270 };
0271
0272
0273
0274
0275
0276
0277
0278 enum Action { OPEN = 0, CLOSE, REOPEN, OPEN_ERR, CLOSE_ERR, REOPEN_ERR, INVALID_ACTION };
0279 using Action_bitmap = std::bitset<INVALID_ACTION + 1>;
0280
0281 inline std::ostream& operator<<( std::ostream& s, const Action& t ) {
0282 static const std::array<const char*, INVALID_ACTION + 1> tbl = {
0283 { "OPEN", "CLOSE", "REOPEN", "OPEN_ERR", "CLOSE_ERR", "REOPEN_ERR", "INVALID_ACTION" } };
0284 return t < tbl.size() ? s << tbl[t] : s;
0285 }
0286
0287 #define FILEMGR_CALLBACK_ARGS const Io::FileAttr*, const std::string&
0288 typedef std::function<StatusCode( FILEMGR_CALLBACK_ARGS )> bfcn_action_t;
0289 }
0290
0291
0292
0293
0294 class GAUDI_API IFileMgr : virtual public IService {
0295
0296 public:
0297 DeclareInterfaceID( IFileMgr, 1, 0 );
0298
0299
0300 virtual StatusCode regHandler( Io::FileHdlr ) = 0;
0301
0302 virtual StatusCode deregHandler( const Io::IoTech& ) = 0;
0303
0304 virtual StatusCode hasHandler( const Io::IoTech& ) const = 0;
0305
0306
0307 virtual StatusCode getHandler( const Io::IoTech&, Io::FileHdlr& ) const = 0;
0308
0309 virtual StatusCode getHandler( const std::string&, Io::FileHdlr& ) const = 0;
0310
0311
0312 virtual int getFileAttr( const std::string&, std::vector<const Io::FileAttr*>& ) const = 0;
0313
0314 virtual StatusCode getFileAttr( const Io::Fd, const Io::FileAttr*& ) const = 0;
0315
0316 virtual StatusCode getFileAttr( void*, const Io::FileAttr*& ) const = 0;
0317
0318 virtual void listHandlers() const = 0;
0319 virtual void listFiles() const = 0;
0320
0321
0322
0323 virtual int getFiles( std::vector<std::string>& FILES, bool onlyOpen = true ) const = 0;
0324 virtual int getFiles( std::vector<const Io::FileAttr*>& FILES, bool onlyOpen = true ) const = 0;
0325
0326
0327
0328 virtual int getFiles( const Io::IoTech&, std::vector<std::string>& FILES, bool onlyOpen = true ) const = 0;
0329 virtual int getFiles( const Io::IoTech&, std::vector<const Io::FileAttr*>& FILES, bool onlyOpen = true ) const = 0;
0330
0331
0332
0333
0334 virtual int getFiles( const Io::IoTech&, const Io::IoFlags&, std::vector<std::string>& FILES,
0335 bool onlyOpen = true ) const = 0;
0336 virtual int getFiles( const Io::IoTech&, const Io::IoFlags&, std::vector<const Io::FileAttr*>& FILES,
0337 bool onlyOpen = true ) const = 0;
0338
0339
0340 virtual int getFd( std::vector<Io::Fd>& ) const = 0;
0341
0342 virtual int getFd( const Io::IoTech&, std::vector<Io::Fd>& ) const = 0;
0343
0344
0345 virtual int getFd( const Io::IoTech&, const Io::IoFlags&, std::vector<Io::Fd>& ) const = 0;
0346
0347
0348 virtual const std::string& fname( const Io::Fd& ) const = 0;
0349 virtual const std::string& fname( void* ) const = 0;
0350
0351
0352 virtual Io::Fd fd( const std::string& ) const = 0;
0353 virtual Io::Fd fd( void* fptr ) const = 0;
0354
0355
0356 virtual void* fptr( const std::string& ) const = 0;
0357 virtual void* fptr( const Io::Fd& ) const = 0;
0358
0359 virtual int getLastError( std::string& ) const = 0;
0360
0361
0362 virtual Io::open_t open( const Io::IoTech&, const std::string& caller, const std::string& fname, const Io::IoFlags&,
0363 Io::Fd&, void*&, const std::string& desc, const bool shared = false ) = 0;
0364
0365
0366 virtual Io::open_t open( const Io::IoTech&, const std::string& caller, const std::string& fname, const Io::IoFlags&,
0367 Io::Fd&, const std::string& desc, const bool shared = false ) = 0;
0368
0369
0370 virtual Io::open_t open( const Io::IoTech&, const std::string& caller, const std::string& fname, const Io::IoFlags&,
0371 void*&, const std::string& desc, const bool shared = false ) = 0;
0372
0373
0374 virtual Io::close_t close( const Io::Fd, const std::string& caller ) = 0;
0375 virtual Io::close_t close( void*, const std::string& caller ) = 0;
0376
0377
0378 virtual Io::reopen_t reopen( const Io::Fd, const Io::IoFlags&, const std::string& ) = 0;
0379 virtual Io::reopen_t reopen( void*, const Io::IoFlags&, const std::string& ) = 0;
0380
0381
0382 virtual StatusCode regAction( Io::bfcn_action_t, const Io::Action&, const std::string& d = "" ) = 0;
0383 virtual StatusCode regAction( Io::bfcn_action_t, const Io::Action&, const Io::IoTech&,
0384 const std::string& d = "" ) = 0;
0385
0386
0387 virtual void suppressAction( const std::string& ) = 0;
0388 virtual void suppressAction( const std::string&, const Io::Action& ) = 0;
0389 };
0390 #endif