Diana Software
QObjectInspector.cc
Go to the documentation of this file.
1 #include "QObjectInspector.hh"
2 #include "QObject.hh"
3 #include "TDataMember.h"
4 #include "TClass.h"
5 #include <sstream>
6 
7 
9 
11 {
12 }
13 
15 {
16  MemberInfo info;
17  info.fAddress = 0;
18  info.fType = "Unknown";
19  info.fBranchType = "Unknown";
20  info.fStringValue = "Unknown";
21 #if ROOT_VERSION_CODE < ROOT_VERSION(5,28,0)
22  char parent[512];
23  parent[0] = 0;
24  obj->ShowMembers(*this,parent);
25 #else
26  obj->ShowMembers(*this);
27 #endif
28  std::map<std::string, MemberInfo>::const_iterator iter = fBaseTypeMembers.find(member);
29  if(iter != fBaseTypeMembers.end()) info = iter->second;
30  return info;
31 
32 }
33 
34 QError QObjectInspector::DumpOnStream(const QObject* obj, std::ostream& str)
35 {
36  // work around const...
37  void** vobj = (void**)&obj;
38  QObject* vvobj = (QObject*) *vobj;
39 
40 #if ROOT_VERSION_CODE < ROOT_VERSION(5,28,0)
41  char parent[512];
42  parent[0] = 0;
43  vvobj->ShowMembers(*this,parent);
44 #else
45  vvobj->ShowMembers(*this);
46 #endif
47 
49  std::map<std::string, MemberInfo>::const_iterator iter;
50 
51  if(!fOtherMembers.empty()) {
53  std::stringstream msg;
54  if(fOtherMembers.size() > 1) msg<<"Members ";
55  else msg<<"Member ";
56  iter = fOtherMembers.begin();
57  while(iter != fOtherMembers.end()) {
58  msg<<iter->first<<"("<<iter->second.fType<<")"<<" ";
59  iter++;
60  }
61  msg<<" cannot be handled by QObjectInspector. Implement the WriteOnStream method of this QObject!";
62  err.SetDescription(__FILE__,__LINE__,msg.str());
63  }
64 
65 
66 
67  iter = fBaseTypeMembers.begin();
68  while(iter != fBaseTypeMembers.end()) {
69  str<<iter->first<<" "<<iter->second.fStringValue<<std::endl;
70  iter++;
71  }
72 
73  return err;
74 
75 }
76 
78 {
79 
80  obj->Clear();
82 #if ROOT_VERSION_CODE < ROOT_VERSION(5,28,0)
83  char parent[512];
84  parent[0] = 0;
85  obj->ShowMembers(*this,parent);
86 #else
87  obj->ShowMembers(*this);
88 #endif
89 
90 
91  if(!fOtherMembers.empty()) {
93  std::stringstream msg;
94  if(fOtherMembers.size() > 1) msg<<"Members ";
95  else msg<<"Member ";
96  std::map<std::string, MemberInfo>::const_iterator iter = fOtherMembers.begin();
97  while(iter != fOtherMembers.end()) {
98  msg<<iter->first<<" ";
99  iter++;
100  }
101  msg<<" cannot be handled by QObjectInspector. Implement the ReadFromStream method of this QObject!";
102  err.SetDescription(__FILE__,__LINE__,msg.str());
103  }
104 
105 
106  std::map<std::string,std::string> parValueMap;
107  std::string line;
108  while(getline(in, line)) {
109  if(in.fail()) break;
110  std::stringstream stream(line);
111  std::string label,value;
112  stream>>label>>value;
113  while(stream.good()) {
114  std::string newval;
115  stream>>newval;
116  value += " " + newval;
117  }
118  parValueMap[label]=value;
119  }
120 
121  std::map<std::string, MemberInfo>::iterator iter = fBaseTypeMembers.begin();
122  while(iter != fBaseTypeMembers.end()) {
123  if(parValueMap.find(iter->first) != parValueMap.end()) {
124  if(iter->second.fIsPointer) {
125  int size = atoi(parValueMap.find(iter->second.fLengthMember)->second.c_str());
126  Resize(iter->second,size);
127 
128  std::stringstream str;
129  str<<parValueMap[iter->first];
130  std::string value;
131  for(int i = 0; i < size; i++) {
132  str>>value;
133  char** apos = (char**) (iter->second.fAddress);
134  char* pos = *apos;
135  pos += (i*iter->second.fMemberSize);
136  Assign(pos,iter->second.fEDataType,value);
137 
138  }
139  } else if(iter->second.fType == "string") {
140  (*(std::string*)iter->second.fAddress) = parValueMap[iter->first];
141  } else {
142  Assign(iter->second.fAddress,iter->second.fEDataType,parValueMap[iter->first]);
143 
144  }
145 
146  } else {
148  std::stringstream msg;
149  msg<<"Member \""<<iter->first<<"\" not found";
150  err.SetDescription(msg.str());
151  }
152  iter++;
153  }
154 
155  return err;
156 }
157 
158 
159 void QObjectInspector::Inspect(TClass* cl, const char* parent, const char* mname, const void* addr)
160 {
161  TDataMember *member = cl->GetDataMember(mname) ;
162 // std::cout<<"BBBB: "<<lastParent<<" "<<parent<<std::endl;
163  if (member != 0) {
164  std::string memberTypeName = member->GetTypeName();
165  std::string memberName = member->GetName();
166  std::string fullName = std::string(parent) + memberName;
167  bool isapointer = member->IsaPointer();
168  bool isbasic = member->IsBasic();
169  bool ispersistent = member->IsPersistent();
170  bool isQObject = 0;
171  TDataType* membertype = member->GetDataType();
172  MemberInfo info;
173  TClass* classa = TClass::GetClass(memberTypeName.c_str(),kTRUE, kTRUE);
174  if(classa && classa->InheritsFrom("TObject")) isQObject = 1;
175  // std::cout<<"AAA Parent: "<<parent<<" Member: "<<fullName<<" QObject: "<<isQObject<<" Type: "<<memberTypeName<<std::endl;
176  info.fType = memberTypeName;
177  info.fAddress = (void*)addr;
178  info.fIsPointer = isapointer;
179  info.fSize = -1;
180  info.fIsQObject = isQObject;
181  if(isQObject ) {
182  // do nothing
183  } else if(isbasic && ispersistent && memberName != "fBits" && memberName != "fUniqueID") {
184  info.fBranchType = TypeToBranchType((EDataType) membertype->GetType());
185  info.fEDataType = (EDataType) membertype->GetType();
186  info.fMemberSize = membertype->Size();;
187  if(isapointer) {
188  info.fLengthMember = std::string(parent) + member->GetArrayIndex();
189 
190  QVdt vsize = fBaseTypeMembers[info.fLengthMember].fStringValue;
191  int size = vsize.GetInt();
192  info.fStringValue = "";
193  for(int i =0; i < size; i++) {
194  info.fStringValue += " ";
195  char** apos = (char**) (info.fAddress);
196  char* pos = *apos;
197  pos += (i*membertype->Size());
198  info.fStringValue += membertype->AsString((void*)pos);
199  }
200 
201  info.fSize = size;
202 
203  } else {
204  info.fStringValue = membertype->AsString(info.fAddress);
205  }
206  fBaseTypeMembers[fullName] = info;
207  } else if(ispersistent && memberName != "fBits" && memberName != "fUniqueID") {
208  if(info.fType == "string") {
209  info.fStringValue = *(std::string*)(info.fAddress);
210  fBaseTypeMembers[fullName] = info;
211  } else {
212  // std::cout<<"AAAAAAAA: "<<membertype->GetName()<<" "<<info.fAddress<<" val: "<<info.fStringValue<<std::endl;
213  fOtherMembers[fullName] = info;
214  }
215 
216  }
217  }
218 }
219 
220 
221 std::string QObjectInspector::TypeToBranchType(EDataType mtypes)
222 {
223  std::string stringType = "Unknown";
224  switch(mtypes) {
225  case kChar_t:
226  stringType = "B"; // an 8 bit signed integer
227  break;
228  case kUChar_t:
229  stringType = "b"; // an 8 bit unsigned integer
230  break;
231  case kShort_t:
232  stringType = "S"; // a 16 bit signed integer
233  break;
234  case kUShort_t:
235  stringType = "s"; // a 16 bit unsigned integer
236  break;
237  case kInt_t:
238  stringType = "I"; // a 32 bit signed integer
239  break;
240  case kUInt_t:
241  stringType = "i"; // a 32 bit unsigned integer
242  break;
243  case kFloat_t:
244  stringType = "F"; // a 32 bit floating point
245  break;
246  case kDouble_t:
247  stringType = "D"; // a 64 bit floating point
248  break;
249  case kLong64_t:
250  stringType = "L"; // a 64 bit signed integer
251  break;
252  case kULong64_t:
253  stringType = "l"; // a 64 bit unsigned integer
254  break;
255  case kBool_t:
256  stringType = "O"; // a boolean
257  break;
258  default:
259  stringType = "Unknown";
260  break;
261  }
262  return stringType;
263 }
264 
265 void QObjectInspector::Assign(void* addr,EDataType dataType,const std::string& value)
266 {
267  switch(dataType) {
268  case kChar_t:
269  if(!value.empty())
270  (*(char*)addr) = value[0];
271  else
272  (*(char*)addr) = '\0';
273  break;
274  case kUChar_t:
275  if(!value.empty())
276  (*(unsigned char*)addr) = value[0];
277  else
278  (*(unsigned char*)addr) = '\0';
279  break;
280  case kShort_t:
281  if(!value.empty())
282  (*(short*)addr) = atoi(value.c_str());
283  else
284  (*(short*)addr) = Q_SHORT_DEFAULT;
285  break;
286  case kUShort_t:
287  if(!value.empty())
288  (*(unsigned short*)addr) = atoi(value.c_str());
289  else
290  (*(unsigned short*)addr) = Q_SHORT_DEFAULT;
291  break;
292  case kInt_t:
293  if(!value.empty())
294  (*(int*)addr) = atoi(value.c_str());
295  else
296  (*(int*)addr) = Q_INT_DEFAULT;
297  break;
298  case kUInt_t:
299  if(!value.empty())
300  (*(unsigned int*)addr) = atoi(value.c_str());
301  else
302  (*(unsigned int*)addr) = Q_INT_DEFAULT;
303  break;
304  case kFloat_t:
305  if(!value.empty())
306  (*(float*)addr) = atof(value.c_str());
307  else
308  (*(float*)addr) = Q_DOUBLE_DEFAULT;
309  break;
310  case kDouble_t:
311  if(!value.empty())
312  (*(double*)addr) = atof(value.c_str());
313  else
314  (*(double*)addr) = Q_DOUBLE_DEFAULT;
315  break;
316  case kLong64_t:
317  if(!value.empty())
318  (*(Long64_t*)addr) = atoi(value.c_str());
319  else
320  (*(Long64_t*)addr) = Q_INT_DEFAULT;
321  break;
322  case kULong64_t:
323  if(!value.empty())
324  (*(Long64_t*)addr) = atoi(value.c_str());
325  else
326  (*(Long64_t*)addr) = Q_INT_DEFAULT;
327  break;
328  case kBool_t:
329  if(!value.empty())
330  (*(bool*)addr) = atoi(value.c_str());
331  else
332  (*(bool*)addr) = Q_INT_DEFAULT;
333  break;
334  default:
335  break;
336  }
337 
338 }
339 
341 {
342  switch(info.fEDataType) {
343  case kChar_t:
344  {
345  char** oaddr = (char**)info.fAddress;
346  char* addr = (char*)*oaddr;
347  if(addr) delete [] addr;
348  *oaddr = new char[size];
349  break;
350  }
351  case kUChar_t:
352  {
353  unsigned char** oaddr = (unsigned char**)info.fAddress;
354  unsigned char* addr = (unsigned char*)*oaddr;
355  if(addr) delete [] addr;
356  *oaddr = new unsigned char[size];
357  break;
358  }
359  case kShort_t:
360  {
361  short** oaddr = (short**)info.fAddress;
362  short* addr = (short*)*oaddr;
363  if(addr) delete [] addr;
364  *oaddr = new short[size];
365  break;
366  }
367  case kUShort_t:
368  {
369  unsigned short** oaddr = (unsigned short**)info.fAddress;
370  unsigned short* addr = (unsigned short*)*oaddr;
371  if(addr) delete [] addr;
372  *oaddr = new unsigned short[size];
373  break;
374  }
375  case kInt_t:
376  {
377  int** oaddr = (int**)info.fAddress;
378  int* addr = (int*)*oaddr;
379  if(addr) delete [] addr;
380  *oaddr = new int[size];
381  break;
382  }
383  case kUInt_t:
384  {
385  unsigned int** oaddr = (unsigned int**)info.fAddress;
386  unsigned int* addr = (unsigned int*)*oaddr;
387  if(addr) delete [] addr;
388  *oaddr = new unsigned int[size];
389  break;
390  }
391  case kFloat_t:
392  {
393  float** oaddr = (float**)info.fAddress;
394  float* addr = (float*)*oaddr;
395  if(addr) delete [] addr;
396  *oaddr = new float[size];
397  break;
398  }
399  case kDouble_t:
400  {
401  double** oaddr = (double**)info.fAddress;
402  double* addr = *oaddr;
403  if(addr) delete [] addr;
404  *oaddr = new double[size];
405  break;
406  }
407  case kLong64_t:
408  {
409  Long64_t** oaddr = (Long64_t**)info.fAddress;
410  Long64_t* addr = *oaddr;
411  if(addr) delete [] addr;
412  *oaddr = new Long64_t[size];
413  break;
414  }
415  case kULong64_t:
416  {
417  ULong64_t** oaddr = (ULong64_t**)info.fAddress;
418  ULong64_t* addr = (ULong64_t*)*oaddr;
419  if(addr) delete [] addr;
420  *oaddr = new ULong64_t[size];
421  break;
422  }
423  case kBool_t:
424  {
425 
426  bool** oaddr = (bool**)info.fAddress;
427  bool* addr = (bool*)*oaddr;
428  if(addr) delete [] addr;
429  *oaddr = new bool[size];
430  break;
431  }
432  default:
433  break;
434  }
435 
436 }
437 
err
Definition: CheckOF.C:114
#define Q_DOUBLE_DEFAULT
Definition: QDiana.hh:24
#define Q_END_NAMESPACE
Definition: QDiana.hh:22
#define Q_SHORT_DEFAULT
Definition: QDiana.hh:28
#define Q_BEGIN_NAMESPACE
Definition: QDiana.hh:20
#define Q_INT_DEFAULT
Definition: QDiana.hh:26
@ QERR_UNKNOWN_ERR
Definition: QError.hh:108
@ QERR_SUCCESS
Definition: QError.hh:27
error class with error type and description
Definition: QError.hh:115
virtual void Inspect(TClass *cl, const char *parent, const char *mname, const void *addr)
void Resize(MemberInfo &info, int size)
std::map< std::string, MemberInfo > fBaseTypeMembers
MemberInfo FindBaseType(QObject *obj, const char *member)
std::string TypeToBranchType(EDataType mtypes)
std::map< std::string, MemberInfo > fOtherMembers
QError DumpOnStream(const QObject *obj, std::ostream &str)
QError FillFromStream(QObject *obj, std::istream &in)
void Assign(void *addr, EDataType dataType, const std::string &value)
base class for objects handled by QEvent and QGlobalDataManager.
Definition: QObject.hh:76
virtual void Clear()=0
reset members to default values
Variable Data Type.
Definition: QVdt.hh:26
long int GetInt() const
Definition: QVdt.cc:213