// @(#)root/meta:$
// Author: Axel Naumann 2014-05-02

/*************************************************************************
 * Copyright (C) 1995-2014, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// Persistent version of a TClass.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TProtoClass.h"

#include "TBaseClass.h"
#include "TClass.h"
#include "TDataMember.h"
#include "TEnum.h"
#include "TInterpreter.h"
#include "TList.h"
#include "TListOfDataMembers.h"
#include "TListOfEnums.h"
#include "TRealData.h"
#include "TError.h"

#include <cassert>
//______________________________________________________________________________
TProtoClass::TProtoClass(TClass* cl):
   TNamed(*cl), fBase(cl->GetListOfBases()), 
   fEnums(cl->GetListOfEnums()), fSizeof(cl->Size()), fCanSplit(cl->fCanSplit),
   fStreamerType(cl->fStreamerType), fProperty(cl->fProperty),
   fClassProperty(cl->fClassProperty)
{
   // Initialize a TProtoClass from a TClass.

   if (cl->Property() & kIsNamespace){
      //fData=new TListOfDataMembers();
      fEnums=nullptr;
      //fPRealData=nullptr;
      fOffsetStreamer=0;
      return;
   }
   // initialize list of data members (fData)
   TList * dataMembers = cl->GetListOfDataMembers();
   if (dataMembers && dataMembers->GetSize() > 0) { 
      fData.reserve(dataMembers->GetSize() ); 
      for (auto * obj : *dataMembers) { 
         TDataMember * dm = dynamic_cast<TDataMember*>(obj); 
         fData.push_back(dm); 
      }
   }

   fPRealData.reserve(100);

   if (!cl->GetCollectionProxy()) {
      // Build the list of RealData before we access it:
      cl->BuildRealData(0, true /*isTransient*/);
      // The data members are ordered as follows:
      // - this class's data members,
      // - foreach base: base class's data members.
      // fPRealData encodes all TProtoRealData objects with a
      // TObjString to signal a new class.
      TClass* clCurrent = cl;
      fDepClasses.push_back(cl->GetName() );
      TRealData* precRd = nullptr;
      for (auto realDataObj: *cl->GetListOfRealData()) {
         TRealData *rd = (TRealData*)realDataObj;
         if (!precRd) precRd = rd;
         TClass* clRD = rd->GetDataMember()->GetClass();
         TProtoRealData protoRealData(rd); 
         if (clRD != clCurrent) {
            // here I have a new class
            fDepClasses.push_back(clRD->GetName() );
            clCurrent = clRD;
            protoRealData.fClassIndex = fDepClasses.size()-1;
            //protoRealData.fClass = clRD->GetName(); 
//TObjString *clstr = new TObjString(clRD->GetName());
            if (precRd->TestBit(TRealData::kTransient)) {
               //clstr->SetBit(TRealData::kTransient);
               protoRealData.SetFlag(TProtoRealData::kIsTransient,true);
            }
            else 
               protoRealData.SetFlag(TProtoRealData::kIsTransient,false); 
               
            //      fPRealData->AddLast(clstr);
            precRd = rd;
         }
         //fPRealData->AddLast(new TProtoRealData(rd));
         fPRealData.push_back(protoRealData);
      }

      if (gDebug > 2) {
         for (auto data : fPRealData) {
            // const auto classType = dataPtr->IsA();
            // const auto dataName = data.fName;
            // const auto dataClass = data.fClass;
            // Info("TProtoClass","Data is a protorealdata: %s - class %s - transient %d", dataName.Data(),dataClass.Data(),data.fIsTransient);
            //if (!dataClass.IsNull() 
            // if (classType == TProtoRealData::Class())
            //    Info("TProtoClass","Data is a protorealdata: %s", dataPtrName);
            // if (classType == TObjString::Class())
            //    Info("TProtoClass","Data is a objectstring: %s", dataPtrName);
            // if (dataPtr->TestBit(TRealData::kTransient))
            //    Info("TProtoClass","And is transient");
         }
      }
   }

   // this crashes 
   cl->CalculateStreamerOffset();
   fOffsetStreamer = cl->fOffsetStreamer;
}




// // conversion of a new TProtoClass from an old TProtoClass
// //______________________________________________________________________________
// TProtoClass::TProtoClass(TProtoClassOld * pc):
//    TNamed(pc->GetName(),pc->GetTitle()), fBase(pc->fBase), 
//    fEnums(pc->fEnums), fSizeof(pc->fSizeof), fCanSplit(pc->fCanSplit),
//    fStreamerType(pc->fStreamerType), fProperty(pc->fProperty),
//    fClassProperty(pc->fClassProperty), fOffsetStreamer( pc->fOffsetStreamer)
// {

