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