Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:31

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 ///////////////////////////////////////////////////////////////////
0012 // IFileMgr.h
0013 // Manages all file open/reopen/close
0014 // Author: C.Leggett
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   // Io modes
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       // only look at first 2 bits
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   // Technologies
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   // File Attributes
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   // Handler functions
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   // file handler functions: open, close, reopen
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   // Callback Actions
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 } // namespace Io
0290 
0291 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0292 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0293 
0294 class GAUDI_API IFileMgr : virtual public IService {
0295 
0296 public:
0297   DeclareInterfaceID( IFileMgr, 1, 0 );
0298 
0299   // register handler function for file technology
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   // get handler from technology
0307   virtual StatusCode getHandler( const Io::IoTech&, Io::FileHdlr& ) const = 0;
0308   // get handler from file name
0309   virtual StatusCode getHandler( const std::string&, Io::FileHdlr& ) const = 0;
0310 
0311   // get file attributes from file name
0312   virtual int getFileAttr( const std::string&, std::vector<const Io::FileAttr*>& ) const = 0;
0313   // get file attributes from file descriptor
0314   virtual StatusCode getFileAttr( const Io::Fd, const Io::FileAttr*& ) const = 0;
0315   // get file attributes from file ptr
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   // get all files known to mgr. return numbers found.
0322   // will replace contents of FILES
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   // get all files of specific IoTech. returns number found.
0327   // will replace contents of FILES
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   // get all file of specific IoTech and access mode.
0332   // will replace contents of FILES
0333   // If IoTech == UNKNOWN, get all. returns number found
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   // get all descriptors known to mgr. returns number found
0340   virtual int getFd( std::vector<Io::Fd>& ) const = 0;
0341   // get all descriptors of specific IoTech. return number found
0342   virtual int getFd( const Io::IoTech&, std::vector<Io::Fd>& ) const = 0;
0343   // get all descriptors of specific IoTech and access mode.
0344   // If IoTech == INVALID, get all. returns number found
0345   virtual int getFd( const Io::IoTech&, const Io::IoFlags&, std::vector<Io::Fd>& ) const = 0;
0346 
0347   // get file name given Fd or ptr. Returns empty string if fails
0348   virtual const std::string& fname( const Io::Fd& ) const = 0;
0349   virtual const std::string& fname( void* ) const         = 0;
0350 
0351   // get Fd given file name. Returns -1 if fails
0352   virtual Io::Fd fd( const std::string& ) const = 0;
0353   virtual Io::Fd fd( void* fptr ) const         = 0;
0354 
0355   // get ptr given file name. Returns 0 if fails
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   // Open file, get Fd and ptr
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   // Open file, get Fd
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   // Open file, get ptr
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   // Close file by Fd or ptr
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   // Reopen file by Fd or ptr
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   // Callback actions
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   // Suppress callback action(s) for specific file.
0387   virtual void suppressAction( const std::string& )                    = 0;
0388   virtual void suppressAction( const std::string&, const Io::Action& ) = 0;
0389 };
0390 #endif