35 static TClass* IsSettableDataMember(TDataMember* dm) {
36 if (!dm || !dm->IsaPointer() || dm->IsBasic())
return 0;
37 TString dtTypeName = dm->GetFullTypeName();
38 if (!dtTypeName.EndsWith(
"*"))
return 0;
39 dtTypeName.Remove(dtTypeName.Length()-1);
40 return TClass::GetClass(dtTypeName);
43 class TSetSelDataMembers:
public TMemberInspector {
45 TSetSelDataMembers(
const TOutputListSelectorDataMap& owner, TCollection* dmInfo, TList* output);
46 using TMemberInspector::Inspect;
47 void Inspect(TClass *cl,
const char *parent,
const char *name,
const void *addr, Bool_t isTransient);
48 Ssiz_t GetNumSet()
const {
return fNumSet; }
53 const TOutputListSelectorDataMap& fOwner;
59 TSetSelDataMembers::TSetSelDataMembers(
const TOutputListSelectorDataMap& owner,
60 TCollection* dmInfo, TList* output):
61 fDMInfo(dmInfo), fOutputList(output), fNumSet(0), fOwner(owner)
73 void TSetSelDataMembers::Inspect(TClass *cl,
const char* parent,
const char *name,
const void *addr, Bool_t )
75 while (name[0] ==
'*') ++name;
77 TObject* mapping = fDMInfo->FindObject(name);
80 PDB(kOutput,1) fOwner.Info("SetDataMembers()",
81 "data member `%s%s::%s' maps to output list
object `%s'",
82 cl->GetName(), parent, name, mapping->GetTitle());
84 TObject* outputObj = fOutputList->FindObject(mapping->GetTitle());
86 PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
87 "
object `%s' not found in output list!",
93 TDataMember *dm = cl->GetDataMember(name);
94 TClass* cldt = IsSettableDataMember(dm);
96 PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
97 "unusable data member `%s' should have been detected by TCollectDataMembers!",
102 char *pointer = (
char*)addr;
103 char **ppointer = (
char**)(pointer);
106 fOwner.Warning(
"SetDataMembers()",
"potential memory leak: replacing data member `%s' != 0. "
107 "Please initialize %s to 0 in constructor %s::%s()",
108 name, name, cl->GetName(), cl->GetName());
110 *ppointer = (
char*)outputObj;
116 class TCollectDataMembers:
public TMemberInspector {
118 TCollectDataMembers(
const TOutputListSelectorDataMap& owner): fOwner(owner) { }
119 ~TCollectDataMembers();
120 using TMemberInspector::Inspect;
121 void Inspect(TClass *cl,
const char *parent,
const char *name,
const void *addr, Bool_t isTransient);
122 TExMap& GetMemberPointers() {
return fMap; }
125 const TOutputListSelectorDataMap& fOwner;
138 void TCollectDataMembers::Inspect(TClass *cl,
const char* ,
const char *name,
const void *addr, Bool_t )
140 TDataMember *dm = cl->GetDataMember(name);
141 if (!IsSettableDataMember(dm))
return;
143 char *pointer = (
char*)addr;
144 char **ppointer = (
char**)(pointer);
145 char **p3pointer = (
char**)(*ppointer);
149 TObject* prev = (TObject*) (ptrdiff_t)fMap.GetValue((Long64_t)(ptrdiff_t)p3pointer);
152 if (prev->InheritsFrom(TDataMember::Class())) {
153 fMap.Remove((Long64_t)(ptrdiff_t)p3pointer);
154 TList* dmList =
new TList;
157 fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dmList);
159 TList* prevList = (TList*) prev;
163 fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dm);
165 if (name[0] ==
'*') ++name;
166 PDB(kOutput,1) fOwner.Info("Init()", "considering data member `%s'", name);
170 TCollectDataMembers::~TCollectDataMembers() {
174 TExMapIter iMembers(&fMap);
177 while (iMembers.Next(key, value)) {
178 TObject* obj = (TObject*) (ptrdiff_t) value;
179 if (obj->InheritsFrom(TList::Class())) {
185 ClassImp(TOutputListSelectorDataMap);
190 TOutputListSelectorDataMap::TOutputListSelectorDataMap(TSelector* sel ):
199 const char* TOutputListSelectorDataMap::GetName()
const
201 return "PROOF_TOutputListSelectorDataMap_object";
207 Bool_t TOutputListSelectorDataMap::Init(TSelector* sel)
210 PDB(kOutput,1) Warning("Init","Leave (no selector!)");
213 TCollection* outList = sel->GetOutputList();
215 PDB(kOutput,1) Info("Init()","Leave (no output)");
219 if (outList->FindObject(GetName())) {
221 PDB(kOutput,1) Warning("Init","Mapping already exists!");
225 if (fMap) delete fMap;
226 fMap = new THashTable;
229 TCollectDataMembers cdm(*this);
230 if (!sel->IsA()->CallShowMembers(sel, cdm)) {
232 PDB(kOutput,1) Warning("Init","Failed to determine mapping!");
235 PDB(kOutput,1) Info("Init()","Found %d data members.",
236 cdm.GetMemberPointers().GetSize());
240 TIter iOutput(outList);
243 while ((output = iOutput())) {
244 TObject* obj = (TObject*) (ptrdiff_t)cdm.GetMemberPointers().GetValue((Long64_t)(ptrdiff_t)output);
248 if (obj->InheritsFrom(TDataMember::Class())) {
252 addAllDM = (TList*) obj;
256 while ((dm = (TDataMember*) iDM())) {
257 fMap->Add(
new TNamed(dm->GetName(), output->GetName()));
258 PDB(kOutput,1) Info("Init()","Data member `%s' corresponds to output `%s'",
259 dm->GetName(), output->GetName());
270 Bool_t TOutputListSelectorDataMap::SetDataMembers(TSelector* sel)
const
272 TList* output = sel->GetOutputList();
273 if (!output || output->IsEmpty())
return kTRUE;
276 TSetSelDataMembers ssdm(*
this, fMap, output);
277 Bool_t res = sel->IsA()->CallShowMembers(sel, ssdm);
278 PDB(kOutput,1) Info("SetDataMembers()","%s, set %d data members.",
279 (res ? "success" : "failure"), ssdm.GetNumSet());
287 Bool_t TOutputListSelectorDataMap::Merge(TObject* obj)
289 TOutputListSelectorDataMap* other =
dynamic_cast<TOutputListSelectorDataMap*
>(obj);
290 if (!other)
return kFALSE;
293 TIter iMapping(other->GetMap());
295 while ((mapping = (TNamed*)iMapping())) {
296 TObject* oldMap = fMap->FindObject(mapping->GetName());
298 fMap->Add(
new TNamed(*mapping));
300 if (strcmp(oldMap->GetTitle(), mapping->GetTitle())) {
304 "contradicting mapping for data member `%s' (output list entry `%s' vs. `%s'). "
305 "Cancelling automatic TSelector data member setting!",
306 mapping->GetName(), oldMap->GetTitle(), mapping->GetTitle());
318 TOutputListSelectorDataMap* TOutputListSelectorDataMap::FindInList(TCollection* coll)
322 TOutputListSelectorDataMap* olsdm = 0;
323 while ((out = iOutput())) {
324 if (out->InheritsFrom(TOutputListSelectorDataMap::Class())) {
325 olsdm =
dynamic_cast<TOutputListSelectorDataMap*
>(out);