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 char line[kline];
81
82 TDataType* membertype;
83 TString memberTypeName;
84 TString memberName;
85 const char* memberFullTypeName;
86 TString memberTitle;
87 Bool_t isapointer;
88 Bool_t isbasic;
89
90 if (TDataMember* member = cl->GetDataMember(mname)) {
91 memberTypeName = member->GetTypeName();
92 memberName = member->GetName();
93 memberFullTypeName = member->GetFullTypeName();
94 memberTitle = member->GetTitle();
95 isapointer = member->IsaPointer();
96 isbasic = member->IsBasic();
97 membertype = member->GetDataType();
98 } else if (!cl->IsLoaded()) {
99 // The class is not loaded, hence it is 'emulated' and the main source of
100 // information is the StreamerInfo.
101 TVirtualStreamerInfo* info = cl->GetStreamerInfo();
102 if (!info) return;
103 const char* cursor = mname;
104 while ((*cursor) == '*') ++cursor;
105 TString elname(cursor);
106 Ssiz_t pos = elname.Index("[");
107 if (pos != kNPOS) {
108 elname.Remove(pos);
109 }
110 TStreamerElement* element = dynamic_cast<TStreamerElement*>(info->GetElements()->FindObject(elname.Data()));
111 if (!element) return;
112 memberFullTypeName = element->GetTypeName();
113
114 memberTypeName = memberFullTypeName;
115 memberTypeName = memberTypeName.Strip(TString::kTrailing, '*');
116 if (memberTypeName.Index("const ") == 0) memberTypeName.Remove(0, 6);
117
118 memberName = element->GetName();
119 memberTitle = element->GetTitle();
120 isapointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;
121 membertype = gROOT->GetType(memberFullTypeName);
122
123 isbasic = membertype != 0;
124 } else {
125 return;
126 }
127
128
129 Bool_t isdate = kFALSE;
130 if (strcmp(memberName, "fDatime") == 0 && strcmp(memberTypeName, "UInt_t") == 0) {
131 isdate = kTRUE;
132 }
133 Bool_t isbits = kFALSE;
134 if (strcmp(memberName, "fBits") == 0 && strcmp(memberTypeName, "UInt_t") == 0) {
135 isbits = kTRUE;
136 }
137 const TClass* dataClass = TClass::GetClass(memberFullTypeName);
138 Bool_t isTString = (dataClass == TString::Class());
139 static TClassRef stdClass("std::string");
140 Bool_t isStdString = (dataClass == stdClass);
141
142 Int_t i;
143 for (i = 0; i < kline; i++) line[i] = ' ';
144 line[kline - 1] = 0;
145
146 // Encode data value or pointer value
147 char* pointer = static_cast<char*>(const_cast<void*>(add));
148 char** ppointer = reinterpret_cast<char**>(pointer);
149
150 if (isapointer) {
151 char** p3pointer = (char**)(*ppointer);
152 if (!p3pointer)
153 snprintf(&line[kvalue], kline - kvalue, "->0");
154 else if (!isbasic)
155 snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)p3pointer);
156 else if (membertype) {
157 if (!strcmp(membertype->GetTypeName(), "char")) {
158 i = strlen(*ppointer);
159 if (kvalue + i > kline) i = kline - 1 - kvalue;
160 Bool_t isPrintable = kTRUE;
161 for (Int_t j = 0; j < i; j++) {
162 if (!std::isprint((*ppointer)[j])) {
163 isPrintable = kFALSE;
164 break;
165 }
166 }
167 if (isPrintable) {
168 //strncpy(line + kvalue, *ppointer, i);
169 std::string out(*ppointer);
170 out.copy(line + kvalue, i);
171 line[kvalue + i] = 0;
172 } else {
173 line[kvalue] = 0;
174 }
175 } else {
176 strncpy(&line[kvalue], membertype->AsString(p3pointer), TMath::Min(kline - 1 - kvalue,
177 (int)strlen(membertype->AsString(p3pointer))));
178 }
179 } else if (!strcmp(memberFullTypeName, "char*") ||
180 !strcmp(memberFullTypeName, "const char*")) {
181 i = strlen(*ppointer);
182 if (kvalue + i >= kline) i = kline - 1 - kvalue;
183 Bool_t isPrintable = kTRUE;
184 for (Int_t j = 0; j < i; j++) {
185 if (!std::isprint((*ppointer)[j])) {
186 isPrintable = kFALSE;
187 break;
188 }
189 }
190 if (isPrintable) {
191 std::string out(*ppointer);
192 out.copy(line + kvalue, i);
193 //strncpy(line + kvalue, *ppointer, i); //
194
195 line[kvalue + i] = 0;
196 } else {
197 line[kvalue] = 0;
198 }
199 } else {
200 snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)p3pointer);
201 }
202 } else if (membertype) {
203 if (isdate) {
204 UInt_t* cdatime = reinterpret_cast<UInt_t*>(pointer);
205 TDatime::GetDateTime(cdatime[0], cdate, ctime);
206 snprintf(&line[kvalue], kline - kvalue, "%d/%d", cdate, ctime);
207 } else if (isbits) {
208 snprintf(&line[kvalue], kline - kvalue, "0x%08x", *reinterpret_cast<UInt_t*>(pointer));
209 } else {
210 strncpy(&line[kvalue], membertype->AsString(pointer), TMath::Min(kline - 1 - kvalue, (int)strlen(membertype->AsString(pointer))));
211 }
212 } else {
213 if (isStdString) {
214 const std::string* str = reinterpret_cast<const std::string*>(pointer);
215 snprintf(&line[kvalue], kline - kvalue, "%s", str->c_str());
216 } else if (isTString) {
217 TString* str = reinterpret_cast<TString*>(pointer);
218 snprintf(&line[kvalue], kline - kvalue, "%s", str->Data());
219 } else {
220 snprintf(&line[kvalue], kline - kvalue, "->%lx ", (Long_t)pointer);
221 }
222 }
223
224
225 m_info += "<tr>";
226 TString indent;
227 if (TString(pname) != "") //indent nested members
228 indent = "&nbsp;&nbsp;&nbsp;";
229 m_info += "<td><b>" + indent + HTML::htmlToPlainText(memberName.Data()) + "</b><br>";
230 m_info += indent + "<small>" + HTML::htmlToPlainText(stripTitle(memberTitle).Data()) + "</small>";
231 m_info += "</td>";
232
233 TString memberValue(HTML::htmlToPlainText(line));
234 m_info += "<td align=right>" + memberValue + "</td>";
235 m_info += "</tr>";
236}
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.