//    fBase = (pc->fBase) ? (TList*) pc->fBase->Clone() : 0;
//    //fData = (pc->fData) ? (TList*) pc->fData->Clone() : 0;
//    fEnums = (pc->fEnums) ? (TList*) pc->fEnums->Clone() : 0;

//    // initialize list of data members (fData)
//    TList * dataMembers = pc->fData;
//    if (dataMembers && dataMembers->GetSize() > 0) { 
//       fData.reserve(dataMembers->GetSize() ); 
//       for (auto * obj : *dataMembers) { 
//          TDataMember * dm = dynamic_cast<TDataMember*>(obj);
//          if (dm) { 
//             TDataMember * dm2 = (TDataMember *) dm->Clone(); 
//             if (dm2)   fData.push_back(dm2); 
//          }
//       }
//    }

//    fPRealData.reserve(100);

//    TString className; 
//    for (auto dataPtr : *(pc->fPRealData) ) {

//       const auto classType = dataPtr->IsA();
//       if (classType == TObjString::Class()) {
//          className = dataPtr->GetName();
//       }
//       else if (classType == TProtoClass::TProtoRealData::Class()) {
//          TProtoRealData protoRealData;
//          TProtoClass::TProtoRealData * oldData= ( TProtoClass::TProtoRealData * )dataPtr;
//          TClass * cl = TClass::GetClass(className); 
//          //protoRealData.fName = dataPtr->GetName();
//          //TObject * obj =  cl->GetListOfDataMembers()->FindObject(  );
//          protoRealData.fDMIndex = DataMemberIndex(cl, dataPtr->GetName() );
//          //  protoRealData.fTitle = dataPtr->GetTitle();
//          //protoRealData.fClass = className; 
//          className.Clear();
//          protoRealData.fIsTransient = dataPtr->TestBit(TRealData::kTransient);
//          protoRealData.fOffset = oldData->GetOffset();
//          protoRealData.fIsObject = dataPtr->TestBit(BIT(15));
//          fPRealData.push_back(protoRealData);
//       }      
//    }
// }

//______________________________________________________________________________
TProtoClass::~TProtoClass()
{
   // Destructor.
   Delete();
}

//______________________________________________________________________________
void TProtoClass::Delete(Option_t* opt /*= ""*/) {
   // Delete the containers that are usually owned by their TClass.
   // if (fPRealData) fPRealData->Delete(opt);
   // delete fPRealData; fPRealData = 0;

   if (fBase) fBase->Delete(opt);
   delete fBase; fBase = 0;

   if (fEnums) fEnums->Delete(opt);
   delete fEnums; fEnums = 0;
   
   if (gErrorIgnoreLevel==-2) printf("Delete the protoClass %s \n",GetName());
}

