Belle II Software  release-05-02-19
StoreEntry.cc
1 #include <framework/datastore/StoreEntry.h>
2 #include <framework/dataobjects/RelationContainer.h>
3 #include <framework/logging/Logger.h>
4 
5 #include <TClass.h>
6 #include <TClonesArray.h>
7 
8 #include <utility>
9 
10 using namespace Belle2;
11 
12 StoreEntry::StoreEntry(bool isArray_, TClass* cl, std::string name_, bool dontWriteOut_):
13  isArray(isArray_),
14  dontWriteOut(dontWriteOut_),
15  objClass(cl),
16  object(nullptr),
17  ptr(nullptr),
18  name(std::move(name_))
19 {
21 }
22 
24 {
25  if (object)
26  return;
27  if (isArray) {
28  object = new TClonesArray(objClass);
29  } else {
30  // Oh dear, where to begin. So we want to create a new object of the class
31  // we have and we require this class to be inheriting from TObject. Fine,
32  // but there could be classes with multiple inheritance where the TObject
33  // is not the first base class. In this case the memory layout puts the
34  // TObject not at the beginning of the instance but at an offset. The
35  // compiler knows this so a static_cast<> or c-style cast from one to the
36  // other will correctly modify the pointing address to point to the start
37  // of TObject, but TClass::New() gives us a void* pointer so the compiler
38  // doesn't know about that. So to be on the safe side we have to manually
39  // fix the pointer address using the BaseClassOffset from TClass. And since
40  // pointer arithmetic on void* is forbidden we have to go to char* first.
41  auto* rawPtr = reinterpret_cast<char*>(objClass->New());
42  int offset = objClass->GetBaseClassOffset(TObject::Class());
43  if (offset < 0) B2FATAL("Class " << objClass->GetName() << " does not inherit from TObject");
44  object = reinterpret_cast<TObject*>(rawPtr + offset);
45  }
46 }
47 
49 {
50  if (isArray) {
51  static_cast<TClonesArray*>(object)->Delete();
52  } else if (object->IsA() == RelationContainer::Class()) {
53  static_cast<RelationContainer*>(object)->Clear();
54  } else {
55  //we don't know anything about object, so we just delete it here (and recreate later)
56  delete object;
57  object = nullptr;
58  }
59 }
60 
62 {
64  if (object == nullptr)
66 
67  ptr = object;
68 }
69 
71 {
72  recreate();
73  ptr = nullptr;
74 }
75 
76 TClonesArray* StoreEntry::getPtrAsArray() const
77 {
78  if (!isArray)
79  return nullptr;
80  return static_cast<TClonesArray*>(ptr);
81 }
Belle2::StoreEntry::object
TObject * object
The pointer to the actual object.
Definition: StoreEntry.h:41
Belle2::RelationContainer
Class to store relations between StoreArrays in the DataStore.
Definition: RelationContainer.h:35
Belle2::StoreEntry::invalidate
void invalidate()
invalidate entry for next event.
Definition: StoreEntry.cc:70
Belle2::StoreEntry::isArray
bool isArray
Flag that indicates whether the object is a TClonesArray.
Definition: StoreEntry.h:32
Belle2::StoreEntry::recreate
void recreate()
Reset stored object to defaults, set ptr to new object.
Definition: StoreEntry.cc:61
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::StoreEntry::getPtrAsArray
TClonesArray * getPtrAsArray() const
Return ptr cast to TClonesArray.
Definition: StoreEntry.cc:76
Belle2::StoreEntry::ptr
TObject * ptr
The pointer to the returned object, either equal to 'object' or null, depending on wether the object ...
Definition: StoreEntry.h:44
Belle2::StoreEntry::resetForGetEntry
void resetForGetEntry()
Reset stored object to defaults, or nullptr.
Definition: StoreEntry.cc:48
Belle2::StoreEntry::recoverFromNullObject
void recoverFromNullObject()
Recreate object if null.
Definition: StoreEntry.cc:23
Belle2::StoreEntry::objClass
TClass * objClass
class of object.
Definition: StoreEntry.h:34