Belle II Software development
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
17using namespace Belle2;
18
19StoreEntry::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
83TClonesArray* 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.
STL namespace.
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