//______________________________________________________________________________
Bool_t TProtoClass::FillTClass(TClass* cl) {
   // Move data from this TProtoClass into cl.

   if (cl->fRealData || cl->fBase || cl->fData || cl->fEnums.load()
       || cl->fSizeof != -1 || cl->fCanSplit >= 0
       || cl->fProperty != (-1) ) {
      if (cl->fProperty & kIsNamespace){
         if (gDebug>0) Info("FillTClass", "Returning w/o doing anything. %s is a namespace.",cl->GetName());
         return kTRUE;
      }
      Error("FillTClass", "TClass %s already initialized!", cl->GetName());
      return kFALSE;
   }
   if (gDebug > 1) Info("FillTClass","Loading TProtoClass for %s - %s",cl->GetName(),GetName());

   if (fPRealData.size() > 0) {

      // A first loop to retrieve the mother classes before starting to
      // fill this TClass instance. This is done in order to avoid recursions
      // for example in presence of daughter and mother class present in two
      // dictionaries compiled in two different libraries which are not linked
      // one with each other.
      for (auto element: fPRealData) {
         //if (element->IsA() == TObjString::Class()) {
         if (element.IsAClass() ) { 
            if (gDebug > 1) Info("","Treating beforehand mother class %s",GetClassName(element.fClassIndex));
//             int autoloadingOldval=gInterpreter->SetClassAutoloading(false);
            TInterpreter::SuspendAutoParsing autoParseRaii(gInterpreter);

            TClass::GetClass(GetClassName(element.fClassIndex));

//             gInterpreter->SetClassAutoloading(autoloadingOldval);
         }
      }
   }


   //this->Dump(); 

   // Copy only the TClass bits.
   // not bit 13 and below and not bit 24 and above, just Bits 14 - 23
   UInt_t newbits = TestBits(0x00ffc000);
   cl->ResetBit(0x00ffc000);
   cl->SetBit(newbits);

   cl->fName  = this->fName;
   cl->fTitle = this->fTitle;
   cl->fBase = fBase;

   // fill list of data members in TClass
   //if (cl->fData) { cl->fData->Delete(); delete cl->fData;  }
   cl->fData = new TListOfDataMembers(fData); 
   // for (auto * dataMember : fData) { 
   //    //printf("add data member for class %s - member %s \n",GetName(), dataMember->GetName() );
   //    cl->fData->Add(dataMember); 
   // }
   // // set loaded bit to true to avoid re-loading the data members
   // cl->fData->SetIsLoaded();* 

   //cl->fData = (TListOfDataMembers*)fData;

   // We need to fill enums one by one to initialise the internal map which is
   // transient
   {
      auto temp = new TListOfEnums();
      for (TObject* enumAsTObj : *fEnums){
         temp->Add((TEnum*) enumAsTObj);
      }
      cl->fEnums = temp;
   }
  
   cl->fSizeof = fSizeof;
   cl->fCanSplit = fCanSplit;
   cl->fProperty = fProperty;
   cl->fClassProperty = fClassProperty;
   cl->fStreamerType = fStreamerType;

   // Update pointers to TClass
   if (cl->fBase) {
      for (auto base: *cl->fBase) {
         ((TBaseClass*)base)->SetClass(cl);
      }
   }
   if (cl->fData) {
      for (auto dm: *cl->fData) {
         ((TDataMember*)dm)->SetClass(cl);
      }
      ((TListOfDataMembers*)cl->fData)->SetClass(cl);
   }
   if (cl->fEnums.load()) {
      for (auto en: *cl->fEnums) {
         ((TEnum*)en)->SetClass(cl);
      }
      ((TListOfEnums*)cl->fEnums)->SetClass(cl);
   }


   TClass* currentRDClass = cl;
   TRealData * prevRealData = 0;
   int prevLevel = 0;
   bool first = true; 
   if (fPRealData.size()  > 0) {
      for (auto element: fPRealData) {
         //if (element->IsA() == TObjString::Class()) {
         if (element.IsAClass() ) { 
            // We now check for the TClass entry, w/o loading. Indeed we did that above.
            // If the class is not found, it means that really it was not selected and we
            // replace it with an empty placeholder with the status of kForwardDeclared.
            // Interactivity will be of course possible but if IO is attempted, a warning
            // will be issued.
            TInterpreter::SuspendAutoParsing autoParseRaii(gInterpreter);

            // Disable autoparsing which might be triggered by the use of ResolvedTypedef
            // and the fallback new TClass() below.
            currentRDClass = TClass::GetClass(GetClassName(element.fClassIndex), false /* Load */ );
            //printf("element is a class - name %s  - index %d  %s \n ",currentRDClass->GetName(), element.fClassIndex, GetClassName(element.fClassIndex) );
            if (!currentRDClass && !element.TestFlag(TProtoRealData::kIsTransient)) {
               if (gDebug>1)
                  Info("FillTClass()",
                       "Cannot find TClass for %s; Creating an empty one in the kForwardDeclared state.",
                       GetClassName(element.fClassIndex));
               currentRDClass = new TClass(GetClassName(element.fClassIndex),1,TClass::kForwardDeclared, true /*silent*/);
            }
         }
         //else {
         if (!currentRDClass) continue;
         //TProtoRealData* prd = (TProtoRealData*)element;
         // pass a previous real data only if depth 

         if (TRealData* rd = element.CreateRealData(currentRDClass, cl,prevRealData, prevLevel)) {
            if (first) { 
               //LM: need to do here because somehow fRealData is destroyed when calling TClass::GetListOfDataMembers() 
               if (cl->fRealData) { 
                  Info("FillTClas","Real data for class %s is not empty - make a new one",cl->GetName() );
                  delete cl->fRealData;
               }
               cl->fRealData = new TList(); // FIXME: this should really become a THashList!               
               first = false; 
            }

            cl->fRealData->AddLast(rd);
            prevRealData = rd; 
            prevLevel = element.fLevel;

         }
            //}
      }
   }
   else { 
      if (cl->fRealData) { 
         Info("FillTClas","Real data for class %s is not empty - make a new one. Class has no Proto-realdata",cl->GetName() );
         delete cl->fRealData;
      }
      cl->fRealData = new TList(); // FIXME: this should really become a THashList!               
   }

   cl->SetStreamerImpl();

   // set to zero in order not to delete when protoclass is deleted
   fBase = 0;
   //fData = 0; 
   fEnums = 0;

   fPRealData.clear();
   fPRealData.shrink_to_fit();  // to reset the underlying allocate space

   // if (fPRealData) fPRealData->Delete();
   // delete fPRealData;
   // fPRealData = 0;


   return kTRUE;
}

