| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# RootIOHandler.cpp

Go to the documentation of this file.

    00001 // $Id: RootIOHandler.cpp,v 1.3 2010-09-27 15:43:53 frankb Exp $
    00002 //====================================================================
    00003 //
    00004 //  Package    : RootCnv
    00005 //
    00006 //  Description: Generate TClassStreamers for special Gaudi classes
    00007 //  @author      M.Frank
    00008 //====================================================================
    00009 #include "GaudiKernel/ObjectContainerBase.h"
    00010 #include "GaudiKernel/LinkManager.h"
    00011 #include "GaudiKernel/IRegistry.h"
    00012 #include "GaudiKernel/MsgStream.h"
    00013 #include "GaudiKernel/SmartRef.h"
    00014 #include "GaudiKernel/System.h"
    00015 #include "RootCnv/RootRefs.h"
    00016 #include "PoolClasses.h"
    00017 #include <stdexcept>
    00018 #include <iostream>
    00019 #include "TROOT.h"
    00020 #include "TClass.h"
    00021 #include "TSystem.h"
    00022 #include "TInterpreter.h"
    00023 #include "TClassStreamer.h"
    00024 #include <memory>
    00025
    00026 using namespace std;
    00027
    00028 namespace GaudiRoot {
    00029   static const DataObject* last_link_object = 0;
    00030   static int               last_link_hint = -1;
    00031   void resetLastLink() {
    00032     last_link_object = 0;
    00033     last_link_hint   = -1;
    00034   }
    00035   void pushCurrentDataObject(DataObject** pobjAddr) {
    00036     Gaudi::pushCurrentDataObject(pobjAddr);
    00037     resetLastLink();
    00038   }
    00039   void popCurrentDataObject() {
    00040     Gaudi::popCurrentDataObject();
    00041     resetLastLink();
    00042   }
    00043
    00044   union RefAccessor {
    00045     void*                       Ptr;
    00046     SmartRefBase*               Base;
    00047     SmartRef<DataObject>*       ObjectRef;
    00048     SmartRef<ContainedObject>*  ContainedRef;
    00049     RefAccessor(void* obj) { Ptr = obj; }
    00050   };
    00051
    00054   template <class T> class IOHandler : public TClassStreamer {
    00055   protected:
    00057     TClass*   m_root;
    00058   public:
    00060     IOHandler(TClass* c) : m_root(c) {  }
    00062     virtual ~IOHandler() {  }
    00064     virtual void operator()(TBuffer &b, void *obj)  {
    00065       try {
    00066         if ( b.IsReading() )
    00067           get(b,obj);
    00068         else
    00069           put(b,obj);
    00070       }
    00071       catch( const exception& e )    {
    00072         string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
    00073         err += e.what();
    00074         throw runtime_error(err);
    00075       }
    00076       catch( ... )    {
    00077         string err = "Class:" + string(m_root->GetName()) + "> Exception in object I/O";
    00078         throw runtime_error(err);
    00079       }
    00080     }
    00082     virtual void get(TBuffer &b, void* obj);
    00084     virtual void put(TBuffer &b, void* obj);
    00085   };
    00086
    00087   template <> void IOHandler<SmartRefBase>::get(TBuffer &b, void* obj) {
    00088     RefAccessor r(obj);
    00089     UInt_t start, count;
    00090     Version_t version = b.ReadVersion(&start, &count, m_root);
    00091     m_root->ReadBuffer(b, obj, version, start, count);
    00092     switch( r.Base->objectType() ) {
    00093     case SmartRefBase::DATAOBJECT:
    00094       (*r.ObjectRef)(Gaudi::getCurrentDataObject());
    00095       break;
    00096     case SmartRefBase::CONTAINEDOBJECT:
    00097       (*r.ContainedRef)(Gaudi::getCurrentDataObject());
    00098       break;
    00099     default:
    00100       cout << "Hit uninitialized smartRef!!!!" << endl;
    00101       break;
    00102     }
    00103   }
    00104
    00105   template <> void IOHandler<SmartRefBase>::put(TBuffer &b, void* obj) {
    00106     RefAccessor r(obj);
    00107     ContainedObject* p;
    00108     DataObject* curr, *pDO;
    00109     int hint, link;
    00110
    00111     curr = Gaudi::getCurrentDataObject();
    00112     pDO  = r.ObjectRef->data();
    00113     hint = r.ObjectRef->hintID();
    00114     link = r.ObjectRef->linkID();
    00115     if ( pDO )  {
    00116       switch( r.Base->objectType() ) {
    00117       case SmartRefBase::CONTAINEDOBJECT:
    00118         p = r.ContainedRef->data();
    00119         if ( p )  {
    00120           const ObjectContainerBase* parent = p->parent();
    00121           if ( parent )  {
    00122             link = p->index();
    00123             pDO  = const_cast<ObjectContainerBase*>(parent);
    00124             break;
    00125           }
    00126         }
    00127         pDO = 0;
    00128         cout << "IOHandler<SmartRefBase>::onWrite> "
    00129           << "Found invalid smart reference with object "
    00130           << "having no parent."
    00131           << endl;
    00132         throw runtime_error("IOHandler<SmartRefBase>::onWrite> "
    00133           "Found invalid smart reference with object "
    00134           "having no parent.");
    00135         break;
    00136       case SmartRefBase::DATAOBJECT:
    00137         link = StreamBuffer::INVALID;
    00138         break;
    00139       default:
    00140         break;
    00141       }
    00142       if ( pDO == last_link_object )  {
    00143         r.Base->set(curr, last_link_hint, link);
    00144         m_root->WriteBuffer(b, obj);
    00145         return;
    00146       }
    00147       else if ( pDO ) {
    00148         LinkManager* mgr = curr->linkMgr();
    00149         IRegistry*   reg = pDO->registry();
    00150         if ( reg && mgr )  {
    00151           hint = mgr->addLink(reg->identifier(), pDO);
    00152           last_link_hint   = hint;
    00153           last_link_object = pDO;
    00154         }
    00155       }
    00156       else {
    00157         hint = link = StreamBuffer::INVALID;
    00158       }
    00159     }
    00160     r.Base->set(curr, hint, link);
    00161     m_root->WriteBuffer(b, obj);
    00162   }
    00163
    00164   template <> void IOHandler<ContainedObject>::get(TBuffer &b, void* obj) {
    00165     UInt_t start, count;
    00166     Version_t version = b.ReadVersion(&start, &count, m_root);
    00167     m_root->ReadBuffer(b, obj, version, start, count);
    00168     ContainedObject* p = (ContainedObject*)obj;
    00169     p->setParent((ObjectContainerBase*)Gaudi::getCurrentDataObject());
    00170   }
    00171
    00172   template <> void IOHandler<ContainedObject>::put(TBuffer &b, void* obj) {
    00173     m_root->WriteBuffer(b, obj);
    00174   }
    00175
    00176   template <> void IOHandler<pool::Token>::get(TBuffer &b, void* obj) {
    00177     UInt_t start, count;
    00178     pool::Token* t = (pool::Token*)obj;
    00179     b.ReadVersion(&start, &count, m_root);
    00180     b.ReadFastArray(&t->m_oid.first, 2);
    00181     b.CheckByteCount(start, count, m_root);
    00182   }
    00183
    00184   template <> void IOHandler<pool::Token>::put(TBuffer &, void* ) {
    00185     throw runtime_error("Writing POOL files is not implemented!");
    00186   }
    00187
    00188   template <class T> static bool makeStreamer(MsgStream& log)  {
    00189     string cl_name = System::typeinfoName(typeid(T));
    00190     TClass* c = gROOT->GetClass(cl_name.c_str());
    00191     if ( c ) {
    00192       TClassStreamer* s = new IOHandler<T>(c);
    00193       c->AdoptStreamer(s);
    00194       log << MSG::DEBUG << "Installed IOHandler for class " << cl_name << endmsg;
    00195       return true;
    00196     }
    00197     log << MSG::ERROR << "[No ROOT TClass] Failed to install IOHandler for class " << cl_name << endmsg;
    00198     return false;
    00199   }
    00200
    00201   bool patchStreamers(MsgStream& s)  {
    00202     static bool first = true;
    00203     if ( first ) {
    00204       first = false;
    00205       gSystem->Load("libCintex");
    00206       gROOT->ProcessLine("Cintex::Cintex::Enable()");
    00207       gROOT->ProcessLine("#include <vector>");
    00208       gInterpreter->EnableAutoLoading();
    00209       gInterpreter->AutoLoad("DataObject");
    00210       gInterpreter->AutoLoad("PoolDbLinkManager");
    00211       gSystem->Load("libGaudiKernelDict");
    00212       gSystem->Load("libGaudiExamplesDict");
    00213
    00214
    00215       bool b1 = makeStreamer<SmartRefBase>(s);
    00216       bool b2 = makeStreamer<ContainedObject>(s);
    00217       bool b3 = makeStreamer<pool::Token>(s);
    00218       return b1 && b2 && b3;
    00219     }
    00220     return true;
    00221   }
    00222 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines