source: trunk/MagicSoft/Mars/mbase/MParEmulated.cc@ 9254

Last change on this file since 9254 was 9079, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 8.8 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 07/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2008
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MParEmulated
28//
29// Storage Container for emulated branches
30//
31// Thanks to roots streaming mechanism simple branches can be recreated
32// from a file. To read these kind of foreign branches the root system
33// allocates memory. We can get a pointer to this memory and the
34// offsets to the data, thus allowing to use this data and ecapsulate
35// it into the MARS environment. This is done using MParEmulated.
36//
37/////////////////////////////////////////////////////////////////////////////
38#include "MParEmulated.h"
39
40#include <TClass.h> // root >=5.20/00
41#include <TPRegexp.h>
42#include <TMethodCall.h>
43#include <TStreamerElement.h>
44#include <TVirtualCollectionProxy.h>
45#if ROOT_VERSION_CODE>ROOT_VERSION(5,12,00)
46#include <TVirtualStreamerInfo.h>
47#endif
48
49#include "MLog.h"
50#include "MLogManip.h"
51
52ClassImp(MParEmulated);
53
54using namespace std;
55
56// --------------------------------------------------------------------------
57//
58// Default constructor.
59//
60MParEmulated::MParEmulated(const char *name, const char *title)
61 : fPtr(0)
62{
63 fName = name ? name : "MParEmulated";
64 fTitle = title ? title : "Parameter container emulating a class";
65}
66
67// --------------------------------------------------------------------------
68//
69// The default is to print all emulated data members. If an option is
70// given it is interpreted as TPRegexp (regular expression) and only
71// data members matching this regex are printed.
72//
73void MParEmulated::Print(Option_t *o) const
74{
75 TString opt(o);
76 if (opt.IsNull())
77 opt = ".*";
78
79 TPRegexp regex(opt);
80 Print(regex, fClassName, "", 0);
81}
82
83int MParEmulated::GetPInt(TVirtualCollectionProxy *proxy, Int_t offset) const
84{
85 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
86 return *reinterpret_cast<int*>((char*)proxy->At(0)+offset);
87}
88Int_t MParEmulated::GetPInt_t(TVirtualCollectionProxy *proxy, Int_t offset) const
89{
90 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
91 return *reinterpret_cast<Int_t*>((char*)proxy->At(0)+offset);
92}
93double MParEmulated::GetPDouble(TVirtualCollectionProxy *proxy, Int_t offset) const
94{
95 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
96 return *reinterpret_cast<double*>((char*)proxy->At(0)+offset);
97}
98unsigned long long MParEmulated::GetPULongLong(TVirtualCollectionProxy *proxy, Int_t offset) const
99{
100 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
101 return *reinterpret_cast<unsigned long long*>((char*)proxy->At(0)+offset);
102}
103
104// --------------------------------------------------------------------------
105//
106// Get the class with name clsname and its corresponding streamer info
107//
108#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
109TStreamerInfo *MParEmulated::GetStreamerInfo(const TString &clsname, TVirtualCollectionProxy * &proxy, Int_t &offset) const
110#else
111TVirtualStreamerInfo *MParEmulated::GetStreamerInfo(const TString &clsname, TVirtualCollectionProxy * &proxy, Int_t &offset) const
112#endif
113{
114 TClass *cls = gROOT->GetClass(clsname);
115 if (!cls)
116 {
117 *fLog << err << dbginf << "ERROR - Class " << clsname << " not in dictionary." << endl;
118 return 0;
119 }
120
121 proxy = cls->GetCollectionProxy();
122 if (proxy)
123 {
124 cls = proxy->GetValueClass();
125
126 proxy->PushProxy(fPtr);
127 // proxy->GetSize() // Number of elements in array
128 if (proxy->At(0))
129 offset = (char*)proxy->At(0)-(char*)fPtr;
130 proxy->PopProxy();
131
132 }
133
134#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
135 TStreamerInfo *info = cls->GetStreamerInfo();
136#else
137 TVirtualStreamerInfo *info = cls->GetStreamerInfo();
138#endif
139 if (!info)
140 {
141 *fLog << err << dbginf << "ERROR - No TStreamerInfo for class " << clsname << "." << endl;
142 return 0;
143 }
144
145 return info;
146}
147
148// --------------------------------------------------------------------------
149//
150// Get the method call for the given method and offset, add method to
151// MParContainer::fgListmethodCall
152//
153TMethodCall *MParEmulated::GetMethodCall(const char *get, Int_t offset, TVirtualCollectionProxy *proxy) const
154{
155 TString name(get);
156 if (proxy)
157 name.Prepend("P");
158 name.Prepend("Get");
159
160 TMethodCall *call = new TMethodCall(MParEmulated::Class(), name, proxy?Form("%p,%d", proxy, offset):Form("%d", offset));
161 fgListMethodCall.Add(call);
162 return call;
163}
164
165// --------------------------------------------------------------------------
166//
167// Get the getter method for the given data member. Since we have no real
168// getter methods and no real data members we have to fake the TMethodCall.
169//
170TMethodCall *MParEmulated::GetterMethod(const char *name, TString clsname, Int_t offset) const
171{
172 TVirtualCollectionProxy *proxy = 0;
173
174 // Get the streamer info for the class and the offset to the
175 // first element of a possible array
176 Int_t arroff = 0;
177
178#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
179 TStreamerInfo *info = GetStreamerInfo(clsname, proxy, arroff);
180#else
181 TVirtualStreamerInfo *info = GetStreamerInfo(clsname, proxy, arroff);
182#endif
183 if (!info)
184 return 0;
185
186 const TString arg(name);
187
188 const Ssiz_t p = arg.Last('.');
189
190 const TString nam = p<0 ? arg : arg(0, p);
191
192 // Get the streamer element to the data member and
193 // and the offset from the base of the object
194 Int_t off;
195 TStreamerElement *el = info->GetStreamerElement(nam, off);
196 if (!el)
197 {
198 *fLog << err << dbginf << "ERROR - No TStreamerElement for " << nam << " [" << clsname << "]" << endl;
199 return 0;
200 }
201
202 const TString type = el->GetTypeNameBasic();
203
204 if (type=="int")
205 return GetMethodCall("Int", arroff+offset+off, proxy);
206 if (type=="Int_t")
207 return GetMethodCall("Int_t", arroff+offset+off, proxy);
208 if (type=="unisgned long long")
209 return GetMethodCall("ULongLong", arroff+offset+off, proxy);
210 if (type=="double")
211 {
212 cout << name << ": " << arroff << " " << offset << " " << off << " " << fPtr << endl;
213
214 return GetMethodCall("Double", arroff+offset+off, proxy);
215 }
216
217 if (p<0)
218 {
219 *fLog << err << dbginf << "ERROR - Variable name missing for " << nam << "." << type << " [" << clsname << "]" << endl;
220 return 0;
221 }
222
223 const TString var = arg(p+1, arg.Length());
224 return GetterMethod(var, type, arroff+offset+off);
225}
226
227// --------------------------------------------------------------------------
228//
229// Print the requested data from our memory using the streamer info.
230//
231void MParEmulated::Print(TPRegexp &regex, TString clsname, TString prefix, Int_t offset) const
232{
233 Int_t arroff = 0;
234
235#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
236 TStreamerInfo *info = GetStreamerInfo(clsname, arroff);
237#else
238 TVirtualStreamerInfo *info = GetStreamerInfo(clsname, arroff);
239#endif
240 if (!info)
241 return;
242
243 TIter Next(info->GetElements());
244 TStreamerElement *el = 0;
245 while ((el=(TStreamerElement*)Next()))
246 {
247 const TString str = prefix+el->GetName();
248
249 if (str(regex).IsNull())
250 continue;
251
252 if (el->InheritsFrom(TStreamerBasicType::Class()))
253 {
254 const TString type(el->GetTypeNameBasic());
255
256 cout << fName << (arroff?"[0]":"") << "." << str << " [" << type << "]" << " \t";
257 if (type=="int")
258 cout << GetInt(el->GetOffset()+arroff+offset);
259 if (type=="Int_t")
260 cout << GetInt_t(el->GetOffset()+arroff+offset);
261 if (type=="double")
262 cout << GetDouble(el->GetOffset()+arroff+offset);
263 if (type=="unsigned long long")
264 cout << GetULongLong(el->GetOffset()+arroff+offset);
265
266 cout << endl;
267 continue;
268 }
269
270 if (el->InheritsFrom(TStreamerObjectAny::Class()))
271 {
272 Print(regex, el->GetTypeNameBasic(), str+".",
273 el->GetOffset()+arroff+offset);
274 continue;
275 }
276 }
277}
Note: See TracBrowser for help on using the repository browser.