//______________________________________________________________________________
TProtoClass::TProtoRealData::TProtoRealData(const TRealData* rd):
   //TNamed(rd->GetDataMember()->GetName(), rd->GetName()),
   //TNamed(),
   //fName(rd->GetDataMember()->GetName()),
//   fTitle(rd->GetName()),
   fOffset(rd->GetThisOffset()),
   fDMIndex(-1),
   fLevel(0),
   fClassIndex(-1),
   fStatusFlag(0)
{
   TDataMember * dm = rd->GetDataMember(); 
   TClass * cl = dm->GetClass();
   assert(cl != NULL); 
   fDMIndex = DataMemberIndex(cl,dm->GetName());
   //printf("Index of data member %s for class %s is %d \n",dm->GetName(), cl->GetName() , fDMIndex);
   TString fullDataMemberName = rd->GetName(); // full data member name (e.g. fXaxis.fNbins)
   fLevel = fullDataMemberName.CountChar('.');

   if (fullDataMemberName.Contains("*") ) SetFlag(kIsPointer); 

   // Initialize this from a TRealData object.
   SetFlag(kIsObject, rd->IsObject());
   SetFlag(kIsTransient, rd->TestBit(TRealData::kTransient) );
}

//______________________________________________________________________________
TProtoClass::TProtoRealData::~TProtoRealData()
{
   // Destructor to pin vtable.
   //if (gErrorIgnoreLevel==-2) printf("destroy real data %s - ",GetName());
}

//______________________________________________________________________________
TRealData* TProtoClass::TProtoRealData::CreateRealData(TClass* dmClass,
                                                         TClass* parent, TRealData *prevData, int prevLevel) const
{
   // Create a TRealData from this, with its data member coming from dmClass.
   // find data member from protoclass
   

      //TDataMember* dm = (TDataMember*)dmClass->GetListOfDataMembers()->FindObject(fName);
   TDataMember* dm = TProtoClass::FindDataMember(dmClass, fDMIndex);

   if (!dm && dmClass->GetState()!=TClass::kForwardDeclared) {
      ::Error("CreateRealData",
             "Cannot find data member # %d of class %s for parent %s!", fDMIndex, dmClass->GetName(),
             parent->GetName());
      return nullptr;
   }

   // here I need to re-construct the realdata full name (e.g. fAxis.fNbins) 

   TString realMemberName;
   // keep an empty name if data member is not found
   if (dm) realMemberName = dm->GetName(); 
   if (TestFlag(kIsPointer) ) 
      realMemberName = TString("*")+realMemberName;  
   else {  
      if (dm && dm->GetArrayDim() > 0) { 
      // in case of array (like fMatrix[2][2] we need to add max index )
      // this only in case of it os not a pointer
         for (int idim = 0; idim < dm->GetArrayDim(); ++idim)  
            realMemberName += TString::Format("[%d]",dm->GetMaxIndex(idim) );
      }
   }

   if (prevData && fLevel > 0 ) {
      if (fLevel-prevLevel == 1) // I am going down 1 level
         realMemberName = TString::Format("%s.%s",prevData->GetName(), realMemberName.Data() ); 
      else if (fLevel <= prevLevel) { // I am at the same level 
         // need to strip out prev name 
         std::string prevName = prevData->GetName();  
         // we strip the prev data member name from the full name
         std::string parentName; 
         for (int i = 0; i < prevLevel-fLevel+1; ++i) { 
            parentName = prevName.substr(0, prevName.find_last_of(".") );
            prevName = parentName; 
         }
         
         // now we need to add the current name
         realMemberName =  TString::Format("%s.%s",parentName.c_str(), realMemberName.Data() ); 
      }
   }

   //printf("adding new realdata for class %s : %s - %s   %d    %d   \n",dmClass->GetName(), realMemberName.Data(), dm->GetName(),fLevel, fDMIndex  );

   TRealData* rd = new TRealData(realMemberName, fOffset, dm);
   rd->SetIsObject(TestFlag(kIsObject) );
   return rd;
}

