All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tclass.cc
Go to the documentation of this file.
1 #include <algorithm>
2 
3 #include "tclass.h"
4 #include "compile.h"
5 
6 #include "TClassTable.h"
7 #include "TClass.h"
8 #include "TDictionary.h"
9 #include "TDictAttributeMap.h"
10 #include "TProtoClass.h"
11 #include "TSystem.h"
12 #include "TParameter.h"
13 #include "TFunction.h"
14 #include "TClassEdit.h"
15 
17  classname = uscript::Compiler::Intern(std::string(classname));
18  auto search = classes.find(classname);
19  // already added -- ok
20  if (search != classes.end()) {
21  return &search->second;
22  }
23 
24  DictFuncPtr_t classdict = gClassTable->GetDict(classname);
25 
26  // no classdict -- bad
27  if (!classdict) return NULL;
28 
29  std::map<const char *, uscript::TField> fields;
30 
31  TClass *tclass = classdict();
32 
33  // handle vector case
34  if (tclass->GetCollectionType() == ROOT::kSTLvector) {
35  TClassInfo tclassinfo;
36  tclassinfo.is_vec = true;
37  tclassinfo.name = classname;
38  tclassinfo.size = sizeof(std::vector<void*>); // all vectors in layout should have the same size
39 
40  TClassEdit::TSplitType split(classname);
41  // get the dictionary for the sub-class
42  classdict = gClassTable->GetDict(split.fElements[1].c_str());
43 
44  // vec data
45  uscript::TData data;
46  data.len = -1;
47  data.info = NULL;
48 
49  if (classdict == NULL) {
50  // try to see if it is a basic type
51  if (split.fElements[1] == "bool" || split.fElements[1] == "Bool_t") {
52  data.type = uscript::FIELD_BOOL;
53  }
54  else if (split.fElements[1] == "float" || split.fElements[1] == "Float_t") {
56  }
57  else if (split.fElements[1] == "double" || split.fElements[1] == "Double_t") {
59  }
60  else if (split.fElements[1] == "int" || split.fElements[1] == "Int_t") {
61  data.type = uscript::FIELD_INT;
62  }
63  else if (split.fElements[1] == "unsigned" || split.fElements[1] == "UInt_t") {
65  }
66  else return NULL;
67  }
68  // a dictionary exists -- try to add it
69  else {
70  TClassInfo *sub_info = Add(split.fElements[1].c_str());
71  data.info = sub_info;
73  }
74 
75  tclassinfo.vec_data = data;
76  return &classes.insert({classname, tclassinfo}).first->second;
77  }
78 
79  TList *members = tclass->GetListOfDataMembers();
80  TIterator *m_iterator = members->MakeIterator();
81  TObject *obj;
82  while ((obj = m_iterator->Next()) != NULL) {
83  TDataMember *member = (TDataMember *)obj;
84 
85  uscript::TField this_field;
86  this_field.offset = member->GetOffset();
87  bool can_use = true;
88  TDataType *basic_type = member->GetDataType();
89 
90  // get size
91  this_field.data.len = -1;
92  if (member->GetArrayDim() > 0) {
93  this_field.data.len = 1;
94  for (unsigned i = 0; i < member->GetArrayDim(); i++) {
95  this_field.data.len = this_field.data.len * member->GetMaxIndex(i);
96  }
97  }
98 
99  // treat enum as unsigned with size 4
100  if (member->IsEnum()) {
101  this_field.data.info = NULL; // no tclass info
102  this_field.data.type = uscript::FIELD_ENUM;
103  assert(member->GetUnitSize() == 4);// make sure size is actually 4
104  }
105  // non-enum basic type
106  else if (basic_type != NULL) {
107  this_field.data.info = NULL; // no tclass info
108  switch (basic_type->GetType()) {
109  case kBool_t:
110  this_field.data.type = uscript::FIELD_BOOL;
111  break;
112  case kFloat_t:
113  this_field.data.type = uscript::FIELD_FLOAT;
114  break;
115  case kDouble_t:
116  this_field.data.type = uscript::FIELD_DOUBLE;
117  break;
118  case kInt_t:
119  this_field.data.type = uscript::FIELD_INT;
120  break;
121  case kUInt_t:
122  this_field.data.type = uscript::FIELD_UNSIGNED;
123  break;
124  default: // don't allow any other field type
125  can_use = false;
126  break;
127  }
128  }
129  // complex-type (TClass)
130  else {
131  // must have a class dictionary
132  uscript::TClassInfo *field_info = Add(member->GetTypeName());
133  if (field_info != NULL) {
134  this_field.data.type = uscript::FIELD_TINSTANCE;
135  this_field.data.info = field_info;
136  }
137  else {
138  can_use = false;
139  }
140  }
141  if (can_use) {
142  fields[uscript::Compiler::Intern(std::string(obj->GetName()))] = this_field;
143  }
144  }
145  uscript::TClassInfo tclassinfo;
146  tclassinfo.fields = std::move(fields);
147  tclassinfo.name = classname;
148  tclassinfo.size = tclass->GetClassSize();
149  tclassinfo.is_vec = false;
150  return &classes.insert({classname, tclassinfo}).first->second;
151 }
152 
153 int uscript::TData::Size() const {
154  switch (type) {
155  case uscript::FIELD_BOOL: return sizeof(bool);
156  case uscript::FIELD_INT: return sizeof(int);
157  case uscript::FIELD_UNSIGNED: return sizeof(unsigned);
158  case uscript::FIELD_FLOAT: return sizeof(float);
159  case uscript::FIELD_DOUBLE: return sizeof(double);
160  case uscript::FIELD_ENUM: return 4;
161  case uscript::FIELD_TINSTANCE: return info->size;
162  }
163  // unreachable
164  return -1;
165 }
166 
167 int uscript::TData::Length(uint8_t *loc) const {
168  if (info && info->is_vec) {
169  // FIXME: this is probably implementation defined -- needs to be fixed
170  uint8_t **vec = (uint8_t**)loc;
171  uint8_t *start = vec[0];
172  uint8_t *end = vec[1];
173  return (end - start) / Size();
174  }
175  else {
176  return len;
177  }
178 
179 }
180 
std::unordered_map< const char *, TClassInfo > classes
Definition: tclass.h:47
TData data
Definition: tclass.h:33
static constexpr bool
std::map< const char *, TField > fields
Definition: tclass.h:37
int Length(uint8_t *loc) const
Definition: tclass.cc:167
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
int Size() const
Definition: tclass.cc:153
TClassInfo * info
Definition: tclass.h:24
std::string name
Definition: tclass.h:38
static const char * Intern(const std::string &str)
Definition: compile.h:138
TFieldType type
Definition: tclass.h:25
TClassInfo * Add(const char *classname)
Definition: tclass.cc:16