예제 #1
0
// Generate dictionaries required to read `tree`.
void ensure_dictionary(const char *class_name) {
    TClass* claim = TClass::GetClass(class_name);
    if (claim && claim->GetCollectionProxy() &&
        dynamic_cast<TEmulatedCollectionProxy*>(claim->GetCollectionProxy())) {
        // Only executed if the dictionary isn't currently present
        init();
        char *orig_dir = get_current_dir_name();
        chdir(dictionary_tmpdir);
        std::cerr << "Generating dictionary for " << class_name << std::endl;
        gInterpreter->GenerateDictionary(class_name);
        chdir(orig_dir);
        free(static_cast<void*>(orig_dir));
    }
}
void classesFromBranch(TBranch *tbranch, TClass *tclass, std::vector<ClassStructure> &classes, int prefix, std::set<std::string> &includes) {
  std::string className = tclass->GetName();

  if (className == std::string("TObject"))
    includes.insert("#include \"TObject.h\"");
  else if (className == std::string("TRef"))
    includes.insert("#include \"TRef.h\"");
  else if (className == std::string("TRefArray"))
    includes.insert("#include \"TRefArray.h\"");
  else if (className == std::string("TH1"))
    includes.insert("#include \"TH1.h\"");
  else if (className == std::string("TBits")) {
    includes.insert("#include \"TBits.h\"");
  }
  else {
    bool classSeen = false;
    for (int i = 0;  i < classes.size();  i++)
      if (classes[i].fullName == className)
        classSeen = true;

    if (!classSeen) {
      TVirtualStreamerInfo *tVirtualStreamerInfo = tclass->GetStreamerInfo();
      int version = tVirtualStreamerInfo->GetClassVersion();

      ClassStructure classStructure(tclass, version);

      if (tVirtualStreamerInfo->GetElements()->GetEntries() == 1  &&
          ((TStreamerElement*)(tVirtualStreamerInfo->GetElements()->First()))->IsBase()  &&
          std::string(tVirtualStreamerInfo->GetElements()->First()->GetName()) == std::string("TObjArray")) {

        TVirtualStreamerInfo *substreamer = ((TBranchElement*)tbranch)->GetInfo();

        if (std::string(substreamer->GetName()) == std::string("TClonesArray")) {
          ROOT::Internal::TTreeGeneratorBase ttreeGenerator(tbranch->GetTree(), "");
          TString className = ttreeGenerator.GetContainedClassName((TBranchElement*)tbranch, (TStreamerElement*)(substreamer->GetElements()->First()), true);
          classesFromBranch(tbranch, TClass::GetClass(className), classes, prefix + std::string(tbranch->GetName()).size() + 1, includes);
        }
      }

      TIter elements = tVirtualStreamerInfo->GetElements();
      for (TStreamerElement *tStreamerElement = (TStreamerElement*)elements.Next();  tStreamerElement != nullptr;  tStreamerElement = (TStreamerElement*)elements.Next()) {
        std::string streamerName = tStreamerElement->GetName();

        if (tStreamerElement->IsBase()) {
          TClass *elementClass = tStreamerElement->GetClassPointer();
          std::string type = elementClass->GetName();

          if (type == std::string("TObject")) {
            classStructure.bases.push_back(type);
            includes.insert(std::string("#include \"") + type + std::string(".h\""));
          }
        }

        else {
          TIter listOfBranches = tbranch->GetListOfBranches();
          TBranch *subbranch;
          for (subbranch = (TBranch*)listOfBranches.Next();  subbranch != nullptr;  subbranch = (TBranch*)listOfBranches.Next()) {
            std::string branchName = subbranch->GetName();
            branchName = branchName.substr(prefix, std::string::npos);
            int firstDot = branchName.find('.');
            int firstBracket = branchName.find('[');
            if (firstDot != std::string::npos  &&  firstBracket != std::string::npos)
              branchName = branchName.substr(0, firstDot < firstBracket ? firstDot : firstBracket);
            else if (firstDot != std::string::npos)
              branchName = branchName.substr(0, firstDot);
            else if (firstBracket != std::string::npos)
              branchName = branchName.substr(0, firstBracket);
            if (branchName == streamerName)
              break;
          }
          if (subbranch == nullptr)
            continue;

          std::string branchName = subbranch->GetName();

          std::string variable = tStreamerElement->GetName();
          std::string variableWithArray = subbranch->GetName();
          variableWithArray = variableWithArray.substr(prefix, std::string::npos);
          variableWithArray = variableWithArray.substr(0, variableWithArray.find('.'));

          std::string comment = tStreamerElement->GetTitle();

          std::string type;
          Bool_t pointer = false;
          switch (tStreamerElement->GetType()) {

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kBool:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kBool:
          case TVirtualStreamerInfo::kBool:
            type = "Bool_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kChar:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kChar:
          case TVirtualStreamerInfo::kChar:
            type = "Char_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kShort:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kShort:
          case TVirtualStreamerInfo::kShort:
            type = "Short_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kInt:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kInt:
          case TVirtualStreamerInfo::kInt:
            type = "Int_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong:
          case TVirtualStreamerInfo::kLong:
            type = "Long_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong64:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong64:
          case TVirtualStreamerInfo::kLong64:
            type = "Long64_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat:
          case TVirtualStreamerInfo::kFloat:
            type = "Float_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat16:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat16:
          case TVirtualStreamerInfo::kFloat16:
            type = "Float16_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble:
          case TVirtualStreamerInfo::kDouble:
            type = "Double_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble32:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble32:
          case TVirtualStreamerInfo::kDouble32:
            type = "Double32_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUChar:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUChar:
          case TVirtualStreamerInfo::kUChar:
            type = "UChar_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUShort:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUShort:
          case TVirtualStreamerInfo::kUShort:
            type = "UShort_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUInt:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUInt:
          case TVirtualStreamerInfo::kUInt:
            type = "UInt_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong:
          case TVirtualStreamerInfo::kULong:
            type = "ULong_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong64:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong64:
          case TVirtualStreamerInfo::kULong64:
            type = "ULong64_t";
            break;

          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kBits:
            pointer = true;
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kBits:
          case TVirtualStreamerInfo::kBits:
            type = "UInt_t";
            break;

          case TVirtualStreamerInfo::kCharStar:
            type = "Char_t*";
            break;

          case TVirtualStreamerInfo::kCounter:
            type = "Int_t";
            break;

          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kObjectp:
          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kObjectP:
          case TVirtualStreamerInfo::kObjectp:
          case TVirtualStreamerInfo::kObjectP:
          case TVirtualStreamerInfo::kAnyp:
          case TVirtualStreamerInfo::kAnyP:
          case TVirtualStreamerInfo::kSTL + TVirtualStreamerInfo::kObjectp:
          case TVirtualStreamerInfo::kSTL + TVirtualStreamerInfo::kObjectP:
            pointer = true;

          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kObject:
          case TVirtualStreamerInfo::kObject:
          case TVirtualStreamerInfo::kTString:
          case TVirtualStreamerInfo::kTNamed:
          case TVirtualStreamerInfo::kTObject:
          case TVirtualStreamerInfo::kAny:
          case TVirtualStreamerInfo::kBase:
          case TVirtualStreamerInfo::kSTL:
            TClass *elementClass = tStreamerElement->GetClassPointer();
            type = elementClass->GetName();

            if (elementClass == TClonesArray::Class()) {
              ROOT::Internal::TTreeGeneratorBase ttreeGenerator(tbranch->GetTree(), "");
              TString className = ttreeGenerator.GetContainedClassName((TBranchElement*)subbranch, tStreamerElement, pointer);
              if (className != nullptr) {
                TClass *otherClass = TClass::GetClass(className);
                classesFromBranch(subbranch, otherClass, classes, variableWithArray.size() + 1, includes);
                includes.insert("#include \"TClonesArray.h\"");
              }
            }

            else if (elementClass->GetCollectionProxy() != nullptr  &&  elementClass->GetCollectionProxy()->GetValueClass() != nullptr) {
              TClass *otherClass = elementClass->GetCollectionProxy()->GetValueClass();
              classesFromBranch(subbranch, otherClass, classes, variableWithArray.size() + 1, includes);
              includes.insert(std::string("#include <") + type.substr(0, type.find('<')) + std::string(">"));
            }

            else
              classesFromBranch(subbranch, elementClass, classes, variableWithArray.size() + 1, includes);

          }
          classStructure.members.push_back(MemberStructure(type, pointer, variable, variableWithArray, comment));
        }
      }

      if (!classStructure.members.empty())
        classes.push_back(classStructure);
    }
  }
}