//______________________________________________________________________________
Int_t TProtoClass::DataMemberIndex(TClass * cl, const char * name)
{
   TList * dmList = cl->GetListOfDataMembers(); 

   // we cannot use IndexOf because order is guranteed only for non-static data member 
   Int_t index = 0; 
   for ( auto * obj : *dmList) { 
      TDataMember * dm = (TDataMember *) obj; 
      if (!dm ) continue; 
      if (dm->Property() & kIsStatic) continue;
      if ( TString(dm->GetName()) == TString(name) ) 
         return index; 
      index++;
   }
   ::Error("TProtoClass::DataMemberIndex","data member %s is not found in class %s",name, cl->GetName());
   dmList->ls();
   return -1; 
}
//______________________________________________________________________________
TDataMember * TProtoClass::FindDataMember(TClass * cl, Int_t index)
{

   TList * dmList = cl->GetListOfDataMembers(false); 

   // we cannot use IndexOf because order is guranteed only for non-static data member 
   Int_t i = 0; 
   for ( auto * obj : *dmList) { 
      TDataMember * dm = (TDataMember *) obj; 
      if (!dm ) continue; 
      if (dm->Property() & kIsStatic) continue;
      if (i == index) 
         return dm; 
      i++;
   }
   if (cl->GetState()!=TClass::kForwardDeclared)
      ::Error("TProtoClass::FindDataMember","data member with index %d is not found in class %s",index,cl->GetName());
   return nullptr;
}
 TProtoClass.cxx:1
 TProtoClass.cxx:2
 TProtoClass.cxx:3
 TProtoClass.cxx:4
 TProtoClass.cxx:5
 TProtoClass.cxx:6
 TProtoClass.cxx:7
 TProtoClass.cxx:8
 TProtoClass.cxx:9
 TProtoClass.cxx:10
 TProtoClass.cxx:11
 TProtoClass.cxx:12
 TProtoClass.cxx:13
 TProtoClass.cxx:14
 TProtoClass.cxx:15
 TProtoClass.cxx:16
 TProtoClass.cxx:17
 TProtoClass.cxx:18
 TProtoClass.cxx:19
 TProtoClass.cxx:20
 TProtoClass.cxx:21
 TProtoClass.cxx:22
 TProtoClass.cxx:23
 TProtoClass.cxx:24
 TProtoClass.cxx:25
 TProtoClass.cxx:26
 TProtoClass.cxx:27
 TProtoClass.cxx:28
 TProtoClass.cxx:29
 TProtoClass.cxx:30
 TProtoClass.cxx:31
 TProtoClass.cxx:32
 TProtoClass.cxx:33
 TProtoClass.cxx:34
 TProtoClass.cxx:35
 TProtoClass.cxx:36
 TProtoClass.cxx:37
 TProtoClass.cxx:38
 TProtoClass.cxx:39
 TProtoClass.cxx:40
 TProtoClass.cxx:41
 TProtoClass.cxx:42
 TProtoClass.cxx:43
 TProtoClass.cxx:44
 TProtoClass.cxx:45
 TProtoClass.cxx:46
 TProtoClass.cxx:47
 TProtoClass.cxx:48
 TProtoClass.cxx:49
 TProtoClass.cxx:50
 TProtoClass.cxx:51
 TProtoClass.cxx:52
 TProtoClass.cxx:53
 TProtoClass.cxx:54
 TProtoClass.cxx:55
 TProtoClass.cxx:56
 TProtoClass.cxx:57
 TProtoClass.cxx:58
 TProtoClass.cxx:59
 TProtoClass.cxx:60
 TProtoClass.cxx:61
 TProtoClass.cxx:62
 TProtoClass.cxx:63
 TProtoClass.cxx:64
 TProtoClass.cxx:65
 TProtoClass.cxx:66
 TProtoClass.cxx:67
 TProtoClass.cxx:68
 TProtoClass.cxx:69
 TProtoClass.cxx:70
 TProtoClass.cxx:71
 TProtoClass.cxx:72
 TProtoClass.cxx:73
 TProtoClass.cxx:74
 TProtoClass.cxx:75
 TProtoClass.cxx:76
 TProtoClass.cxx:77
 TProtoClass.cxx:78
 TProtoClass.cxx:79
 TProtoClass.cxx:80
 TProtoClass.cxx:81
 TProtoClass.cxx:82
 TProtoClass.cxx:83
 TProtoClass.cxx:84
 TProtoClass.cxx:85
 TProtoClass.cxx:86
 TProtoClass.cxx:87
 TProtoClass.cxx:88
 TProtoClass.cxx:89
 TProtoClass.cxx:90
 TProtoClass.cxx:91
 TProtoClass.cxx:92
 TProtoClass.cxx:93
 TProtoClass.cxx:94
 TProtoClass.cxx:95
 TProtoClass.cxx:96
 TProtoClass.cxx:97
 TProtoClass.cxx:98
 TProtoClass.cxx:99
 TProtoClass.cxx:100
 TProtoClass.cxx:101
 TProtoClass.cxx:102
 TProtoClass.cxx:103
 TProtoClass.cxx:104
 TProtoClass.cxx:105
 TProtoClass.cxx:106
 TProtoClass.cxx:107
 TProtoClass.cxx:108
 TProtoClass.cxx:109
 TProtoClass.cxx:110
 TProtoClass.cxx:111
 TProtoClass.cxx:112
 TProtoClass.cxx:113
 TProtoClass.cxx:114
 TProtoClass.cxx:115
 TProtoClass.cxx:116
 TProtoClass.cxx:117
 TProtoClass.cxx:118
 TProtoClass.cxx:119
 TProtoClass.cxx:120
 TProtoClass.cxx:121
 TProtoClass.cxx:122
 TProtoClass.cxx:123
 TProtoClass.cxx:124
 TProtoClass.cxx:125
 TProtoClass.cxx:126
 TProtoClass.cxx:127
 TProtoClass.cxx:128
 TProtoClass.cxx:129
 TProtoClass.cxx:130
 TProtoClass.cxx:131
 TProtoClass.cxx:132
 TProtoClass.cxx:133
 TProtoClass.cxx:134
 TProtoClass.cxx:135
 TProtoClass.cxx:136
 TProtoClass.cxx:137
 TProtoClass.cxx:138
 TProtoClass.cxx:139
 TProtoClass.cxx:140
 TProtoClass.cxx:141
 TProtoClass.cxx:142
 TProtoClass.cxx:143
 TProtoClass.cxx:144
 TProtoClass.cxx:145
 TProtoClass.cxx:146
 TProtoClass.cxx:147
 TProtoClass.cxx:148
 TProtoClass.cxx:149
 TProtoClass.cxx:150
 TProtoClass.cxx:151
 TProtoClass.cxx:152
 TProtoClass.cxx:153
 TProtoClass.cxx:154
 TProtoClass.cxx:155
 TProtoClass.cxx:156
 TProtoClass.cxx:157
 TProtoClass.cxx:158
 TProtoClass.cxx:159
 TProtoClass.cxx:160
 TProtoClass.cxx:161
 TProtoClass.cxx:162
 TProtoClass.cxx:163
 TProtoClass.cxx:164
 TProtoClass.cxx:165
 TProtoClass.cxx:166
 TProtoClass.cxx:167
 TProtoClass.cxx:168
 TProtoClass.cxx:169
 TProtoClass.cxx:170
 TProtoClass.cxx:171
 TProtoClass.cxx:172
 TProtoClass.cxx:173
 TProtoClass.cxx:174
 TProtoClass.cxx:175
 TProtoClass.cxx:176
 TProtoClass.cxx:177
 TProtoClass.cxx:178
 TProtoClass.cxx:179
 TProtoClass.cxx:180
 TProtoClass.cxx:181
 TProtoClass.cxx:182
 TProtoClass.cxx:183
 TProtoClass.cxx:184
 TProtoClass.cxx:185
 TProtoClass.cxx:186
 TProtoClass.cxx:187
 TProtoClass.cxx:188
 TProtoClass.cxx:189
 TProtoClass.cxx:190
 TProtoClass.cxx:191
 TProtoClass.cxx:192
 TProtoClass.cxx:193
 TProtoClass.cxx:194
 TProtoClass.cxx:195
 TProtoClass.cxx:196
 TProtoClass.cxx:197
 TProtoClass.cxx:198
 TProtoClass.cxx:199
 TProtoClass.cxx:200
 TProtoClass.cxx:201
 TProtoClass.cxx:202
 TProtoClass.cxx:203
 TProtoClass.cxx:204
 TProtoClass.cxx:205
 TProtoClass.cxx:206
 TProtoClass.cxx:207
 TProtoClass.cxx:208
 TProtoClass.cxx:209
 TProtoClass.cxx:210
 TProtoClass.cxx:211
 TProtoClass.cxx:212
 TProtoClass.cxx:213
 TProtoClass.cxx:214
 TProtoClass.cxx:215
 TProtoClass.cxx:216
 TProtoClass.cxx:217
 TProtoClass.cxx:218
 TProtoClass.cxx:219
 TProtoClass.cxx:220
 TProtoClass.cxx:221
 TProtoClass.cxx:222
 TProtoClass.cxx:223
 TProtoClass.cxx:224
 TProtoClass.cxx:225
 TProtoClass.cxx:226
 TProtoClass.cxx:227
 TProtoClass.cxx:228
 TProtoClass.cxx:229
 TProtoClass.cxx:230
 TProtoClass.cxx:231
 TProtoClass.cxx:232
 TProtoClass.cxx:233
 TProtoClass.cxx:234
 TProtoClass.cxx:235
 TProtoClass.cxx:236
 TProtoClass.cxx:237
 TProtoClass.cxx:238
 TProtoClass.cxx:239
 TProtoClass.cxx:240
 TProtoClass.cxx:241
 TProtoClass.cxx:242
 TProtoClass.cxx:243
 TProtoClass.cxx:244
 TProtoClass.cxx:245
 TProtoClass.cxx:246
 TProtoClass.cxx:247
 TProtoClass.cxx:248
 TProtoClass.cxx:249
 TProtoClass.cxx:250
 TProtoClass.cxx:251
 TProtoClass.cxx:252
 TProtoClass.cxx:253
 TProtoClass.cxx:254
 TProtoClass.cxx:255
 TProtoClass.cxx:256
 TProtoClass.cxx:257
 TProtoClass.cxx:258
 TProtoClass.cxx:259
 TProtoClass.cxx:260
 TProtoClass.cxx:261
 TProtoClass.cxx:262
 TProtoClass.cxx:263
 TProtoClass.cxx:264
 TProtoClass.cxx:265
 TProtoClass.cxx:266
 TProtoClass.cxx:267
 TProtoClass.cxx:268
 TProtoClass.cxx:269
 TProtoClass.cxx:270
 TProtoClass.cxx:271
 TProtoClass.cxx:272
 TProtoClass.cxx:273
 TProtoClass.cxx:274
 TProtoClass.cxx:275
 TProtoClass.cxx:276
 TProtoClass.cxx:277
 TProtoClass.cxx:278
 TProtoClass.cxx:279
 TProtoClass.cxx:280
 TProtoClass.cxx:281
 TProtoClass.cxx:282
 TProtoClass.cxx:283
 TProtoClass.cxx:284
 TProtoClass.cxx:285
 TProtoClass.cxx:286
 TProtoClass.cxx:287
 TProtoClass.cxx:288
 TProtoClass.cxx:289
 TProtoClass.cxx:290
 TProtoClass.cxx:291
 TProtoClass.cxx:292
 TProtoClass.cxx:293
 TProtoClass.cxx:294
 TProtoClass.cxx:295
 TProtoClass.cxx:296
 TProtoClass.cxx:297
 TProtoClass.cxx:298
 TProtoClass.cxx:299
 TProtoClass.cxx:300
 TProtoClass.cxx:301
 TProtoClass.cxx:302
 TProtoClass.cxx:303
 TProtoClass.cxx:304
 TProtoClass.cxx:305
 TProtoClass.cxx:306
 TProtoClass.cxx:307
 TProtoClass.cxx:308
 TProtoClass.cxx:309
 TProtoClass.cxx:310
 TProtoClass.cxx:311
 TProtoClass.cxx:312
 TProtoClass.cxx:313
 TProtoClass.cxx:314
 TProtoClass.cxx:315
 TProtoClass.cxx:316
 TProtoClass.cxx:317
 TProtoClass.cxx:318
 TProtoClass.cxx:319
 TProtoClass.cxx:320
 TProtoClass.cxx:321
 TProtoClass.cxx:322
 TProtoClass.cxx:323
 TProtoClass.cxx:324
 TProtoClass.cxx:325
 TProtoClass.cxx:326
 TProtoClass.cxx:327
 TProtoClass.cxx:328
 TProtoClass.cxx:329
 TProtoClass.cxx:330
 TProtoClass.cxx:331
 TProtoClass.cxx:332
 TProtoClass.cxx:333
 TProtoClass.cxx:334
 TProtoClass.cxx:335
 TProtoClass.cxx:336
 TProtoClass.cxx:337
 TProtoClass.cxx:338
 TProtoClass.cxx:339
 TProtoClass.cxx:340
 TProtoClass.cxx:341
 TProtoClass.cxx:342
 TProtoClass.cxx:343
 TProtoClass.cxx:344
 TProtoClass.cxx:345
 TProtoClass.cxx:346
 TProtoClass.cxx:347
 TProtoClass.cxx:348
 TProtoClass.cxx:349
 TProtoClass.cxx:350
 TProtoClass.cxx:351
 TProtoClass.cxx:352
 TProtoClass.cxx:353
 TProtoClass.cxx:354
 TProtoClass.cxx:355
 TProtoClass.cxx:356
 TProtoClass.cxx:357
 TProtoClass.cxx:358
 TProtoClass.cxx:359
 TProtoClass.cxx:360
 TProtoClass.cxx:361
 TProtoClass.cxx:362
 TProtoClass.cxx:363
 TProtoClass.cxx:364
 TProtoClass.cxx:365
 TProtoClass.cxx:366
 TProtoClass.cxx:367
 TProtoClass.cxx:368
 TProtoClass.cxx:369
 TProtoClass.cxx:370
 TProtoClass.cxx:371
 TProtoClass.cxx:372
 TProtoClass.cxx:373
 TProtoClass.cxx:374
 TProtoClass.cxx:375
 TProtoClass.cxx:376
 TProtoClass.cxx:377
 TProtoClass.cxx:378
 TProtoClass.cxx:379
 TProtoClass.cxx:380
 TProtoClass.cxx:381
 TProtoClass.cxx:382
 TProtoClass.cxx:383
 TProtoClass.cxx:384
 TProtoClass.cxx:385
 TProtoClass.cxx:386
 TProtoClass.cxx:387
 TProtoClass.cxx:388
 TProtoClass.cxx:389
 TProtoClass.cxx:390
 TProtoClass.cxx:391
 TProtoClass.cxx:392
 TProtoClass.cxx:393
 TProtoClass.cxx:394
 TProtoClass.cxx:395
 TProtoClass.cxx:396
 TProtoClass.cxx:397
 TProtoClass.cxx:398
 TProtoClass.cxx:399
 TProtoClass.cxx:400
 TProtoClass.cxx:401
 TProtoClass.cxx:402
 TProtoClass.cxx:403
 TProtoClass.cxx:404
 TProtoClass.cxx:405
 TProtoClass.cxx:406
 TProtoClass.cxx:407
 TProtoClass.cxx:408
 TProtoClass.cxx:409
 TProtoClass.cxx:410
 TProtoClass.cxx:411
 TProtoClass.cxx:412
 TProtoClass.cxx:413
 TProtoClass.cxx:414
 TProtoClass.cxx:415
 TProtoClass.cxx:416
 TProtoClass.cxx:417
 TProtoClass.cxx:418
 TProtoClass.cxx:419
 TProtoClass.cxx:420
 TProtoClass.cxx:421
 TProtoClass.cxx:422
 TProtoClass.cxx:423
 TProtoClass.cxx:424
 TProtoClass.cxx:425
 TProtoClass.cxx:426
 TProtoClass.cxx:427
 TProtoClass.cxx:428
 TProtoClass.cxx:429
 TProtoClass.cxx:430
 TProtoClass.cxx:431
 TProtoClass.cxx:432
 TProtoClass.cxx:433
 TProtoClass.cxx:434
 TProtoClass.cxx:435
 TProtoClass.cxx:436
 TProtoClass.cxx:437
 TProtoClass.cxx:438
 TProtoClass.cxx:439
 TProtoClass.cxx:440
 TProtoClass.cxx:441
 TProtoClass.cxx:442
 TProtoClass.cxx:443
 TProtoClass.cxx:444
 TProtoClass.cxx:445
 TProtoClass.cxx:446
 TProtoClass.cxx:447
 TProtoClass.cxx:448
 TProtoClass.cxx:449
 TProtoClass.cxx:450
 TProtoClass.cxx:451
 TProtoClass.cxx:452
 TProtoClass.cxx:453
 TProtoClass.cxx:454
 TProtoClass.cxx:455
 TProtoClass.cxx:456
 TProtoClass.cxx:457
 TProtoClass.cxx:458
 TProtoClass.cxx:459
 TProtoClass.cxx:460
 TProtoClass.cxx:461
 TProtoClass.cxx:462
 TProtoClass.cxx:463
 TProtoClass.cxx:464
 TProtoClass.cxx:465
 TProtoClass.cxx:466
 TProtoClass.cxx:467
 TProtoClass.cxx:468
 TProtoClass.cxx:469
 TProtoClass.cxx:470
 TProtoClass.cxx:471
 TProtoClass.cxx:472
 TProtoClass.cxx:473
 TProtoClass.cxx:474
 TProtoClass.cxx:475
 TProtoClass.cxx:476
 TProtoClass.cxx:477
 TProtoClass.cxx:478
 TProtoClass.cxx:479
 TProtoClass.cxx:480
 TProtoClass.cxx:481
 TProtoClass.cxx:482
 TProtoClass.cxx:483
 TProtoClass.cxx:484
 TProtoClass.cxx:485
 TProtoClass.cxx:486
 TProtoClass.cxx:487
 TProtoClass.cxx:488
 TProtoClass.cxx:489
 TProtoClass.cxx:490
 TProtoClass.cxx:491
 TProtoClass.cxx:492
 TProtoClass.cxx:493
 TProtoClass.cxx:494
 TProtoClass.cxx:495
 TProtoClass.cxx:496
 TProtoClass.cxx:497
 TProtoClass.cxx:498
 TProtoClass.cxx:499
 TProtoClass.cxx:500
 TProtoClass.cxx:501
 TProtoClass.cxx:502
 TProtoClass.cxx:503