55#include " root_ttree_container.hpp"
66
77#include " TBranch.h"
8+ #include " TClassEdit.h"
89#include " TFile.h"
910#include " TLeaf.h"
1011#include " TTree.h"
1112
1213#include < unordered_map>
1314
1415namespace {
16+ // Return the demangled type name
17+ std::string DemangleName (std::type_info const & type)
18+ {
19+ int errorCode;
20+ // The TClassEdit version works on both linux and Windows.
21+ char * demangledName = TClassEdit::DemangleTypeIdName (type, errorCode);
22+ if (errorCode != 0 ) {
23+ // NOTE: Instead of throwing, we could return the mangled name as a fallback.
24+ throw std::runtime_error (" Failed to demangle type name" );
25+ }
26+ std::string result (demangledName);
27+ std::free (demangledName);
28+ return result;
29+ }
1530 // Type name conversion based on https://root.cern.ch/doc/master/classTTree.html#ac1fa9466ce018d4aa739b357f981c615
1631 // An empty leaf list defaults to Float_t
1732 std::unordered_map<std::string, std::string> typeNameToLeafList = {{" int" , " /I" },
@@ -63,16 +78,18 @@ void ROOT_TBranch_ContainerImp::setParent(std::shared_ptr<IStorage_Container> pa
6378 return ;
6479}
6580
66- void ROOT_TBranch_ContainerImp::setupWrite (std::string const & type)
81+ void ROOT_TBranch_ContainerImp::setupWrite (std::type_info const & type)
6782{
6883 if (m_tree == nullptr ) {
6984 throw std::runtime_error (" ROOT_TBranch_ContainerImp::setupWrite no tree found" );
7085 }
7186
72- auto dictInfo = TDictionary::GetDictionary (type. c_str () );
87+ auto dictInfo = TDictionary::GetDictionary (type);
7388 if (m_branch == nullptr ) {
7489 if (!dictInfo) {
75- throw std::runtime_error (" ROOT_TBranch_ContainerImp::setupWrite unsupported type: " + type);
90+ throw std::runtime_error (
91+ std::string{" ROOT_TBranch_ContainerImp::setupWrite unsupported type: " } +
92+ DemangleName (type));
7693 }
7794 if (dictInfo->Property () & EProperty::kIsFundamental ) {
7895 m_branch = m_tree->Branch (col_name ().c_str (),
@@ -117,7 +134,7 @@ void ROOT_TBranch_ContainerImp::commit()
117134 return ;
118135}
119136
120- bool ROOT_TBranch_ContainerImp::read (int id, void const ** data, std::string & type)
137+ bool ROOT_TBranch_ContainerImp::read (int id, void const ** data, std::type_info const & type)
121138{
122139 if (m_tfile == nullptr ) {
123140 throw std::runtime_error (" ROOT_TBranch_ContainerImp::read no file attached" );
@@ -138,23 +155,34 @@ bool ROOT_TBranch_ContainerImp::read(int id, void const** data, std::string& typ
138155 return false ;
139156
140157 void * branchBuffer = nullptr ;
141- auto dictInfo = TClass::GetClass (type. c_str () );
158+ auto dictInfo = TDictionary::GetDictionary (type);
142159 int branchStatus = 0 ;
143- if (dictInfo) {
144- branchBuffer = dictInfo-> New ();
145- branchStatus = m_tree-> SetBranchAddress (
146- col_name (). c_str (), &branchBuffer, TClass::GetClass (type. c_str ()), EDataType:: kOther_t , true );
147- } else {
148- // Assume this is a fundamental type like int or double
149- auto fundInfo = static_cast <TDataType*>(TDictionary::GetDictionary (type. c_str ()) );
160+ if (! dictInfo) {
161+ throw std::runtime_error (std::string{ " ROOT_TBranch_ContainerImp::read unsupported type: " } +
162+ DemangleName (type));
163+ }
164+
165+ if (dictInfo-> Property () & EProperty:: kIsFundamental ) {
166+ auto fundInfo = static_cast <TDataType*>(dictInfo );
150167 branchBuffer = new char [fundInfo->Size ()];
151168 branchStatus = m_tree->SetBranchAddress (
152169 col_name ().c_str (), &branchBuffer, nullptr , EDataType (fundInfo->GetType ()), true );
170+ } else {
171+ auto klass = TClass::GetClass (type);
172+ if (!klass) {
173+ throw std::runtime_error (std::string{" ROOT_TBranch_ContainerImp::read missing TClass" } +
174+ " (col_name='" + col_name () + " ', type='" + DemangleName (type) +
175+ " ')" );
176+ }
177+ branchBuffer = klass->New ();
178+ branchStatus =
179+ m_tree->SetBranchAddress (col_name ().c_str (), &branchBuffer, klass, EDataType::kOther_t , true );
153180 }
154181
155182 if (branchStatus < 0 ) {
156183 throw std::runtime_error (
157- " ROOT_TBranch_ContainerImp::read SetBranchAddress() failed with error code " +
184+ std::string{" ROOT_TBranch_ContainerImp::read SetBranchAddress() failed" } + " (col_name='" +
185+ col_name () + " ', type='" + DemangleName (type) + " ')" + " with error code " +
158186 std::to_string (branchStatus));
159187 }
160188
0 commit comments