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