forked from root-project/root
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTMemberInspector.cxx
More file actions
158 lines (132 loc) · 4.53 KB
/
Copy pathTMemberInspector.cxx
File metadata and controls
158 lines (132 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// @(#)root/base:$Id$
// Author: Fons Rademakers 15/07/96
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
/** \class TMemberInspector
\ingroup Base
Abstract base class for accessing the data-members of a class.
Classes derived from this class can be given as argument to the
ShowMembers() methods of ROOT classes. This feature facilitates
the writing of class browsers and inspectors.
*/
#include "TMemberInspector.h"
#include "TInterpreter.h"
#include "TClassEdit.h"
#include "TClass.h"
#include "TError.h"
class TMemberInspector::TParentBuf {
private:
std::vector<char> fBuf;
Ssiz_t fLen;
public:
TParentBuf(): fBuf(1024), fLen(0) {}
Ssiz_t GetLength() const { return fLen; }
void Append(const char*);
void Remove(Ssiz_t startingAt);
operator const char*() const { return &fBuf[0]; }
};
void TMemberInspector::TParentBuf::Append(const char* add)
{
// Add "add" to string
if (!add || !add[0]) return;
Ssiz_t addlen = strlen(add);
fBuf.resize(fLen + addlen + 1);
const char* i = add;
while (*i) {
fBuf[fLen++] = *i;
++i;
}
fBuf[fLen] = 0;
}
void TMemberInspector::TParentBuf::Remove(Ssiz_t startingAt)
{
// Remove characters starting at "startingAt"
fLen = startingAt;
fBuf[startingAt] = 0;
}
ClassImp(TMemberInspector);
TMemberInspector::TMemberInspector():
fObjectPointerState(kUnset)
{
// Construct a member inspector
fParent = new TParentBuf();
}
TMemberInspector::~TMemberInspector() {
// Destruct a member inspector
delete fParent;
}
const char* TMemberInspector::GetParent() const
{
// Get the parent string.
return *fParent;
}
Ssiz_t TMemberInspector::GetParentLen() const
{
// Get the length of the parent string.
return fParent->GetLength();
}
void TMemberInspector::AddToParent(const char* name)
{
// Append "name" to the parent string.
fParent->Append(name);
}
void TMemberInspector::RemoveFromParent(Ssiz_t startingAt)
{
// Remove trailing characters starting at "startingAt".
fParent->Remove(startingAt);
}
void TMemberInspector::Inspect(TClass *, const char *, const char *, const void *)
{
// Obsolete signature
Fatal("Inspect","This version of Inspect is obsolete");
}
void TMemberInspector::GenericShowMembers(const char *topClassName, const void *obj,
Bool_t isTransient) {
// Call ShowMember() on obj.
// This could be faster if we implemented this either as a templated
// function or by rootcint-generated code using the typeid (i.e. the
// difference is a lookup in a TList instead of in a map).
// To avoid a spurious error message in case the data member is
// transient and does not have a dictionary we check first.
if (isTransient) {
if (!TClassEdit::IsSTLCont(topClassName)) {
ClassInfo_t *b = gInterpreter->ClassInfo_Factory(topClassName);
Bool_t isloaded = gInterpreter->ClassInfo_IsLoaded(b);
gInterpreter->ClassInfo_Delete(b);
if (!isloaded) return;
}
}
TClass *top = TClass::GetClass(topClassName, true, isTransient);
if (top) {
top->CallShowMembers(obj, *this, isTransient);
} else {
// This might be worth an error message
}
}
void TMemberInspector::InspectMember(const TObject& obj, const char* name, Bool_t isTransient)
{
// Routine driving the visiting of the class information/data members.
InspectMember<TObject>(obj, name, isTransient);
}
void TMemberInspector::InspectMember(const char* topclassname, const void* pobj,
const char* name, Bool_t isTransient)
{
// Routine driving the visiting of the class information/data members.
Ssiz_t len = fParent->GetLength();
fParent->Append(name);
GenericShowMembers(topclassname, pobj, isTransient);
fParent->Remove(len);
}
void TMemberInspector::InspectMember(TClass* cl, const void* pobj, const char* name, Bool_t isTransient)
{
// Routine driving the visiting of the class information/data members.
Ssiz_t len = fParent->GetLength();
fParent->Append(name);
cl->CallShowMembers(pobj, *this, isTransient);
fParent->Remove(len);
}