/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz 07/2008 ! ! Copyright: MAGIC Software Development, 2000-2008 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MParEmulated // // Storage Container for emulated branches // // Thanks to roots streaming mechanism simple branches can be recreated // from a file. To read these kind of foreign branches the root system // allocates memory. We can get a pointer to this memory and the // offsets to the data, thus allowing to use this data and ecapsulate // it into the MARS environment. This is done using MParEmulated. // ///////////////////////////////////////////////////////////////////////////// #include "MParEmulated.h" #include #include #include #include "MLog.h" #include "MLogManip.h" ClassImp(MParEmulated); using namespace std; // -------------------------------------------------------------------------- // // Default constructor. // MParEmulated::MParEmulated(const char *name, const char *title) : fPtr(0) { fName = name ? name : "MParEmulated"; fTitle = title ? title : "Parameter container emulating a class"; } // -------------------------------------------------------------------------- // // The default is to print all emulated data members. If an option is // given it is interpreted as TPRegexp (regular expression) and only // data members matching this regex are printed. // void MParEmulated::Print(Option_t *o) const { TString opt(o); if (opt.IsNull()) opt = ".*"; TPRegexp regex(opt); Print(regex, fClassName, "", 0); } // -------------------------------------------------------------------------- // // Get the class with name clsname and its corresponding streamer info // TStreamerInfo *MParEmulated::GetStreamerInfo(const TString &clsname) const { TClass *cls = gROOT->GetClass(clsname); if (!cls) { *fLog << err << dbginf << "ERROR - Class " << clsname << " not in dictionary." << endl; return 0; } TStreamerInfo *info = cls->GetStreamerInfo(); if (!info) { *fLog << err << dbginf << "ERROR - No TStreamerInfo for class " << clsname << "." << endl; return 0; } return info; } // -------------------------------------------------------------------------- // // Get the method call for the given method and offset, add method to // MParContainer::fgListmethodCall // TMethodCall *MParEmulated::GetMethodCall(const char *get, Int_t offset) const { TMethodCall *call = new TMethodCall(MParEmulated::Class(), get, Form("%d", offset));; fgListMethodCall.Add(call); return call; } // -------------------------------------------------------------------------- // // Get the getter method for the given data member. Since we have no real // getter methods and no real data members we have to fake the TMethodCall. // TMethodCall *MParEmulated::GetterMethod(const char *name, TString clsname, Int_t offset) const { TStreamerInfo *info = GetStreamerInfo(clsname); if (!info) return 0; const TString arg(name); const Ssiz_t p = arg.First('.'); const TString nam = p<0 ? arg : arg(0, p); Int_t off; TStreamerElement *el = info->GetStreamerElement(nam, off); if (!el) { *fLog << err << dbginf << "ERROR - No TStreamerInfo for " << nam << " [" << clsname << "]" << endl; return 0; } const TString type = el->GetTypeNameBasic(); if (type=="int") return GetMethodCall("GetInt", offset+off); if (type=="double") return GetMethodCall("GetDouble", offset+off); if (p<0) { *fLog << err << dbginf << "ERROR - No TStreamerInfo for " << nam << "." << type << " [" << clsname << "]" << endl; return 0; } const TString var = arg(p+1, arg.Length()); return GetterMethod(var, type, offset+off); } // -------------------------------------------------------------------------- // // Print the requested data from our memory using the streamer info. // void MParEmulated::Print(TPRegexp ®ex, TString clsname, TString prefix, Int_t offset) const { TStreamerInfo *info = GetStreamerInfo(clsname); if (!info) return; TIter Next(info->GetElements()); TStreamerElement *el = 0; while ((el=(TStreamerElement*)Next())) { const TString str = prefix+el->GetName(); if (str(regex).IsNull()) continue; if (el->InheritsFrom(TStreamerBasicType::Class())) { const TString type(el->GetTypeNameBasic()); cout << fName << "." << str << "[" << type << "] \t"; if (type=="int") cout << GetInt(el->GetOffset()+offset); if (type=="double") cout << GetDouble(el->GetOffset()+offset); cout << endl; continue; } if (el->InheritsFrom(TStreamerObjectAny::Class())) { Print(regex, el->GetTypeNameBasic(), str+".", el->GetOffset()+offset); continue; } } }