// @(#)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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMemberInspector                                                     //
//                                                                      //
// Abstract base class for accessing the datamembers 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.reserve(fLen + addlen);
   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 spurrious 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);
   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);
}
 TMemberInspector.cxx:1
 TMemberInspector.cxx:2
 TMemberInspector.cxx:3
 TMemberInspector.cxx:4
 TMemberInspector.cxx:5
 TMemberInspector.cxx:6
 TMemberInspector.cxx:7
 TMemberInspector.cxx:8
 TMemberInspector.cxx:9
 TMemberInspector.cxx:10
 TMemberInspector.cxx:11
 TMemberInspector.cxx:12
 TMemberInspector.cxx:13
 TMemberInspector.cxx:14
 TMemberInspector.cxx:15
 TMemberInspector.cxx:16
 TMemberInspector.cxx:17
 TMemberInspector.cxx:18
 TMemberInspector.cxx:19
 TMemberInspector.cxx:20
 TMemberInspector.cxx:21
 TMemberInspector.cxx:22
 TMemberInspector.cxx:23
 TMemberInspector.cxx:24
 TMemberInspector.cxx:25
 TMemberInspector.cxx:26
 TMemberInspector.cxx:27
 TMemberInspector.cxx:28
 TMemberInspector.cxx:29
 TMemberInspector.cxx:30
 TMemberInspector.cxx:31
 TMemberInspector.cxx:32
 TMemberInspector.cxx:33
 TMemberInspector.cxx:34
 TMemberInspector.cxx:35
 TMemberInspector.cxx:36
 TMemberInspector.cxx:37
 TMemberInspector.cxx:38
 TMemberInspector.cxx:39
 TMemberInspector.cxx:40
 TMemberInspector.cxx:41
 TMemberInspector.cxx:42
 TMemberInspector.cxx:43
 TMemberInspector.cxx:44
 TMemberInspector.cxx:45
 TMemberInspector.cxx:46
 TMemberInspector.cxx:47
 TMemberInspector.cxx:48
 TMemberInspector.cxx:49
 TMemberInspector.cxx:50
 TMemberInspector.cxx:51
 TMemberInspector.cxx:52
 TMemberInspector.cxx:53
 TMemberInspector.cxx:54
 TMemberInspector.cxx:55
 TMemberInspector.cxx:56
 TMemberInspector.cxx:57
 TMemberInspector.cxx:58
 TMemberInspector.cxx:59
 TMemberInspector.cxx:60
 TMemberInspector.cxx:61
 TMemberInspector.cxx:62
 TMemberInspector.cxx:63
 TMemberInspector.cxx:64
 TMemberInspector.cxx:65
 TMemberInspector.cxx:66
 TMemberInspector.cxx:67
 TMemberInspector.cxx:68
 TMemberInspector.cxx:69
 TMemberInspector.cxx:70
 TMemberInspector.cxx:71
 TMemberInspector.cxx:72
 TMemberInspector.cxx:73
 TMemberInspector.cxx:74
 TMemberInspector.cxx:75
 TMemberInspector.cxx:76
 TMemberInspector.cxx:77
 TMemberInspector.cxx:78
 TMemberInspector.cxx:79
 TMemberInspector.cxx:80
 TMemberInspector.cxx:81
 TMemberInspector.cxx:82
 TMemberInspector.cxx:83
 TMemberInspector.cxx:84
 TMemberInspector.cxx:85
 TMemberInspector.cxx:86
 TMemberInspector.cxx:87
 TMemberInspector.cxx:88
 TMemberInspector.cxx:89
 TMemberInspector.cxx:90
 TMemberInspector.cxx:91
 TMemberInspector.cxx:92
 TMemberInspector.cxx:93
 TMemberInspector.cxx:94
 TMemberInspector.cxx:95
 TMemberInspector.cxx:96
 TMemberInspector.cxx:97
 TMemberInspector.cxx:98
 TMemberInspector.cxx:99
 TMemberInspector.cxx:100
 TMemberInspector.cxx:101
 TMemberInspector.cxx:102
 TMemberInspector.cxx:103
 TMemberInspector.cxx:104
 TMemberInspector.cxx:105
 TMemberInspector.cxx:106
 TMemberInspector.cxx:107
 TMemberInspector.cxx:108
 TMemberInspector.cxx:109
 TMemberInspector.cxx:110
 TMemberInspector.cxx:111
 TMemberInspector.cxx:112
 TMemberInspector.cxx:113
 TMemberInspector.cxx:114
 TMemberInspector.cxx:115
 TMemberInspector.cxx:116
 TMemberInspector.cxx:117
 TMemberInspector.cxx:118
 TMemberInspector.cxx:119
 TMemberInspector.cxx:120
 TMemberInspector.cxx:121
 TMemberInspector.cxx:122
 TMemberInspector.cxx:123
 TMemberInspector.cxx:124
 TMemberInspector.cxx:125
 TMemberInspector.cxx:126
 TMemberInspector.cxx:127
 TMemberInspector.cxx:128
 TMemberInspector.cxx:129
 TMemberInspector.cxx:130
 TMemberInspector.cxx:131
 TMemberInspector.cxx:132
 TMemberInspector.cxx:133
 TMemberInspector.cxx:134
 TMemberInspector.cxx:135
 TMemberInspector.cxx:136
 TMemberInspector.cxx:137
 TMemberInspector.cxx:138
 TMemberInspector.cxx:139
 TMemberInspector.cxx:140
 TMemberInspector.cxx:141
 TMemberInspector.cxx:142
 TMemberInspector.cxx:143
 TMemberInspector.cxx:144
 TMemberInspector.cxx:145
 TMemberInspector.cxx:146
 TMemberInspector.cxx:147
 TMemberInspector.cxx:148
 TMemberInspector.cxx:149
 TMemberInspector.cxx:150
 TMemberInspector.cxx:151
 TMemberInspector.cxx:152
 TMemberInspector.cxx:153
 TMemberInspector.cxx:154
 TMemberInspector.cxx:155
 TMemberInspector.cxx:156
 TMemberInspector.cxx:157
 TMemberInspector.cxx:158
 TMemberInspector.cxx:159
 TMemberInspector.cxx:160