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

Last change on this file since 9492 was 9302, 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
52#include "MString.h"
53
54ClassImp(MParEmulated);
55
56using namespace std;
57
58// --------------------------------------------------------------------------
59//
60// Default constructor.
61//
62MParEmulated::MParEmulated(const char *name, const char *title)
63 : fPtr(0)
64{
65 fName = name ? name : "MParEmulated";
66 fTitle = title ? title : "Parameter container emulating a class";
67}
68
69// --------------------------------------------------------------------------
70//
71// The default is to print all emulated data members. If an option is
72// given it is interpreted as TPRegexp (regular expression) and only
73// data members matching this regex are printed.
74//
75void MParEmulated::Print(Option_t *o) const
76{
77 TString opt(o);
78 if (opt.IsNull())
79 opt = ".*";
80
81 TPRegexp regex(opt);
82 Print(regex, fClassName, "", 0);
83}
84
85int MParEmulated::GetPInt(TVirtualCollectionProxy *proxy, Int_t offset) const
86{
87 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
88 return *reinterpret_cast<int*>((char*)proxy->At(0)+offset);
89}
90Int_t MParEmulated::GetPInt_t(TVirtualCollectionProxy *proxy, Int_t offset) const
91{
92 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
93 return *reinterpret_cast<Int_t*>((char*)proxy->At(0)+offset);
94}
95double MParEmulated::GetPDouble(TVirtualCollectionProxy *proxy, Int_t offset) const
96{
97 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
98 return *reinterpret_cast<double*>((char*)proxy->At(0)+offset);
99}
100unsigned long long MParEmulated::GetPULongLong(TVirtualCollectionProxy *proxy, Int_t offset) const
101{
102 const TVirtualCollectionProxy::TPushPop pp(proxy, fPtr);
103 return *reinterpret_cast<unsigned long long*>((char*)proxy->At(0)+offset);
104}
105
106// --------------------------------------------------------------------------
107//
108// Get the class with name clsname and its corresponding streamer info
109//
110#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
111TStreamerInfo *MParEmulated::GetStreamerInfo(const TString &clsname, TVirtualCollectionProxy * &proxy, Int_t &offset) const
112#else
113TVirtualStreamerInfo *MParEmulated::GetStreamerInfo(const TString &clsname, TVirtualCollectionProxy * &proxy, Int_t &offset) const
114#endif
115{
116 TClass *cls = gROOT->GetClass(clsname);
117 if (!cls)
118 {
119 *fLog << err << dbginf << "ERROR - Class " << clsname << " not in dictionary." << endl;
120 return 0;
121 }
122
123 proxy = cls->GetCollectionProxy();
124 if (proxy)
125 {
126 cls = proxy->GetValueClass();
127
128 proxy->PushProxy(fPtr);
129 // proxy->GetSize() // Number of elements in array
130 if (proxy->At(0))
131 offset = (char*)proxy->At(0)-(char*)fPtr;
132 proxy->PopProxy();
133
134 }
135
136#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
137 TStreamerInfo *info = cls->GetStreamerInfo();
138#else
139 TVirtualStreamerInfo *info = cls->GetStreamerInfo();
140#endif
141 if (!info)
142 {
143 *fLog << err << dbginf << "ERROR - No TStreamerInfo for class " << clsname << "." << endl;
144 return 0;
145 }
146
147 return info;
148}
149
150// --------------------------------------------------------------------------
151//
152// Get the method call for the given method and offset, add method to
153// MParContainer::fgListmethodCall
154//
155TMethodCall *MParEmulated::GetMethodCall(const char *get, Int_t offset, TVirtualCollectionProxy *proxy) const
156{
157 TString name(get);
158 if (proxy)
159 name.Prepend("P");
160 name.Prepend("Get");
161
162 TMethodCall *call = new TMethodCall(MParEmulated::Class(), name, proxy?MString::Format("%p,%d", proxy, offset):MString::Format("%d", offset));
163 fgListMethodCall.Add(call);
164 return call;
165}
166
167// --------------------------------------------------------------------------
168//
169// Get the getter method for the given data member. Since we have no real
170// getter methods and no real data members we have to fake the TMethodCall.
171//
172TMethodCall *MParEmulated::GetterMethod(const char *name, TString clsname, Int_t offset) const
173{
174 TVirtualCollectionProxy *proxy = 0;
175
176 // Get the streamer info for the class and the offset to the
177 // first element of a possible array
178 Int_t arroff = 0;
179
180#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
181 TStreamerInfo *info = GetStreamerInfo(clsname, proxy, arroff);
182#else
183 TVirtualStreamerInfo *info = GetStreamerInfo(clsname, proxy, arroff);
184#endif
185 if (!info)
186 return 0;
187
188 const TString arg(name);
189
190 const Ssiz_t p = arg.Last('.');
191
192 const TString nam = p<0 ? arg : arg(0, p);
193
194 // Get the streamer element to the data member and
195 // and the offset from the base of the object
196 Int_t off;
197 TStreamerElement *el = info->GetStreamerElement(nam, off);
198 if (!el)
199 {
200 *fLog << err << dbginf << "ERROR - No TStreamerElement for " << nam << " [" << clsname << "]" << endl;
201 return 0;
202 }
203
204 const TString type = el->GetTypeNameBasic();
205
206 if (type=="int")
207 return GetMethodCall("Int", arroff+offset+off, proxy);
208 if (type=="Int_t")
209 return GetMethodCall("Int_t", arroff+offset+off, proxy);
210 if (type=="unisgned long long")
211 return GetMethodCall("ULongLong", arroff+offset+off, proxy);
212 if (type=="double")
213 {
214 cout << name << ": " << arroff << " " << offset << " " << off << " " << fPtr << endl;
215
216 return GetMethodCall("Double", arroff+offset+off, proxy);
217 }
218
219 if (p<0)
220 {
221 *fLog << err << dbginf << "ERROR - Variable name missing for " << nam << "." << type << " [" << clsname << "]" << endl;
222 return 0;
223 }
224
225 const TString var = arg(p+1, arg.Length());
226 return GetterMethod(var, type, arroff+offset+off);
227}
228
229// --------------------------------------------------------------------------
230//
231// Print the requested data from our memory using the streamer info.
232//
233void MParEmulated::Print(TPRegexp &regex, TString clsname, TString prefix, Int_t offset) const
234{
235 Int_t arroff = 0;
236
237#if ROOT_VERSION_CODE<ROOT_VERSION(5,18,00)
238 TStreamerInfo *info = GetStreamerInfo(clsname, arroff);
239#else
240 TVirtualStreamerInfo *info = GetStreamerInfo(clsname, arroff);
241#endif
242 if (!info)
243 return;
244
245 TIter Next(info->GetElements());
246 TStreamerElement *el = 0;
247 while ((el=(TStreamerElement*)Next()))
248 {
249 const TString str = prefix+el->GetName();
250
251 if (str(regex).IsNull())
252 continue;
253
254 if (el->InheritsFrom(TStreamerBasicType::Class()))
255 {
256 const TString type(el->GetTypeNameBasic());
257
258 cout << fName << (arroff?"[0]":"") << "." << str << " [" << type << "]" << " \t";
259 if (type=="int")
260 cout << GetInt(el->GetOffset()+arroff+offset);
261 if (type=="Int_t")
262 cout << GetInt_t(el->GetOffset()+arroff+offset);
263 if (type=="double")
264 cout << GetDouble(el->GetOffset()+arroff+offset);
265 if (type=="unsigned long long")
266 cout << GetULongLong(el->GetOffset()+arroff+offset);
267
268 cout << endl;
269 continue;
270 }
271
272 if (el->InheritsFrom(TStreamerObjectAny::Class()))
273 {
274 Print(regex, el->GetTypeNameBasic(), str+".",
275 el->GetOffset()+arroff+offset);
276 continue;
277 }
278 }
279}
Note: See TracBrowser for help on using the repository browser.