]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTOUT.cxx
minor coverity defect: added protection for self-assignment
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUT.cxx
CommitLineData
62bb3cd4 1// $Id$
2
0f1882a7 3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
62bb3cd4 18
4c4b4801 19/// @file AliHLTOUT.cxx
20/// @author Matthias Richter
21/// @date
22/// @brief The control class for HLTOUT data.
23///
62bb3cd4 24
4de7334f 25#include <cerrno>
5db0e774 26#include <cassert>
62bb3cd4 27#include "AliHLTOUT.h"
e5701dcf 28#include "AliHLTMessage.h"
466d4e62 29#include "AliHLTMisc.h"
c1292031 30#include "TSystem.h"
31#include "TClass.h"
32#include "TROOT.h"
4c4b4801 33#include <sstream>
34#include <iomanip>
35using namespace std;
62bb3cd4 36
37/** ROOT macro for the implementation of ROOT specific class methods */
38ClassImp(AliHLTOUT)
39
40AliHLTOUT::AliHLTOUT()
4de7334f 41 :
42 fSearchDataType(kAliHLTVoidDataType),
43 fSearchSpecification(kAliHLTVoidDataSpec),
44dc7683 44 fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
0f1882a7 45 fFlags(kSkipProcessed),
4de7334f 46 fBlockDescList(),
0f1882a7 47 fCurrent(0),
5db0e774 48 fpBuffer(NULL),
44dc7683 49 fDataHandlers(),
4c4b4801 50 fbVerbose(false),
b005ef92 51 fLog()
e5701dcf 52 , fpDataObject(NULL)
53 , fpObjectBuffer(NULL)
54 , fObjectBufferSize(0)
c63e8be4 55 , fCurrentEventId(kAliHLTVoidEventID)
4de7334f 56{
62bb3cd4 57 // see header file for class documentation
58 // or
59 // refer to README to build package
60 // or
61 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
62}
63
64AliHLTOUT::~AliHLTOUT()
4de7334f 65{
66 // see header file for class documentation
0f1882a7 67 if (CheckStatusFlag(kIsSubCollection)) {
b005ef92 68 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "~AliHLTOUT" , __FILE__ , __LINE__ , "severe internal error: collection has not been released, potential crash due to invalid pointer");
0f1882a7 69 }
e5701dcf 70
71 if (fpDataObject) {
72 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
73 }
74 fpDataObject=NULL;
4de7334f 75}
b005ef92 76AliHLTOUT* AliHLTOUT::fgGlobalInstance=NULL;
4de7334f 77
5db0e774 78int AliHLTOUT::Init()
79{
80 // see header file for class documentation
81 int iResult=0;
f3c1d403 82
83 // ignore if already initialized
84 if (fBlockDescList.size()>0) {
f3c1d403 85 return 0;
86 }
87
18b56222 88 SetStatusFlag(kCollecting);
5db0e774 89 if ((iResult=GenerateIndex())>=0) {
90 if ((iResult=InitHandlers())>=0) {
91 }
92 }
18b56222 93 ClearStatusFlag(kCollecting);
5db0e774 94 return iResult;
95}
96
4de7334f 97int AliHLTOUT::GetNofDataBlocks()
98{
99 // see header file for class documentation
100 return fBlockDescList.size();
101}
102
5db0e774 103int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
0f1882a7 104 AliHLTModuleAgent::AliHLTOUTHandlerType handlerType,
105 bool skipProcessed)
4de7334f 106{
107 // see header file for class documentation
0f1882a7 108 fCurrent=0;
4de7334f 109 fSearchDataType=dt;
110 fSearchSpecification=spec;
44dc7683 111 fSearchHandlerType=handlerType;
0f1882a7 112 if (skipProcessed) SetStatusFlag(kSkipProcessed);
113 else ClearStatusFlag(kSkipProcessed);
049b43b2 114 return FindAndSelectDataBlock();
4de7334f 115}
116
117int AliHLTOUT::SelectNextDataBlock()
118{
119 // see header file for class documentation
0f1882a7 120 if (fCurrent>=fBlockDescList.size()) return -ENOENT;
049b43b2 121 fCurrent++;
122 return FindAndSelectDataBlock();
123}
124
125int AliHLTOUT::FindAndSelectDataBlock()
126{
127 // see header file for class documentation
128 if (CheckStatusFlag(kLocked)) return -EPERM;
4de7334f 129 int iResult=-ENOENT;
0f1882a7 130 while (fCurrent<fBlockDescList.size() && iResult==-ENOENT) {
131 if (fBlockDescList[fCurrent]==fSearchDataType &&
132 (fSearchSpecification==kAliHLTVoidDataSpec || fBlockDescList[fCurrent]==fSearchSpecification) &&
512302d3 133 (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent)==fSearchHandlerType) &&
0f1882a7 134 (!CheckStatusFlag(kBlockSelection) || fBlockDescList[fCurrent].IsSelected()) &&
135 (!CheckStatusFlag(kSkipProcessed) || !fBlockDescList[fCurrent].IsProcessed())) {
136 iResult=fBlockDescList[fCurrent].GetIndex();
049b43b2 137 // TODO: check the byte order on the current system and the byte order of the
c5123824 138 // data block, print warning when mismatch and user did not check
13398559 139 //AliHLTOUTByteOrder blockBO=CheckByteOrder();
06f53caf 140 CheckByteOrder();
049b43b2 141 /*
142 if (blockBO!=fByteOrder) {
143 SetStatusFlag(kByteOrderWarning);
144
145 }
146 */
147 ClearStatusFlag(kByteOrderChecked);
148
149 // TODO: check the alignment on the current system and the alignment of the
c5123824 150 // data block, print warning when mismatch and user did not check
049b43b2 151 ClearStatusFlag(kAlignmentChecked);
18b56222 152
153 break;
4de7334f 154 }
049b43b2 155 fCurrent++;
4de7334f 156 }
157 return iResult;
158}
159
160int AliHLTOUT::GetDataBlockDescription(AliHLTComponentDataType& dt, AliHLTUInt32_t& spec)
161{
162 // see header file for class documentation
163 int iResult=-ENOENT;
0f1882a7 164 if (fCurrent<fBlockDescList.size()) {
4de7334f 165 iResult=0;
0f1882a7 166 dt=fBlockDescList[fCurrent];
167 spec=fBlockDescList[fCurrent];
4de7334f 168 }
169 return iResult;
170}
171
c5123824 172const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::GetDataBlockHandlerDesc()
173{
174 // see header file for class documentation
512302d3 175 return FindHandlerDesc(fCurrent);
c5123824 176}
177
178AliHLTModuleAgent::AliHLTOUTHandlerType AliHLTOUT::GetDataBlockHandlerType()
179{
180 // see header file for class documentation
512302d3 181 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=FindHandlerDesc(fCurrent);
c5123824 182 AliHLTModuleAgent::AliHLTOUTHandlerType type=desc;
183 return type;
184}
185
5db0e774 186AliHLTUInt32_t AliHLTOUT::GetDataBlockIndex()
187{
188 // see header file for class documentation
0f1882a7 189 if (fCurrent>=fBlockDescList.size()) return AliHLTOUTInvalidIndex;
190 return fBlockDescList[fCurrent].GetIndex();
5db0e774 191}
192
4de7334f 193int AliHLTOUT::GetDataBuffer(const AliHLTUInt8_t* &pBuffer, AliHLTUInt32_t& size)
194{
195 // see header file for class documentation
196 int iResult=-ENOENT;
197 pBuffer=NULL;
198 size=0;
0f1882a7 199 if (fCurrent<fBlockDescList.size()) {
200 if ((iResult=fBlockDescList[fCurrent].GetDataBuffer(pBuffer, size))>=0) {
4de7334f 201 fpBuffer=pBuffer;
202 }
203 }
204 return iResult;
205}
206
207int AliHLTOUT::ReleaseDataBuffer(const AliHLTUInt8_t* pBuffer)
208{
209 // see header file for class documentation
210 int iResult=0;
211 if (pBuffer==fpBuffer) {
212 fpBuffer=NULL;
213 } else {
b005ef92 214 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "ReleaseDataBuffer" , __FILE__ , __LINE__ , "buffer %p does not match the provided one %p", pBuffer, fpBuffer);
4de7334f 215 }
216 return iResult;
217}
218
c5123824 219AliHLTModuleAgent* AliHLTOUT::GetAgent()
220{
221 // see header file for class documentation
222 AliHLTModuleAgent* pAgent=NULL;
512302d3 223 pAgent=FindHandlerDesc(fCurrent);
c5123824 224 return pAgent;
225}
226
626bfcc1 227AliHLTOUTHandler* AliHLTOUT::GetHandler()
228{
229 // see header file for class documentation
230 AliHLTOUTHandler* pHandler=NULL;
512302d3 231 pHandler=FindHandlerDesc(fCurrent);
626bfcc1 232 return pHandler;
233}
234
c5123824 235int AliHLTOUT::WriteESD(const AliHLTUInt8_t* /*pBuffer*/, AliHLTUInt32_t /*size*/, AliHLTComponentDataType /*dt*/, AliESDEvent* /*tgtesd*/) const
236{
237 // see header file for class documentation
b005ef92 238 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "WriteESD" , __FILE__ , __LINE__ , "method not implemented in base class");
c5123824 239 return -ENOSYS;
240}
241
4de7334f 242int AliHLTOUT::AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc)
243{
62bb3cd4 244 // see header file for class documentation
049b43b2 245 if (!CheckStatusFlag(kCollecting)) return -EPERM;
4de7334f 246 int iResult=0;
247 fBlockDescList.push_back(desc);
248 return iResult;
62bb3cd4 249}
049b43b2 250
13398559 251AliHLTOUT::AliHLTOUTByteOrder AliHLTOUT::CheckByteOrder()
049b43b2 252{
5db0e774 253 // see header file for class documentation
0f1882a7 254 if (fCurrent<fBlockDescList.size()) {
049b43b2 255 SetStatusFlag(kByteOrderChecked);
0f1882a7 256 AliHLTOUT::AliHLTOUTByteOrder order=CheckBlockByteOrder(fBlockDescList[fCurrent].GetIndex());
049b43b2 257 return order;
258 }
259 return kInvalidByteOrder;
260}
261
13398559 262int AliHLTOUT::CheckAlignment(AliHLTOUT::AliHLTOUTDataType type)
049b43b2 263{
5db0e774 264 // see header file for class documentation
0f1882a7 265 if (fCurrent<fBlockDescList.size()) {
049b43b2 266 SetStatusFlag(kAlignmentChecked);
0f1882a7 267 int alignment=CheckBlockAlignment(fBlockDescList[fCurrent].GetIndex(), type);
049b43b2 268 return alignment;
269 }
270 return -ENOENT;
271}
5db0e774 272
273int AliHLTOUT::InitHandlers()
274{
275 // see header file for class documentation
276 int iResult=0;
277 AliHLTOUTIndexList remnants;
44dc7683 278 int iCount=0;
a3ef3c1d 279 for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
44dc7683 280 iCount++;
5db0e774 281 remnants.push_back(GetDataBlockIndex());
282 AliHLTComponentDataType dt=kAliHLTVoidDataType;
283 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
e94eb049 284 if (GetDataBlockDescription(dt, spec)<0) break;
f94e8c27 285 bool bHaveHandler=false;
5db0e774 286 for (AliHLTModuleAgent* pAgent=AliHLTModuleAgent::GetFirstAgent(); pAgent && iResult>=0; pAgent=AliHLTModuleAgent::GetNextAgent()) {
287 AliHLTModuleAgent::AliHLTOUTHandlerDesc handlerDesc;
626bfcc1 288 if (pAgent->GetHandlerDescription(dt, spec, handlerDesc)>0) {
5db0e774 289 AliHLTOUTHandlerListEntry entry(pAgent->GetOutputHandler(dt, spec), handlerDesc, pAgent, GetDataBlockIndex());
c5123824 290 InsertHandler(fDataHandlers, entry);
5db0e774 291 remnants.pop_back();
f94e8c27 292 bHaveHandler=true;
4c4b4801 293 if (fbVerbose) {
294 stringstream sout;
295 sout << "adding handler for block " << AliHLTComponent::DataType2Text(dt).c_str()
296 << " 0x" << setfill('0') << setw(8) << hex << spec;
297 cout << sout.str() << endl;
298 }
5db0e774 299 break;
300 }
301 }
f94e8c27 302 if (!bHaveHandler && (dt==kAliHLTDataTypeESDObject || dt==kAliHLTDataTypeESDTree)) {
303 // ESDs are handled by the framework
304 remnants.pop_back();
305 }
5db0e774 306 }
44dc7683 307
308 // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
309 // criterion
310 if (GetNofDataBlocks()>iCount) {
b005ef92 311 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, GetNofDataBlocks());
44dc7683 312 }
313
314 // warning if handler not found
5db0e774 315 if (remnants.size()>0) {
b005ef92 316 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "InitHandlers" , __FILE__ , __LINE__ , "no handlers found for %d data blocks out of %d", remnants.size(), iCount);
13398559 317 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
8decd484 318 for (AliHLTOUTIndexList::iterator element=remnants.begin();
319 element!=remnants.end() && block!=fBlockDescList.end();
320 element++) {
5db0e774 321 for (int trials=0; trials<2; trials++) {
322 do {
323 // we start searching the index from the current position in the block list
324 if ((*block).GetIndex()==*element) break;
325 } while ((++block)!=fBlockDescList.end());
326 if (block==fBlockDescList.end()) {
327 // rewind and try again
328 block=fBlockDescList.begin();
329 }
330 }
331 assert(block!=fBlockDescList.end());
5db0e774 332 }
333 }
4c4b4801 334
335 if (fbVerbose) Print();
336
5db0e774 337 return iResult;
338}
339
c5123824 340int AliHLTOUT::InsertHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTOUTHandlerListEntry &entry)
5db0e774 341{
342 // see header file for class documentation
343 int iResult=0;
c5123824 344 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
b005ef92 345 for (; element!=list.end();
346 element++) {
5db0e774 347 if (entry==(*element)) break;
5db0e774 348 }
c5123824 349 if (element==list.end()) {
350 list.push_back(entry);
5db0e774 351 } else {
a3ef3c1d 352 element->AddIndex(const_cast<AliHLTOUTHandlerListEntry&>(entry));
5db0e774 353 }
354 return iResult;
355}
356
b005ef92 357int AliHLTOUT::FillHandlerList(AliHLTOUTHandlerListEntryVector& list, AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
358{
359 // see header file for class documentation
360 int iResult=0;
361 for (iResult=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec, handlerType);
362 iResult>=0;
363 iResult=SelectNextDataBlock()) {
364 AliHLTComponentDataType dt=kAliHLTVoidDataType;
365 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
366 GetDataBlockDescription(dt, spec);
367 AliHLTOUTHandler* pHandler=GetHandler();
368 if (!pHandler) {
369 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "FillHandlerList" , __FILE__ , __LINE__ ,
370 "missing HLTOUT handler for block of type kChain: agent %s, data type %s, specification %#x, ... skipping data block",
371 GetAgent()?GetAgent()->GetModuleId():"invalid",
372 AliHLTComponent::DataType2Text(dt).c_str(), spec);
373 } else {
374 InsertHandler(list, GetDataBlockHandlerDesc());
375 }
376 }
377 // TODO: the return value of SelectFirst/NextDataBlock must be
378 // changed in order to avoid this check
379 if (iResult==-ENOENT) iResult=0;
380
381 return iResult;
382}
383
384int AliHLTOUT::RemoveEmptyDuplicateHandlers(AliHLTOUTHandlerListEntryVector& list)
385{
386 // see header file for class documentation
387 int iResult=0;
388 AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
389 while (element!=list.end()) {
390 if (element->IsEmpty()) {
391 AliHLTOUTHandler* pHandler=*element;
392 AliHLTModuleAgent* pAgent=*element;
393 AliHLTModuleAgent::AliHLTOUTHandlerDesc desc=*element;
394 if (FindHandler(list, desc)>=0) {
395 element=list.erase(element);
396 if (pAgent) {
397 pAgent->DeleteOutputHandler(pHandler);
398 }
399 // we are already at the next element
400 continue;
401 }
402 }
403 element++;
404 }
405 return iResult;
406}
407
408int AliHLTOUT::FindHandler(AliHLTOUTHandlerListEntryVector& list, const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc)
409{
410 // see header file for class documentation
411 for (int i=0; i<(int)list.size(); i++) {
412 if (list[i]==desc) return i;
413 }
414 return -ENOENT;
415}
416
417int AliHLTOUT::InvalidateBlocks(AliHLTOUTHandlerListEntryVector& list)
418{
419 // see header file for class documentation
420 for (AliHLTOUTHandlerListEntryVector::iterator element=list.begin();
421 element!=list.end();
422 element++) {
423 element->InvalidateBlocks();
424 }
425 return 0;
426}
427
44dc7683 428const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
626bfcc1 429{
430 // see header file for class documentation
f3c1d403 431 if (blockIndex<fBlockDescList.size()) {
432 return fBlockDescList[blockIndex].GetHandlerDesc();
626bfcc1 433 }
44dc7683 434 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
626bfcc1 435}
436
437AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
438 :
439 fpHandler(NULL),
440 fpHandlerDesc(NULL),
441 fpAgent(NULL),
442 fBlocks()
443{
444 // see header file for class documentation
445}
446
5db0e774 447AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(AliHLTOUTHandler* pHandler,
448 AliHLTModuleAgent::AliHLTOUTHandlerDesc& handlerDesc,
449 AliHLTModuleAgent* pAgent,
450 AliHLTUInt32_t index)
451 :
452 fpHandler(pHandler),
626bfcc1 453 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 454 fpAgent(pAgent),
455 fBlocks()
456{
457 // see header file for class documentation
626bfcc1 458 *fpHandlerDesc=handlerDesc;
5db0e774 459 fBlocks.push_back(index);
460}
461
462AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry(const AliHLTOUTHandlerListEntry& src)
463 :
464 fpHandler(src.fpHandler),
626bfcc1 465 fpHandlerDesc(new AliHLTModuleAgent::AliHLTOUTHandlerDesc),
5db0e774 466 fpAgent(src.fpAgent),
467 fBlocks()
468{
469 // see header file for class documentation
626bfcc1 470 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 471 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
472}
473
fb24bec7 474AliHLTOUT::AliHLTOUTHandlerListEntry::~AliHLTOUTHandlerListEntry()
475{
476 // see header file for class documentation
626bfcc1 477 if (fpHandlerDesc) delete fpHandlerDesc;
478 fpHandlerDesc=NULL;
fb24bec7 479}
480
5db0e774 481AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTHandlerListEntry::operator=(const AliHLTOUTHandlerListEntry& src)
482{
483 // see header file for class documentation
b5ccc144 484 if (this==&src) return *this;
5db0e774 485 fpHandler=src.fpHandler;
44dc7683 486 if (src.fpHandlerDesc)
487 *fpHandlerDesc=*src.fpHandlerDesc;
5db0e774 488 fpAgent=src.fpAgent;
489 fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
490 return *this;
491}
492
18b56222 493AliHLTUInt32_t AliHLTOUT::AliHLTOUTHandlerListEntry::operator[](int i) const
494{
495 // see header file for class documentation
b0914d2e 496 return (int)fBlocks.size()>i?fBlocks[i]:AliHLTOUTInvalidIndex;
5db0e774 497}
498
fb24bec7 499bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTOUTHandlerListEntry& entry) const
500{
18b56222 501 // see header file for class documentation
a3ef3c1d 502 if (entry.fpHandler!=fpHandler || fpHandler==NULL) return false;
503 assert(entry.fpAgent==fpAgent);
504 if (entry.fpAgent!=fpAgent) return false;
505 return true;
506}
507
44dc7683 508bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
509{
510 // see header file for class documentation
511 if (!fpHandlerDesc) return false;
512 return *fpHandlerDesc==handlerType;
513}
514
b005ef92 515bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerDesc desc) const
516{
517 // see header file for class documentation
518 if (!fpHandlerDesc) return false;
519 return *fpHandlerDesc==desc;
520}
521
a3ef3c1d 522void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
523{
524 // see header file for class documentation
525 AliHLTOUTIndexList::iterator element;
526 for (element=desc.fBlocks.begin(); element!=desc.fBlocks.end(); element++) {
527 AddIndex(*element);
528 }
fb24bec7 529}
530
18b56222 531void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTUInt32_t index)
532{
533 // see header file for class documentation
5db0e774 534 fBlocks.push_back(index);
535}
626bfcc1 536
0f1882a7 537bool AliHLTOUT::AliHLTOUTHandlerListEntry::HasIndex(AliHLTUInt32_t index) const
200853e2 538{
539 // see header file for class documentation
a3ef3c1d 540 AliHLTOUTIndexList::iterator element;
0f1882a7 541 for (unsigned int i=0; i<fBlocks.size(); i++) {
542 if (fBlocks[i]==index) return true;
a3ef3c1d 543 }
200853e2 544 return false;
545}
546
626bfcc1 547const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
44dc7683 548
ff3b6fed 549AliHLTUInt64_t AliHLTOUT::ByteSwap64(AliHLTUInt64_t src)
44dc7683 550{
551 // see header file for class documentation
552 return ((src & 0xFFULL) << 56) |
553 ((src & 0xFF00ULL) << 40) |
554 ((src & 0xFF0000ULL) << 24) |
555 ((src & 0xFF000000ULL) << 8) |
556 ((src & 0xFF00000000ULL) >> 8) |
557 ((src & 0xFF0000000000ULL) >> 24) |
558 ((src & 0xFF000000000000ULL) >> 40) |
559 ((src & 0xFF00000000000000ULL) >> 56);
560}
561
ff3b6fed 562AliHLTUInt32_t AliHLTOUT::ByteSwap32(AliHLTUInt32_t src)
44dc7683 563{
564 // see header file for class documentation
565 return ((src & 0xFFULL) << 24) |
566 ((src & 0xFF00ULL) << 8) |
567 ((src & 0xFF0000ULL) >> 8) |
568 ((src & 0xFF000000ULL) >> 24);
569}
c1292031 570
571AliHLTOUT* AliHLTOUT::New(AliRawReader* pRawReader)
572{
573 // see header file for class documentation
466d4e62 574 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTRawReader", "libHLTrec.so");
c1292031 575 if (instance) {
576 instance->SetParam(pRawReader);
577 }
578 return instance;
579}
580
581AliHLTOUT* AliHLTOUT::New(TTree* pDigitTree, int event)
582{
583 // see header file for class documentation
466d4e62 584 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
c1292031 585 if (instance) {
586 instance->SetParam(pDigitTree, event);
587 }
588 return instance;
589}
590
466d4e62 591AliHLTOUT* AliHLTOUT::New(const char* filename, int event)
592{
593 // see header file for class documentation
594 AliHLTOUT* instance=AliHLTMisc::LoadInstance((AliHLTOUT*)0, "AliHLTOUTDigitReader", "libHLTrec.so");
595 if (instance) {
596 instance->SetParam(filename, event);
c1292031 597 }
598 return instance;
599}
600
601void AliHLTOUT::Delete(AliHLTOUT* pInstance)
602{
603 // see header file for class documentation
604 if (!pInstance) return;
b005ef92 605 if (pInstance==fgGlobalInstance) return;
c1292031 606
607 // check if the library is still there in order to have the
608 // destructor available
609 TClass* pCl1=TClass::GetClass("AliHLTOUTRawReader");
610 TClass* pCl2=TClass::GetClass("AliHLTOUTDigitReader");
611 if (!pCl1 && !pCl2) {
612 AliHLTLogging log;
613 log.Logging(kHLTLogError, "AliHLTOUT::Delete", "HLTOUT handling", "potential memory leak: libHLTrec library not available, skipping destruction %p", pInstance);
614 return;
615 }
616
617 delete pInstance;
618}
619
620void AliHLTOUT::SetParam(AliRawReader* /*pRawReader*/)
621{
622 // see header file for class documentation
623 // default implementation, we should never get here
624 // this function can only be called from the class itsself and
625 // is intended to be used with the New functions. If we get into
626 // the default implementation there is a class mismatch.
627 assert(0);
b005ef92 628 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 629}
630
631void AliHLTOUT::SetParam(TTree* /*pDigitTree*/, int /*event*/)
632{
633 // see header file for class documentation
634 // default implementation, we should never get here
635 // this function can only be called from the class itsself and
636 // is intended to be used with the New functions. If we get into
637 // the default implementation there is a class mismatch.
638 assert(0);
b005ef92 639 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
c1292031 640}
0f1882a7 641
466d4e62 642void AliHLTOUT::SetParam(const char* /*filename*/, int /*event*/)
643{
644 // see header file for class documentation
645 // default implementation, we should never get here
646 // this function can only be called from the class itsself and
647 // is intended to be used with the New functions. If we get into
648 // the default implementation there is a class mismatch.
649 assert(0);
650 fLog.LoggingVarargs(kHLTLogFatal, "AliHLTOUT", "SetParam" , __FILE__ , __LINE__ , "severe internal error: class mismatch");
651}
652
0f1882a7 653int AliHLTOUT::SelectDataBlock()
654{
655 // see header file for class documentation
656 int iResult=0;
657 if (fCurrent>=fBlockDescList.size()) return 0;
658 fBlockDescList[fCurrent].Select(true);
659 EnableBlockSelection();
660 return iResult;
661}
662
e13512e4 663int AliHLTOUT::SelectDataBlocks(const AliHLTOUTHandlerListEntry* pHandlerEntry)
0f1882a7 664{
665 // see header file for class documentation
666 int iResult=0;
e13512e4 667 if (!pHandlerEntry) return 0;
0f1882a7 668
e13512e4 669 AliHLTModuleAgent* pAgent=*pHandlerEntry;
670 AliHLTLogging log;
671 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", "selecting blocks for handler %s", pAgent->GetModuleId());
0f1882a7 672 AliHLTOUTBlockDescriptorVector::iterator element;
673 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
674 block!=fBlockDescList.end();
675 block++) {
e13512e4 676 if (block->GetHandlerDesc()==*pHandlerEntry && pHandlerEntry->HasIndex(block->GetIndex())) {
0f1882a7 677 block->Select(true);
e13512e4 678 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " select block %s", AliHLTComponent::DataType2Text(*block).c_str());
679 } else {
680 log.Logging(kHLTLogDebug, "AliHLTOUT::SelectDataBlocks", "HLTOUT handling", " skip block %s", AliHLTComponent::DataType2Text(*block).c_str());
0f1882a7 681 block->Select(false);
e13512e4 682 }
0f1882a7 683 }
684 EnableBlockSelection();
e13512e4 685
686 // Matthias 2009-07-03 bugfix: the fCurrent position was not reset at that
687 // place. Also I think the data type and specification must be set in order
688 // to make SelectFirst/NextDataBlock working on the selected collection
689 // of data blocks
690 AliHLTModuleAgent::AliHLTOUTHandlerDesc pHandlerDesc=*pHandlerEntry;
691 fSearchDataType=pHandlerDesc;
692 fSearchSpecification=kAliHLTVoidDataSpec;
693 fSearchHandlerType=pHandlerDesc;
694 fCurrent=0;
0f1882a7 695
696 return iResult;
697}
698
699int AliHLTOUT::EnableBlockSelection()
700{
701 // see header file for class documentation
702 SetStatusFlag(kBlockSelection);
703 return 0;
704}
705
706int AliHLTOUT::DisableBlockSelection()
707{
708 // see header file for class documentation
709 ClearStatusFlag(kBlockSelection);
710 return 0;
711}
712
713int AliHLTOUT::ResetBlockSelection()
714{
715 // see header file for class documentation
716 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
717 block!=fBlockDescList.end();
718 block++) {
719 block->Select(false);
720 }
721 return 0;
722}
723
724int AliHLTOUT::MarkDataBlockProcessed()
725{
726 // see header file for class documentation
727 int iResult=0;
728 if (fCurrent>=fBlockDescList.size()) return 0;
729 fBlockDescList[fCurrent].MarkProcessed();
730 return iResult;
731}
732
733int AliHLTOUT::MarkDataBlocksProcessed(const AliHLTOUTHandlerListEntry* pHandlerDesc)
734{
735 // see header file for class documentation
736 int iResult=0;
737 if (!pHandlerDesc) return 0;
738
739 AliHLTOUTBlockDescriptorVector::iterator element;
740 for (AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
741 block!=fBlockDescList.end();
742 block++) {
f3c1d403 743 if (block->GetHandlerDesc()==*pHandlerDesc && pHandlerDesc->HasIndex(block->GetIndex()))
0f1882a7 744 block->MarkProcessed();
745 }
746
747 return iResult;
748}
749
750int AliHLTOUT::AddSubCollection(AliHLTOUT* pCollection)
751{
752 // see header file for class documentation
753 int iResult=0;
754 if (!pCollection) return 0;
755
d4a18597 756 SetStatusFlag(kCollecting);
0f1882a7 757 int index=-1;
758 for (index=pCollection->SelectFirstDataBlock();
759 index>=0;
760 index=pCollection->SelectNextDataBlock()) {
761 AliHLTComponentDataType dt=kAliHLTVoidDataType;
762 AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
763 pCollection->GetDataBlockDescription(dt, spec);
764 AliHLTOUTBlockDescriptor desc(dt, spec, index, pCollection);
765 AddBlockDescriptor(desc);
766 iResult++;
767 }
768 if (iResult>0) {
4562bf66 769 if (CheckStatusFlag(kIsSubCollection)) {
770 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "AddSubCollection" , __FILE__ , __LINE__ , "HLTOUT object %p has already been added as sub-collection", pCollection);
771 } else {
772 pCollection->SetStatusFlag(kIsSubCollection);
773 }
0f1882a7 774 }
d4a18597 775 ClearStatusFlag(kCollecting);
0f1882a7 776
777 return iResult;
778}
779
780int AliHLTOUT::ReleaseSubCollection(AliHLTOUT* pCollection)
781{
782 // see header file for class documentation
783 int iResult=0;
784 if (!pCollection) return 0;
785
b005ef92 786 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
787 while (block!=fBlockDescList.end()) {
0f1882a7 788 if ((*block)==pCollection) {
b005ef92 789 block=fBlockDescList.erase(block);
790 continue;
0f1882a7 791 }
b005ef92 792 block++;
0f1882a7 793 }
4562bf66 794 pCollection->ClearStatusFlag(kIsSubCollection);
0f1882a7 795
796 return iResult;
797}
b005ef92 798
799int AliHLTOUT::Reset()
800{
801 // see header file for class documentation
802 int iResult=0;
803 AliHLTOUTPVector subCollections;
804 AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
805 while (block!=fBlockDescList.end()) {
d4a18597 806 if (!((*block)==this)) {
b005ef92 807 AliHLTOUTPVector::iterator collection=subCollections.begin();
808 for (; collection!=subCollections.end(); collection++)
809 if((*block)==*collection) break;
810 if (collection==subCollections.end())
811 subCollections.push_back(block->GetCollection());
812 }
813 block=fBlockDescList.erase(block);
814 }
815
816 for (AliHLTOUTPVector::iterator collection=subCollections.begin();
4562bf66 817 collection!=subCollections.end(); collection++) {
b005ef92 818 (*collection)->Reset();
4562bf66 819 (*collection)->ClearStatusFlag(kIsSubCollection);
820 }
b005ef92 821
822 ResetInput();
c63e8be4 823 fCurrentEventId=kAliHLTVoidEventID;
b005ef92 824
825 return iResult;
826}
827
828int AliHLTOUT::ResetInput()
829{
830 // default implementation, nothing to do
831 return 0;
832}
f3c1d403 833
834const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::AliHLTOUTBlockDescriptor::GetHandlerDesc()
835{
836 // see header file for class documentation
837 if (fpCollection) {
838 AliHLTOUTHandlerListEntryVector::iterator element=fpCollection->fDataHandlers.begin();
839 while (element!=fpCollection->fDataHandlers.end()) {
840 if (element->HasIndex(GetIndex())) {
841 return *element;
842 }
843 element++;
844 }
845 }
846 return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
847}
e5701dcf 848
849TObject* AliHLTOUT::GetDataObject()
850{
851 // see header file for class documentation
852 if (fpDataObject) {
853 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "data object has not been released, potential memory leak");
854 ReleaseDataBuffer(fpObjectBuffer);
855 }
856 fpObjectBuffer=NULL;
857 fObjectBufferSize=0;
858 fpDataObject=NULL;
859
860 if (GetDataBuffer(fpObjectBuffer, fObjectBufferSize)>=0) {
861 fpDataObject=AliHLTMessage::Extract(fpObjectBuffer, fObjectBufferSize);
862 } else {
863 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "can not fetch data buffer");
864 }
865
866 return fpDataObject;
867}
868
869int AliHLTOUT::ReleaseDataObject(TObject* pObject)
870{
871 // see header file for class documentation
872 if (!pObject) return -EINVAL;
873 if (pObject!=fpDataObject) {
874 fLog.LoggingVarargs(kHLTLogError, "AliHLTOUT", "GetDataObject" , __FILE__ , __LINE__ , "attempt to release wrong data object %p, expected %p", pObject, fpDataObject);
875 return -EINVAL;
876 }
877
878 delete fpDataObject;
879 fpDataObject=NULL;
880 ReleaseDataBuffer(fpObjectBuffer);
881 fpObjectBuffer=NULL;
882 fObjectBufferSize=0;
883
884 return 0;
885}
c63e8be4 886
887void AliHLTOUT::SetEventId(AliHLTUInt64_t id)
888{
889 // see header file for class documentation
890 if (fCurrentEventId!=kAliHLTVoidEventID && fCurrentEventId!=id) {
891 fLog.LoggingVarargs(kHLTLogWarning, "AliHLTOUT", "SetEventId" , __FILE__ , __LINE__ , "event id was already set to 0x%llx, setting now to 0x%llx", fCurrentEventId, id);
892 }
893 fCurrentEventId=id;
894}
4c4b4801 895
896void AliHLTOUT::Print(const char* option) const
897{
898 // print info
899 {
900 for (AliHLTOUTBlockDescriptorVector::const_iterator i=fBlockDescList.begin();
901 i!=fBlockDescList.end(); i++)
902 i->Print(option);
903 }
904 {
905 for (AliHLTOUTHandlerListEntryVector::const_iterator i=fDataHandlers.begin();
906 i!=fDataHandlers.end(); i++)
907 i->Print(option);
908 }
909}
910
911void AliHLTOUT::AliHLTOUTBlockDescriptor::Print(const char* /*option*/) const
912{
913 // print info
914 stringstream sout;
915 sout << "AliHLTOUTBlockDescriptor index 0x" << setfill('0') << setw(8) << hex << right << fIndex
916 << ": " << AliHLTComponent::DataType2Text(fDataType).c_str()
917 << " 0x" << setfill('0') << setw(8) << hex << fSpecification
918 << " processed " << dec << fProcessed;
919 cout << sout.str() << endl;
920}
921
922void AliHLTOUT::AliHLTOUTHandlerListEntry::Print(const char* /*option*/) const
923{
924 // print info
925 stringstream sout;
926 AliHLTModuleAgent::AliHLTOUTHandlerType type=AliHLTModuleAgent::kUnknownOutput;
927 AliHLTComponentDataType dt=kAliHLTVoidDataType;
928 if (this->fpHandlerDesc) {
929 type=*(this->fpHandlerDesc);
930 dt=*(this->fpHandlerDesc);
931 }
932 const char* stype="";
933 switch(type) {
934 case AliHLTModuleAgent::kEsd: stype="ESD"; break;
935 case AliHLTModuleAgent::kRawReader: stype="RawReader"; break;
936 case AliHLTModuleAgent::kRawStream: stype="RawStream"; break;
937 case AliHLTModuleAgent::kChain: stype="Chain"; break;
938 case AliHLTModuleAgent::kProprietary: stype="Proprietary"; break;
939 default: stype="unknown";
940 }
941 sout << "HLTOUT handler: "
942 << " " << type << " (" << stype << ")"
943 << " " << AliHLTComponent::DataType2Text(dt).c_str();
944 cout << sout.str() << endl;
945}