Project
Loading...
Searching...
No Matches
TPCFlagsMemberCustomStreamer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include "TPCBase/CalArray.h"
13#include <TMemberStreamer.h>
14#include <TBuffer.h>
15#include <DataFormatsTPC/Defs.h>
16#include <iostream>
17
18// to enable assert statements
19#ifdef NDEBUG
20#undef NDEBUG
21#include <cassert>
22#endif
23
24// The following code provides a specific ROOT I/O streaming method
25// for the mData member of CalArray<o2::tpc::PadFlags>
26// This member was written incorrectly to the TFile in ROOT versions < 6.36, causing
27// segfaults when reading on ARM64 (occassionally).
28// We continue to write it in the incorrect format and fix the reading back.
29
30// See also:
31// - https://github.com/root-project/root/pull/17009
32// - https://its.cern.ch/jira/browse/O2-4671
33
34void MemberVectorPadFlagsStreamer(TBuffer& R__b, void* objp, int n)
35{
36 if (n != 1) {
37 std::cerr << "Error in MemberVectorPadFlagsStreamer : Unexpected n " << n << std::endl;
38 return;
39 }
40 std::vector<o2::tpc::PadFlags>* obj = static_cast<std::vector<o2::tpc::PadFlags>*>(objp);
41 if (R__b.IsReading()) {
42 obj->clear();
43 std::vector<int> R__stl;
44 R__stl.clear();
45 int R__n;
46 R__b >> R__n;
47 R__stl.reserve(R__n);
48 for (int R__i = 0; R__i < R__n; R__i++) {
49 Int_t readtemp;
50 R__b >> readtemp;
51 R__stl.push_back(readtemp);
52 }
53 auto data = reinterpret_cast<unsigned short*>(R__stl.data());
54 constexpr size_t bloatfactor = sizeof(int) / sizeof(o2::tpc::PadFlags);
55 for (int i = 0; i < bloatfactor * R__n; ++i) {
56 obj->push_back(static_cast<o2::tpc::PadFlags>(data[i]));
57 }
58 } else {
59 // We always save things with the old format.
60 R__b << (int)obj->size() / 2;
61 for (size_t i = 0; i < obj->size(); i++) {
62 R__b << (short)obj->at(i);
63 }
64 }
65}
66
67// register the streamer via static global initialization (on library load)
68// the streamer is only correct in combination with new ROOT
69#if ROOT_VERSION_CODE >= ROOT_VERSION(6, 33, 00)
70namespace ROOT
71{
72static __attribute__((used)) int _R__dummyStreamer_3 =
73 ([]() {
74 auto cl = TClass::GetClass<o2::tpc::CalArray<o2::tpc::PadFlags>>();
75 if (cl) {
76 if (!getenv("TPC_PADFLAGS_STREAMER_OFF")) {
77 cl->AdoptMemberStreamer("mData", new TMemberStreamer(MemberVectorPadFlagsStreamer));
78 }
79 } else {
80 // we should never come here ... and if we do we should assert/fail
81 assert(false);
82 }
83 return 0;
84 })();
85} // namespace ROOT
86#endif
int32_t i
void MemberVectorPadFlagsStreamer(TBuffer &R__b, void *objp, int n)
GLdouble n
Definition glcorearb.h:1982
GLboolean * data
Definition glcorearb.h:298
PadFlags
Definition Defs.h:100