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