Source

mana-core-athenarootcomps / src / RootCnv.cxx

///////////////////////// -*- C++ -*- /////////////////////////////
// RootCnv.cxx 
// Implementation file for class Athena::RootCnv
// Author Peter van Gemmeren <gemmeren@anl.gov>
// Author: S.Binet<binet@cern.ch>
/////////////////////////////////////////////////////////////////// 

// stl includes
#include <string>

// fwk includes
#include "GaudiKernel/DataObject.h"
#include "GaudiKernel/IRegistry.h"
#include "AthenaKernel/ITPCnvBase.h"

// athenarootkernel
#include "AthenaRootKernel/IAthenaRootCnvSvc.h"
#include "AthenaRootKernel/IRootSvc.h"

// athenarootcomps
#include "RootCnv.h"

// sgtools
#include "SGTools/StorableConversions.h"

namespace {
  std::string name_from_clid (const CLID clid)
  {
    std::ostringstream o;
    o << "AthenaRootCnv_" << clid;
    return o.str();
  }
}


namespace Athena {

RootCnv::RootCnv(const CLID& id, ISvcLocator* pSvcLocator) :
  ::Converter(ROOT_StorageType, id, pSvcLocator),
  ::AthMessaging((pSvcLocator != 0 ? msgSvc() : 0), 
                 ::name_from_clid(id)),
  m_cnvsvc("Athena::RootCnvSvc/AthenaRootCnvSvc", ::name_from_clid(id)),
  m_ttype(), 
  m_ptype(), 
  m_tpcnv(0) 
{}

RootCnv::RootCnv( ISvcLocator* pSvcLocator ) : 
  ::Converter   ( ROOT_StorageType, CLID_NULL, pSvcLocator ),
  ::AthMessaging( msgSvc(),    name_from_clid(CLID_NULL) ),
  m_cnvsvc("Athena::RootCnvSvc/AthenaRootCnvSvc", ::name_from_clid(CLID_NULL)),
  m_ttype(), 
  m_ptype(), 
  m_tpcnv(0) 
{}

RootCnv::~RootCnv() 
{}

StatusCode 
RootCnv::initialize() 
{
  if (!::Converter::initialize().isSuccess()) {
    ATH_MSG_FATAL("Cannot initialize Converter base class.");
    return(StatusCode::FAILURE);
  }
  // Get the AthenaRootCnvSvc
  if (!m_cnvsvc.retrieve().isSuccess()) {
    ATH_MSG_FATAL("Cannot get AthenaRootCnvSvc.");
    return(StatusCode::FAILURE);
  }
  return(StatusCode::SUCCESS);
}

StatusCode 
RootCnv::finalize() 
{
  // Release the AthenaRootCnvSvc
  if (!m_cnvsvc.release().isSuccess()) {
    ATH_MSG_WARNING("Cannot release AthenaRootCnvSvc.");
  }
  return(::Converter::finalize());
}

long
RootCnv::repSvcType() const 
{
   return(ROOT_StorageType);
}

long 
RootCnv::storageType()
{
  return ROOT_StorageType;
}

StatusCode
RootCnv::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) 
{
  ATH_MSG_DEBUG("::createObj(" << pAddr << ", " << pObj << ")");
  /*
  Athena::RootBranchAddress *rba = dynamic_cast<Athena::RootBranchAddress*>(pAddr);
  if (!rba) {
    ATH_MSG_DEBUG(*pAddr->par() << " is NOT a GenericAddress!");
    return StatusCode::FAILURE;
  }
  ATH_MSG_DEBUG("loading branch: [" << rba->par()[0]
                << "/" << rba->par()[1] << "]...");
  rba->setBranchAddress(m_type);
  ATH_MSG_DEBUG("loading branch: [" << rba->par()[0]
                << "/" << rba->par()[1] << "]... [done]");
  Athena::DataBucketBranch *dbb = new DataBucketBranch(rba->clID(), 
                                                       rba->m_ptr);
  pObj = dbb;
  return StatusCode::SUCCESS;
  */
  return StatusCode::FAILURE;
}

StatusCode
RootCnv::fillObjRefs(IOpaqueAddress* pAddr, DataObject* pObj) 
{
  ATH_MSG_VERBOSE("::fillObjRefs(paddr=" << pAddr << ", "
                  << "dobj=" << pObj << ")...");
  return(StatusCode::FAILURE);
}

StatusCode
RootCnv::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) 
{
  ATH_MSG_VERBOSE("::createRep pObj = " << pObj);
  pAddr = 0;
  if (pObj == 0) {
    ATH_MSG_ERROR("::createRep called without DataObjetct.");
    return(StatusCode::FAILURE);
  }
  CLID clid = pObj->clID();
  IRegistry* pR = pObj->registry();
  std::string p[2] = { "", pR->identifier() };
  ATH_MSG_VERBOSE("::createRep identifier = " << pR->name());
  if (!m_ptype) {
    m_tpcnv = m_cnvsvc->getTPConverter(clid);
    ATH_MSG_VERBOSE("::createRep m_tpcnv = " 
                    << m_tpcnv);
    if (m_tpcnv == 0) {
      ATH_MSG_INFO("Cannot get T/P converter for DataObject, "
		   "writing transient type ["
		   << pR->name() << ", clid=" << clid << "]");
      m_ptype = m_cnvsvc->getType(clid);
    } else {
      m_ptype = m_cnvsvc->getType(m_tpcnv->persistentTInfo());
    }
    if (!m_ptype) {
      ATH_MSG_ERROR("Cannot get TClass for DataObject.");
      return(StatusCode::FAILURE);
    }
  }
  unsigned long ip[2] = { 0, 0 };
  if (!m_cnvsvc->createAddress(this->repSvcType(), 
			       clid, 
			       p, 
			       ip, 
			       pAddr).isSuccess()) {
    ATH_MSG_ERROR("problem creating opaque address");
    return StatusCode::FAILURE;
  }

  void* trans = SG::fromStorable(pObj, clid);
  ATH_MSG_DEBUG("writing [" << objType() << "/" << p[1] << "]");
  ATH_MSG_DEBUG("p-type: [" << m_ptype.Name() << "]");
  ip[0] = m_cnvsvc->writeObject(pR->identifier(), 
                                m_ptype, 
                                trans, 
                                m_tpcnv);
  ATH_MSG_DEBUG("writing [" << objType() << "/" << p[1] << "] [done]");

  return StatusCode::SUCCESS;
}

StatusCode
RootCnv::fillRepRefs(IOpaqueAddress* pAddr, DataObject* pObj) 
{
  ATH_MSG_VERBOSE("::fillRepRefs(paddr=" << pAddr << ", "
                  << "dobj=" << pObj << ")...");
  return(StatusCode::FAILURE);
}


} //< end namespace Athena