Belle II Software development
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
24using namespace Belle2;
25
26TString HtmlClassInspector::getMemberData(const TObject* obj)
27{
29 const_cast<TObject*>(obj)->ShowMembers(dm);
30 return dm.getTable();
31}
32
33TString 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
46TString 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}
64void 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.