00001
00002 #ifndef GAUDIKERNEL_IINTERFACE_H
00003 #define GAUDIKERNEL_IINTERFACE_H
00004
00005
00006
00007 #include "GaudiKernel/Kernel.h"
00008 #include "GaudiKernel/StatusCode.h"
00009 #include <ostream>
00010
00022 class InterfaceID {
00023 public:
00025 InterfaceID( unsigned long lid ) : m_id( lid & 0xFFFF ),
00026 m_major_ver( (lid & 0xFF000000)>>24 ),
00027 m_minor_ver( (lid & 0xFF0000)>> 16 ) { }
00029 InterfaceID( unsigned long id, unsigned long major, unsigned long minor = 0)
00030 : m_id( id ), m_major_ver( major ), m_minor_ver( minor ) { }
00032 InterfaceID( const char* name, unsigned long major, unsigned long minor = 0)
00033 : m_id( hash32(name) ), m_major_ver( major ), m_minor_ver( minor ) { }
00035 ~InterfaceID() { }
00037 operator unsigned long() const {
00038 return (m_major_ver << 24) + (m_minor_ver << 16) + m_id;
00039 }
00041 unsigned long id() const { return m_id; }
00043 unsigned long majorVersion() const { return m_major_ver; }
00045 unsigned long minorVersion() const { return m_minor_ver; }
00049 bool versionMatch( const InterfaceID& iid ) const {
00050 return ( id() == iid.id() &&
00051 majorVersion() == iid.majorVersion() &&
00052 minorVersion() >= iid.minorVersion() );
00053 }
00055 bool fullMatch( const InterfaceID& iid ) const {
00056 return ( id() == iid.id() &&
00057 majorVersion() == iid.majorVersion() &&
00058 minorVersion() == iid.minorVersion() );
00059 }
00061 bool operator == (const InterfaceID& iid ) const { return fullMatch(iid); }
00063 unsigned int hash32(const char* key) {
00064 unsigned int hash;
00065 const char* k;
00066 for (hash = 0, k = key; *k; k++) {
00067 hash += *k; hash += (hash << 10); hash ^= (hash >> 6);
00068 }
00069 hash += (hash << 3); hash ^= (hash >> 11); hash += (hash << 15);
00070 return hash;
00071 }
00072 private:
00073 friend std::ostream& operator << ( std::ostream&, const InterfaceID&);
00074 unsigned long m_id;
00075 unsigned long m_major_ver;
00076 unsigned long m_minor_ver;
00077 };
00078
00080
00081
00082
00083 static const InterfaceID IID_IInterface(1,0,0);
00084
00091 class IInterface {
00092 public:
00094 static const InterfaceID& interfaceID() { return IID_IInterface; }
00095
00097 virtual ~IInterface() { }
00098
00103 virtual StatusCode queryInterface(const InterfaceID& riid,
00104 void** ppvInterface) = 0;
00105
00107 virtual unsigned long addRef() = 0;
00108
00110 virtual unsigned long release() = 0;
00111
00113 enum Status {
00115 SUCCESS = 1,
00117 NO_INTERFACE,
00119 VERSMISMATCH,
00121 LAST_ERROR
00122 };
00123 };
00124
00132 template <class I>
00133 bool isValidInterface( I* i) {
00134 void* ii;
00135 StatusCode sc = i->queryInterface( I::interfaceID(), &ii);
00136 return sc.isSuccess();
00137 }
00138
00140 inline std::ostream& operator << ( std::ostream& s, const InterfaceID& id) {
00141 s << "IID_" << id.m_id;
00142 return s;
00143 }
00144
00155 template <class DEST,class SRC>
00156 inline DEST** pp_cast(SRC** ptr){
00157 return reinterpret_cast<DEST**>(ptr);
00158 }
00159 #endif // GAUDIKERNEL_IINTERFACE_H