Belle II Software  release-05-01-25
HtmlClassInspector.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Christian Pulvermacher *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <display/HtmlClassInspector.h>
12 
13 #include <framework/utilities/HTML.h>
14 
15 #include <TClass.h>
16 #include <TClassRef.h>
17 #include <TDataType.h>
18 #include <TDataMember.h>
19 #include <TROOT.h>
20 #include <TStreamerElement.h>
21 #include <TVirtualStreamerInfo.h>
22 
23 #include <string>
24 
25 using namespace Belle2;
26 
27 TString HtmlClassInspector::getMemberData(const TObject* obj)
28 {
30  const_cast<TObject*>(obj)->ShowMembers(dm);
31  return dm.getTable();
32 }
33 
34 TString HtmlClassInspector::getClassInfo(const TClass* cl)
35 {
36  if (!cl)
37  return "";
38  TString info;
39  info += "<b>";
40  info += HTML::htmlToPlainText(cl->GetName());
41  info += "</b> (";
42 
43  TString title(HTML::htmlToPlainText(stripTitle(cl->GetTitle()).Data()));
44  return info + title + ")<br> <br>";
45 }
46 
47 TString HtmlClassInspector::stripTitle(TString title)
48 {
49  title = title.Strip(TString::kBoth, '/');
50  title = title.Strip(TString::kBoth, '*');
51  title = title.Strip(TString::kLeading, '!');
52  title = title.Strip(TString::kLeading, '<');
53  title = title.Strip(TString::kBoth, ' ');
54  return title;
55 }
56 
58 {
59  TString tmp;
60  tmp += "<table width=100% cellpadding=2 bgcolor=eeeeee>";
61  tmp += m_info;
62  tmp += "</table>";
63  return tmp;
64 }
65 void HtmlClassInspector::Inspect(TClass* cl, const char* pname, const char* mname, const void* add)
66 {
67  // Print value of member mname.
68  //
69  // This method is called by the ShowMembers() method for each
70  // data member when object.Dump() is invoked.
71  //
72  // cl is the pointer to the current class
73  // pname is the parent name (in case of composed objects)
74  // mname is the data member name
75  // add is the data member address
76 
77  const Int_t kvalue = 30;
78  const Int_t kline = 1024;
79  Int_t cdate = 0;
80  Int_t ctime = 0;
81  UInt_t* cdatime;
82  char line[kline];
83 
84  TDataType* membertype;
85  TString memberTypeName;
86  TString memberName;
87  const char* memberFullTypeName;
88  TString memberTitle;
89  Bool_t isapointer;
90  Bool_t isbasic;
91 
92  if (TDataMember* member = cl->GetDataMember(mname)) {
93  memberTypeName = member->GetTypeName();
94  memberName = member->GetName();
95  memberFullTypeName = member->GetFullTypeName();
96  memberTitle = member->GetTitle();
97  isapointer = member->IsaPointer();
98  isbasic = member->IsBasic();
99  membertype = member->GetDataType();
100  } else if (!cl->IsLoaded()) {
101  // The class is not loaded, hence it is 'emulated' and the main source of
102  // information is the StreamerInfo.
103  TVirtualStreamerInfo* info = cl->GetStreamerInfo();
104  if (!info) return;
105  const char* cursor = mname;
106  while ((*cursor) == '*') ++cursor;
107  TString elname(cursor);
108  Ssiz_t pos = elname.Index("[");
109  if (pos != kNPOS) {
110  elname.Remove(pos);
111  }
112  TStreamerElement* element = (TStreamerElement*)info->GetElements()->FindObject(elname.Data());
113  if (!element) return;
114  memberFullTypeName = element->GetTypeName();
115 
116  memberTypeName = memberFullTypeName;
117  memberTypeName = memberTypeName.Strip(TString::kTrailing, '*');
118  if (memberTypeName.Index("const ") == 0) memberTypeName.Remove(0, 6);
119 
120  memberName = element->GetName();
121  memberTitle = element->GetTitle();
122  isapointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;
123  membertype = gROOT->GetType(memberFullTypeName);
124 
125  isbasic = membertype != 0;
126  } else {
127  return;
128  }
129 
130 
131  Bool_t isdate = kFALSE;
132  if (strcmp(memberName, "fDatime") == 0 && strcmp(memberTypeName, "UInt_t") == 0) {
133  isdate = kTRUE;
134  }
135  Bool_t isbits = kFALSE;
136  if (strcmp(memberName, "fBits") == 0 && strcmp(memberTypeName, "UInt_t") == 0) {
137  isbits = kTRUE;
138  }
139  TClass* dataClass = TClass::GetClass(memberFullTypeName);
140  Bool_t isTString = (dataClass == TString::Class());
141  static TClassRef stdClass("std::string");
142  Bool_t isStdString = (dataClass == stdClass);
143 
144  Int_t i;
145  for (i = 0; i < kline; i++) line[i] = ' ';
146  line[kline - 1] = 0;
147  //snprintf(line,kline,"%s%s ",pname,mname);
148  //i = strlen(line); line[i] = ' ';
149 
150  // Encode data value or pointer value
151  char* pointer = (char*)add;
152  char** ppointer = (char**)(pointer);
153 
154  if (isapointer) {
155  char** p3pointer = (char**)(*ppointer);
156  if (!p3pointer)
157  snprintf(&line[kvalue], kline - kvalue, "->0");
158  else if (!isbasic)
159  snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)p3pointer);
160  else if (membertype) {
161  if (!strcmp(membertype->GetTypeName(), "char")) {
162  i = strlen(*ppointer);
163  if (kvalue + i > kline) i = kline - 1 - kvalue;
164  Bool_t isPrintable = kTRUE;
165  for (Int_t j = 0; j < i; j++) {
166  if (!std::isprint((*ppointer)[j])) {
167  isPrintable = kFALSE;
168  break;
169  }
170  }
171  if (isPrintable) {
172  //strncpy(line + kvalue, *ppointer, i);
173  std::string out(*ppointer);
174  out.copy(line + kvalue, i);
175  line[kvalue + i] = 0;
176  } else {
177  line[kvalue] = 0;
178  }
179  } else {
180  strncpy(&line[kvalue], membertype->AsString(p3pointer), TMath::Min(kline - 1 - kvalue,
181  (int)strlen(membertype->AsString(p3pointer))));
182  }
183  } else if (!strcmp(memberFullTypeName, "char*") ||
184  !strcmp(memberFullTypeName, "const char*")) {
185  i = strlen(*ppointer);
186  if (kvalue + i >= kline) i = kline - 1 - kvalue;
187  Bool_t isPrintable = kTRUE;
188  for (Int_t j = 0; j < i; j++) {
189  if (!std::isprint((*ppointer)[j])) {
190  isPrintable = kFALSE;
191  break;
192  }
193  }
194  if (isPrintable) {
195  std::string out(*ppointer);
196  out.copy(line + kvalue, i);
197  //strncpy(line + kvalue, *ppointer, i); //
198 
199  line[kvalue + i] = 0;
200  } else {
201  line[kvalue] = 0;
202  }
203  } else {
204  snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)p3pointer);
205  }
206  } else if (membertype) {
207  if (isdate) {
208  cdatime = (UInt_t*)pointer;
209  TDatime::GetDateTime(cdatime[0], cdate, ctime);
210  snprintf(&line[kvalue], kline - kvalue, "%d/%d", cdate, ctime);
211  } else if (isbits) {
212  snprintf(&line[kvalue], kline - kvalue, "0x%08x", *(UInt_t*)pointer);
213  } else {
214  strncpy(&line[kvalue], membertype->AsString(pointer), TMath::Min(kline - 1 - kvalue, (int)strlen(membertype->AsString(pointer))));
215  }
216  } else {
217  if (isStdString) {
218  std::string* str = (std::string*)pointer;
219  snprintf(&line[kvalue], kline - kvalue, "%s", str->c_str());
220  } else if (isTString) {
221  TString* str = (TString*)pointer;
222  snprintf(&line[kvalue], kline - kvalue, "%s", str->Data());
223  } else {
224  snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)pointer);
225  }
226  }
227 
228 
229  m_info += "<tr>";
230  TString indent;
231  if (TString(pname) != "") //indent nested members
232  indent = "&nbsp;&nbsp;&nbsp;";
233  m_info += "<td><b>" + indent + HTML::htmlToPlainText(memberName.Data()) + "</b><br>";
234  m_info += indent + "<small>" + HTML::htmlToPlainText(stripTitle(memberTitle).Data()) + "</small>";
235  m_info += "</td>";
236 
237  TString memberValue(HTML::htmlToPlainText(line));
238  m_info += "<td align=right>" + memberValue + "</td>";
239  m_info += "</tr>";
240 }
Belle2::HTML::htmlToPlainText
std::string htmlToPlainText(const std::string &html)
Reformat given HTML string into terminal-friendly plain text.
Definition: HTML.cc:132
Belle2::HtmlClassInspector::stripTitle
static TString stripTitle(TString title)
strip comment things
Definition: HtmlClassInspector.cc:47
Belle2::HtmlClassInspector::getMemberData
static TString getMemberData(const TObject *obj)
Return table with member data contents.
Definition: HtmlClassInspector.cc:27
Belle2::HtmlClassInspector::m_info
TString m_info
used to store output.
Definition: HtmlClassInspector.h:50
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::HtmlClassInspector::Inspect
void Inspect(TClass *cl, const char *pname, const char *mname, const void *add) override
Implementation mostly copied from TDumpMembers.
Definition: HtmlClassInspector.cc:65
Belle2::HtmlClassInspector
Pass to TObject::ShowMembers() to get tabular view of object data.
Definition: HtmlClassInspector.h:30
Belle2::HtmlClassInspector::getTable
TString getTable() const
Return finished table.
Definition: HtmlClassInspector.cc:57
Belle2::HtmlClassInspector::getClassInfo
static TString getClassInfo(const TClass *obj)
Get class name + description from comment after ClassDef().
Definition: HtmlClassInspector.cc:34