bugfix in high level interface: GetFirst/NextObject/Block
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3/**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5 * *
6 * Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 * Timm Steinbeck <timm@kip.uni-heidelberg.de> *
f23a6e1a 8 * for The ALICE Off-line 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 **************************************************************************/
18
bfccbf68 19/** @file AliHLTComponent.cxx
20 @author Matthias Richter, Timm Steinbeck
21 @date
22 @brief Base class implementation for HLT components. */
f23a6e1a 23
0c0c9d99 24#if __GNUC__>= 3
f23a6e1a 25using namespace std;
26#endif
27
66043029 28//#include "AliHLTStdIncludes.h"
f23a6e1a 29#include "AliHLTComponent.h"
30#include "AliHLTComponentHandler.h"
a655eae3 31#include "AliHLTMessage.h"
70ed7d01 32#include "TString.h"
a655eae3 33#include "TObjArray.h"
34#include "TClass.h"
90ebac25 35#include "TStopwatch.h"
f23a6e1a 36
b22e91eb 37/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 38ClassImp(AliHLTComponent);
39
40/** stopwatch macro using the stopwatch guard */
41#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
42//#define ALIHLTCOMPONENT_STOPWATCH(type)
43
44/** stopwatch macro for operations of the base class */
45#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
46/** stopwatch macro for operations of the detector algorithm (DA) */
47#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 48
f23a6e1a 49AliHLTComponent::AliHLTComponent()
85869391 50 :
53feaef5 51 fEnvironment(),
3cde846d 52 fCurrentEvent(0),
a655eae3 53 fEventCount(-1),
54 fFailedEvents(0),
55 fCurrentEventData(),
56 fpInputBlocks(NULL),
57 fCurrentInputBlock(-1),
58 fSearchDataType(kAliHLTVoidDataType),
59 fClassName(),
60 fpInputObjects(NULL),
61 fpOutputBuffer(NULL),
62 fOutputBufferSize(0),
63 fOutputBufferFilled(0),
90ebac25 64 fOutputBlocks(),
65 fpStopwatches(new TObjArray(kSWTypeCount))
70ed7d01 66{
67 // see header file for class documentation
68 // or
69 // refer to README to build package
70 // or
71 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
f23a6e1a 72 memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
70ed7d01 73 if (fgpComponentHandler)
74 fgpComponentHandler->ScheduleRegister(this);
8451168b 75 SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 76}
77
78AliHLTComponent::AliHLTComponent(const AliHLTComponent&)
79 :
9253e11b 80 AliHLTLogging(),
70ed7d01 81 fEnvironment(),
82 fCurrentEvent(0),
a655eae3 83 fEventCount(-1),
84 fFailedEvents(0),
85 fCurrentEventData(),
86 fpInputBlocks(NULL),
87 fCurrentInputBlock(-1),
88 fSearchDataType(kAliHLTVoidDataType),
89 fClassName(),
90 fpInputObjects(NULL),
91 fpOutputBuffer(NULL),
92 fOutputBufferSize(0),
93 fOutputBufferFilled(0),
90ebac25 94 fOutputBlocks(),
95 fpStopwatches(NULL)
70ed7d01 96{
97 // see header file for class documentation
98 HLTFatal("copy constructor untested");
99}
100
101AliHLTComponent& AliHLTComponent::operator=(const AliHLTComponent&)
102{
103 // see header file for class documentation
104 HLTFatal("assignment operator untested");
105 return *this;
f23a6e1a 106}
107
108AliHLTComponent::~AliHLTComponent()
109{
70ed7d01 110 // see header file for function documentation
8451168b 111 CleanupInputObjects();
4498d7d1 112 if (fpStopwatches!=NULL) delete fpStopwatches;
113 fpStopwatches=NULL;
f23a6e1a 114}
115
70ed7d01 116AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 117
85869391 118int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
119{
70ed7d01 120 // see header file for function documentation
85869391 121 int iResult=0;
70ed7d01 122 if (fgpComponentHandler==NULL || bOverwrite!=0)
123 fgpComponentHandler=pCH;
85869391 124 else
125 iResult=-EPERM;
126 return iResult;
127}
128
70ed7d01 129int AliHLTComponent::UnsetGlobalComponentHandler()
130{
131 // see header file for function documentation
85869391 132 return SetGlobalComponentHandler(NULL,1);
133}
134
70ed7d01 135int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv )
f23a6e1a 136{
70ed7d01 137 // see header file for function documentation
f23a6e1a 138 int iResult=0;
139 if (environ) {
140 memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment));
70ed7d01 141 fEnvironment.fParam=environParam;
f23a6e1a 142 }
8451168b 143 const char** pArguments=NULL;
144 int iNofChildArgs=0;
145 TString argument="";
146 int bMissingParam=0;
147 if (argc>0) {
148 pArguments=new const char*[argc];
149 if (pArguments) {
150 for (int i=0; i<argc && iResult>=0; i++) {
151 argument=argv[i];
152 if (argument.IsNull()) continue;
153
154 // benchmark
155 if (argument.CompareTo("benchmark")==0) {
156
157 // loglevel
158 } else if (argument.CompareTo("loglevel")==0) {
159 if ((bMissingParam=(++i>=argc))) break;
160 TString parameter(argv[i]);
161 parameter.Remove(TString::kLeading, ' '); // remove all blanks
162 if (parameter.BeginsWith("0x") &&
163 parameter.Replace(0,2,"",0).IsHex()) {
164 AliHLTComponentLogSeverity loglevel=kHLTLogNone;
7a5ccd96 165 sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
8451168b 166 SetLocalLoggingLevel(loglevel);
167 } else {
168 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
169 iResult=-EINVAL;
170 }
171 } else {
172 pArguments[iNofChildArgs++]=argv[i];
173 }
174 }
175 } else {
176 iResult=-ENOMEM;
177 }
178 }
179 if (bMissingParam) {
180 HLTError("missing parameter for argument %s", argument.Data());
181 iResult=-EINVAL;
182 }
183 if (iResult>=0) {
184 iResult=DoInit(iNofChildArgs, pArguments);
185 }
3cde846d 186 if (iResult>=0) fEventCount=0;
8451168b 187 if (pArguments) delete [] pArguments;
f23a6e1a 188 return iResult;
189}
190
191int AliHLTComponent::Deinit()
192{
70ed7d01 193 // see header file for function documentation
f23a6e1a 194 int iResult=0;
195 iResult=DoDeinit();
196 return iResult;
197}
fa2e9b7c 198
53feaef5 199int AliHLTComponent::DoInit( int argc, const char** argv )
200{
70ed7d01 201 // see header file for function documentation
53feaef5 202 if (argc==0 && argv==NULL) {
203 // this is currently just to get rid of the warning "unused parameter"
204 }
66043029 205 fEventCount=0;
53feaef5 206 return 0;
207}
208
209int AliHLTComponent::DoDeinit()
210{
70ed7d01 211 // see header file for function documentation
66043029 212 fEventCount=0;
53feaef5 213 return 0;
214}
215
70ed7d01 216void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
217{
218 // see header file for function documentation
9ce4bf4a 219 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
220 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
221 strcat( output, ":" );
222 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 223}
224
9ce4bf4a 225string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type )
226{
70ed7d01 227 // see header file for function documentation
9ce4bf4a 228 string out("");
3cde846d 229
9ce4bf4a 230 if (type==kAliHLTVoidDataType) {
231 out="VOID:VOID";
232 } else {
3cde846d 233 // some gymnastics in order to avoid a '0' which is part of either or both
234 // ID and origin terminating the whole string. Unfortunately, string doesn't
235 // stop appending at the '0' if the number of elements to append was
236 // explicitely specified
237 string tmp("");
238 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
239 out.append(tmp.c_str());
9ce4bf4a 240 out.append(":");
3cde846d 241 tmp="";
242 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
243 out.append(tmp.c_str());
9ce4bf4a 244 }
245 return out;
246}
247
248
70ed7d01 249void* AliHLTComponent::AllocMemory( unsigned long size )
250{
251 // see header file for function documentation
85869391 252 if (fEnvironment.fAllocMemoryFunc)
253 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 254 HLTFatal("no memory allocation handler registered");
85869391 255 return NULL;
256}
257
8ede8717 258int AliHLTComponent::MakeOutputDataBlockList( const vector<AliHLTComponentBlockData>& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 259 AliHLTComponentBlockData** outputBlocks )
260{
261 // see header file for function documentation
9ce4bf4a 262 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 263 return -EFAULT;
fa2e9b7c 264 AliHLTUInt32_t count = blocks.size();
265 if ( !count )
266 {
267 *blockCount = 0;
268 *outputBlocks = NULL;
269 return 0;
270 }
8ede8717 271 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 272 if ( !*outputBlocks )
2d7ff710 273 return -ENOMEM;
ca8524df 274 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 275 (*outputBlocks)[i] = blocks[i];
ca8524df 276 if (blocks[i].fDataType==kAliHLTAnyDataType) {
5f5b708b 277 (*outputBlocks)[i].fDataType=GetOutputDataType();
278 /* data type was set to the output data type by the PubSub AliRoot
279 Wrapper component, if data type of the block was ********:****.
280 Now handled by the component base class in order to have same
281 behavior when running embedded in AliRoot
ca8524df 282 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
283 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 284 */
ca8524df 285 }
286 }
fa2e9b7c 287 *blockCount = count;
288 return 0;
289
290}
0c0c9d99 291
70ed7d01 292int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
293{
294 // see header file for function documentation
85869391 295 if (fEnvironment.fGetEventDoneDataFunc)
296 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
297 return -ENOSYS;
298}
299
8ede8717 300int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList)
0c0c9d99 301{
70ed7d01 302 // see header file for function documentation
0c0c9d99 303 int iResult=0;
304 if (pConsumer) {
8ede8717 305 vector<AliHLTComponentDataType> ctlist;
0c0c9d99 306 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(ctlist);
8ede8717 307 vector<AliHLTComponentDataType>::iterator type=ctlist.begin();
5f5b708b 308 //AliHLTComponentDataType ouptdt=GetOutputDataType();
309 //PrintDataTypeContent(ouptdt, "publisher \'%s\'");
0c0c9d99 310 while (type!=ctlist.end() && iResult==0) {
5f5b708b 311 //PrintDataTypeContent((*type), "consumer \'%s\'");
9ce4bf4a 312 if ((*type)==GetOutputDataType() ||
313 (*type)==kAliHLTAnyDataType) {
0c0c9d99 314 if (tgtList) tgtList->push_back(*type);
315 iResult++;
9ce4bf4a 316 // this loop has to be changed in case of multiple output types
0c0c9d99 317 break;
318 }
319 type++;
320 }
321 } else {
322 iResult=-EINVAL;
323 }
324 return iResult;
325}
2d7ff710 326
5f5b708b 327void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format) const
328{
66043029 329 // see header file for function documentation
5f5b708b 330 const char* fmt="publisher \'%s\'";
331 if (format) fmt=format;
332 HLTMessage(fmt, (DataType2Text(dt)).c_str());
333 HLTMessage("%x %x %x %x %x %x %x %x : %x %x %x %x",
334 dt.fID[0],
335 dt.fID[1],
336 dt.fID[2],
337 dt.fID[3],
338 dt.fID[4],
339 dt.fID[5],
340 dt.fID[6],
341 dt.fID[7],
342 dt.fOrigin[0],
343 dt.fOrigin[1],
344 dt.fOrigin[2],
345 dt.fOrigin[3]);
346}
347
70ed7d01 348void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData ) const
349{
350 // see header file for function documentation
2d7ff710 351 blockData.fStructSize = sizeof(blockData);
352 FillShmData( blockData.fShmKey );
353 blockData.fOffset = ~(AliHLTUInt32_t)0;
354 blockData.fPtr = NULL;
355 blockData.fSize = 0;
356 FillDataType( blockData.fDataType );
a655eae3 357 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 358}
359
70ed7d01 360void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData ) const
361{
362 // see header file for function documentation
2d7ff710 363 shmData.fStructSize = sizeof(shmData);
364 shmData.fShmType = gkAliHLTComponentInvalidShmType;
365 shmData.fShmID = gkAliHLTComponentInvalidShmID;
366}
367
70ed7d01 368void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType ) const
369{
370 // see header file for function documentation
ca8524df 371 dataType=kAliHLTAnyDataType;
2d7ff710 372}
373
70ed7d01 374void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
375{
376 // see header file for function documentation
2d7ff710 377 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
378 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
379}
380
70ed7d01 381void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
382{
383 // see header file for function documentation
2d7ff710 384 tgtdt.fStructSize = sizeof(AliHLTComponentDataType);
385 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
386 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
387
9ce4bf4a 388 if ((int)strlen(id)>kAliHLTComponentDataTypefIDsize) {
2d7ff710 389 HLTWarning("data type id %s is too long, truncated to %d", id, kAliHLTComponentDataTypefIDsize);
390 }
391 strncpy(&tgtdt.fID[0], id, kAliHLTComponentDataTypefIDsize);
392
9ce4bf4a 393 if ((int)strlen(origin)>kAliHLTComponentDataTypefOriginSize) {
2d7ff710 394 HLTWarning("data type origin %s is too long, truncated to %d", origin, kAliHLTComponentDataTypefOriginSize);
395 }
396 strncpy(&tgtdt.fOrigin[0], origin, kAliHLTComponentDataTypefOriginSize);
397}
9ce4bf4a 398
399void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
400{
70ed7d01 401 // see header file for function documentation
9ce4bf4a 402 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
403 evtData.fStructSize=sizeof(AliHLTComponentEventData);
404}
405
70ed7d01 406void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
407{
408 // see header file for function documentation
9ce4bf4a 409 TString msg;
410 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
411 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
412 if (dt.fID[i]!=0) msg+=dt.fID[i];
413 else msg+="\\0";
414 }
415 msg+="\" Origin=\"";
416 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
417 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
418 else msg+="\\0";
419 }
420 msg+="\"";
3cde846d 421 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 422}
423
70ed7d01 424int AliHLTComponent::GetEventCount() const
3cde846d 425{
70ed7d01 426 // see header file for function documentation
3cde846d 427 return fEventCount;
428}
429
430int AliHLTComponent::IncrementEventCounter()
431{
70ed7d01 432 // see header file for function documentation
3cde846d 433 if (fEventCount>=0) fEventCount++;
434 return fEventCount;
435}
436
66043029 437int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 438{
439 // see header file for function documentation
440 if (fpInputBlocks!=NULL) {
441 return fCurrentEventData.fBlockCnt;
442 }
443 return 0;
444}
445
446const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
447 const char* classname,
448 int bForce)
449{
450 // see header file for function documentation
90ebac25 451 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 452 fSearchDataType=dt;
453 if (classname) fClassName=classname;
454 else fClassName.clear();
1edbbe49 455 int idx=FindInputBlock(fSearchDataType, 0, 1);
8451168b 456 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 457 TObject* pObj=NULL;
458 if (idx>=0) {
459 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
460 fCurrentInputBlock=idx;
461 } else {
462 }
463 }
464 return pObj;
465}
466
467const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
468 const char* dtOrigin,
469 const char* classname,
470 int bForce)
471{
472 // see header file for function documentation
90ebac25 473 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 474 AliHLTComponentDataType dt;
475 SetDataType(dt, dtID, dtOrigin);
476 return GetFirstInputObject(dt, classname, bForce);
477}
478
479const TObject* AliHLTComponent::GetNextInputObject(int bForce)
480{
481 // see header file for function documentation
90ebac25 482 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 483 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 484 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
485 TObject* pObj=NULL;
486 if (idx>=0) {
487 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
488 fCurrentInputBlock=idx;
489 }
490 }
491 return pObj;
492}
493
1edbbe49 494int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 495{
496 // see header file for function documentation
497 int iResult=-ENOENT;
498 if (fpInputBlocks!=NULL) {
499 int idx=startIdx<0?0:startIdx;
4b98eadb 500 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
1edbbe49 501 if (bObject!=0) {
502 if (fpInputBlocks[idx].fPtr==NULL) continue;
503 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
504 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
505 }
a655eae3 506 if (dt == kAliHLTAnyDataType || fpInputBlocks[idx].fDataType == dt) {
507 iResult=idx;
508 }
509 }
510 }
511 return iResult;
512}
513
514TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
515{
516 // see header file for function documentation
517 TObject* pObj=NULL;
518 if (fpInputBlocks!=NULL) {
4b98eadb 519 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 520 if (fpInputBlocks[idx].fPtr) {
521 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
522 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 523 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
a655eae3 524 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 525 TClass* objclass=msg.GetClass();
526 pObj=msg.ReadObject(objclass);
527 if (pObj && objclass) {
528 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 529 } else {
530 }
1edbbe49 531 //} else {
532 } else if (bForce!=0) {
a655eae3 533 HLTError("size missmatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
534 }
535 } else {
536 HLTFatal("block descriptor empty");
537 }
538 } else {
539 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
540 }
541 } else {
542 HLTError("no input blocks available");
543 }
544
545 return pObj;
546}
547
548TObject* AliHLTComponent::GetInputObject(int idx, const char* classname, int bForce)
549{
550 // see header file for function documentation
551 if (fpInputObjects==NULL) {
552 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
553 }
554 TObject* pObj=NULL;
555 if (fpInputObjects) {
556 pObj=fpInputObjects->At(idx);
557 if (pObj==NULL) {
558 pObj=CreateInputObject(idx, bForce);
559 if (pObj) {
560 fpInputObjects->AddAt(pObj, idx);
561 }
562 }
563 } else {
564 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
565 }
566 return pObj;
567}
568
8451168b 569int AliHLTComponent::CleanupInputObjects()
570{
66043029 571 // see header file for function documentation
8451168b 572 if (!fpInputObjects) return 0;
573 TObjArray* array=fpInputObjects;
574 fpInputObjects=NULL;
575 for (int i=0; i<array->GetEntries(); i++) {
576 TObject* pObj=array->At(i);
577 if (pObj) delete pObj;
578 }
579 delete array;
90ebac25 580 return 0;
8451168b 581}
582
a655eae3 583AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
584{
585 // see header file for function documentation
90ebac25 586 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 587 AliHLTComponentDataType dt=kAliHLTVoidDataType;
588 int idx=fCurrentInputBlock;
589 if (pObject) {
590 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
591 } else {
592 HLTError("unknown object %p", pObject);
593 }
594 }
595 if (idx>=0) {
4b98eadb 596 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 597 dt=fpInputBlocks[idx].fDataType;
598 } else {
599 HLTFatal("severe internal error, index out of range");
600 }
601 }
602 return dt;
603}
604
605AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
606{
607 // see header file for function documentation
90ebac25 608 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 609 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
610 int idx=fCurrentInputBlock;
611 if (pObject) {
612 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
613 } else {
614 HLTError("unknown object %p", pObject);
615 }
616 }
617 if (idx>=0) {
4b98eadb 618 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 619 iSpec=fpInputBlocks[idx].fSpecification;
620 } else {
621 HLTFatal("severe internal error, index out of range");
622 }
623 }
624 return iSpec;
625}
626
627const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
628{
629 // see header file for function documentation
90ebac25 630 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 631 fSearchDataType=dt;
632 fClassName.clear();
633 int idx=FindInputBlock(fSearchDataType, 0);
634 const AliHLTComponentBlockData* pBlock=NULL;
635 if (idx>=0) {
636 // check for fpInputBlocks pointer done in FindInputBlock
637 pBlock=&fpInputBlocks[idx];
1edbbe49 638 fCurrentInputBlock=idx;
a655eae3 639 }
640 return pBlock;
641}
642
643const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
644 const char* dtOrigin)
645{
646 // see header file for function documentation
90ebac25 647 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 648 AliHLTComponentDataType dt;
649 SetDataType(dt, dtID, dtOrigin);
650 return GetFirstInputBlock(dt);
651}
652
653const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
654{
655 // see header file for function documentation
90ebac25 656 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 657 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
658 const AliHLTComponentBlockData* pBlock=NULL;
659 if (idx>=0) {
660 // check for fpInputBlocks pointer done in FindInputBlock
661 pBlock=&fpInputBlocks[idx];
1edbbe49 662 fCurrentInputBlock=idx;
a655eae3 663 }
664 return pBlock;
665}
666
66043029 667int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 668{
669 // see header file for function documentation
670 int iResult=-ENOENT;
671 if (fpInputBlocks!=NULL) {
672 if (pBlock) {
673 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 674 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 675 }
676 } else {
677 iResult=-EINVAL;
678 }
679 }
680 return iResult;
681}
682
683AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
684{
685 // see header file for function documentation
90ebac25 686 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 687 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
688 int idx=fCurrentInputBlock;
689 if (pBlock) {
690 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
691 } else {
692 HLTError("unknown Block %p", pBlock);
693 }
694 }
695 if (idx>=0) {
696 // check for fpInputBlocks pointer done in FindInputBlock
697 iSpec=fpInputBlocks[idx].fSpecification;
698 }
699 return iSpec;
700}
701
702int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
703{
704 // see header file for function documentation
90ebac25 705 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 706 int iResult=0;
707 if (pObject) {
708 AliHLTMessage msg(kMESS_OBJECT);
709 msg.WriteObject(pObject);
710 Int_t iMsgLength=msg.Length();
711 if (iMsgLength>0) {
712 msg.SetLength(); // sets the length to the first (reserved) word
713 iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec);
714 if (iResult>=0) {
8451168b 715 HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
a655eae3 716 }
717 } else {
718 HLTError("object serialization failed for object %p", pObject);
719 iResult=-ENOMSG;
720 }
721 } else {
722 iResult=-EINVAL;
723 }
724 return iResult;
725}
726
727int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
728{
729 // see header file for function documentation
90ebac25 730 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 731 AliHLTComponentDataType dt;
732 SetDataType(dt, dtID, dtOrigin);
733 return PushBack(pObject, dt, spec);
734}
735
736int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
737{
738 // see header file for function documentation
90ebac25 739 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 740 return InsertOutputBlock(pBuffer, iSize, dt, spec);
741}
742
743int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
744{
745 // see header file for function documentation
90ebac25 746 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 747 AliHLTComponentDataType dt;
748 SetDataType(dt, dtID, dtOrigin);
749 return PushBack(pBuffer, iSize, dt, spec);
750}
751
752int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
753{
754 // see header file for function documentation
755 int iResult=0;
756 if (pBuffer) {
7a5ccd96 757 if (fpOutputBuffer && iSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 758 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
759 AliHLTComponentBlockData bd;
760 FillBlockData( bd );
761 bd.fOffset = fOutputBufferFilled;
762 bd.fPtr = pTgt;
763 bd.fSize = iSize;
764 bd.fDataType = dt;
765 bd.fSpecification = spec;
766 if (pBuffer!=NULL && pBuffer!=pTgt) {
767 memcpy(pTgt, pBuffer, iSize);
4b98eadb 768 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
a655eae3 769 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iSize, pBuffer, pTgt, firstWord);
770 }
771 fOutputBufferFilled+=bd.fSize;
772 fOutputBlocks.push_back( bd );
773 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iSize, DataType2Text(dt).c_str(), spec);
774 } else {
775 if (fpOutputBuffer) {
776 HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iSize);
777 } else {
778 HLTError("output buffer not available");
779 }
780 iResult=-ENOSPC;
781 }
782 } else {
783 iResult=-EINVAL;
784 }
785 return iResult;
786}
787
8451168b 788int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
789{
66043029 790 // see header file for function documentation
8451168b 791 if (!pObject) return -EINVAL;
792 AliHLTMessage msg(kMESS_OBJECT);
793 msg.WriteObject(pObject);
794 return msg.Length();
795}
796
a655eae3 797int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
798{
799 // see header file for function documentation
800 int iResult=-ENOSYS;
801 //#warning function not yet implemented
802 HLTWarning("function not yet implemented");
803 return iResult;
804}
805
3cde846d 806int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
807 const AliHLTComponentBlockData* blocks,
808 AliHLTComponentTriggerData& trigData,
809 AliHLTUInt8_t* outputPtr,
810 AliHLTUInt32_t& size,
811 AliHLTUInt32_t& outputBlockCnt,
812 AliHLTComponentBlockData*& outputBlocks,
813 AliHLTComponentEventDoneData*& edd )
814{
70ed7d01 815 // see header file for function documentation
90ebac25 816 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 817 int iResult=0;
818 fCurrentEvent=evtData.fEventID;
a655eae3 819 fCurrentEventData=evtData;
820 fpInputBlocks=blocks;
821 fCurrentInputBlock=-1;
822 fSearchDataType=kAliHLTAnyDataType;
823 fpOutputBuffer=outputPtr;
824 fOutputBufferSize=size;
825 fOutputBufferFilled=0;
826 fOutputBlocks.clear();
827
828 vector<AliHLTComponentBlockData> blockData;
90ebac25 829 { // dont delete, sets the scope for the stopwatch guard
830 ALIHLTCOMPONENT_DA_STOPWATCH();
831 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
832 } // end of the scope of the stopwatch guard
a655eae3 833 if (iResult>=0) {
834 if (fOutputBlocks.size()>0) {
835 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
836 if (blockData.size()>0) {
837 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
838 iResult=-EFAULT;
839 } else {
840 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
841 size=fOutputBufferFilled;
842 }
843 } else {
844 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
845 }
846 if (iResult<0) {
847 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
848 }
849 }
850 if (iResult<0) {
851 outputBlockCnt=0;
852 outputBlocks=NULL;
853 }
8451168b 854 CleanupInputObjects();
3cde846d 855 IncrementEventCounter();
856 return iResult;
857}
a655eae3 858
90ebac25 859AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
860 :
861 fpStopwatch(NULL),
862 fpPrec(NULL)
863{
864 // standard constructor (not for use)
865}
866
867AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
868 :
869 fpStopwatch(pStopwatch),
870 fpPrec(NULL)
871{
872 // constructor
873
874 // check for already existing guard
875 if (fgpCurrent) fpPrec=fgpCurrent;
876 fgpCurrent=this;
877
878 // stop the preceeding guard if it controls a different stopwatch
879 int bStart=1;
880 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
881
882 // start the stopwatch if the current guard controls a different one
883 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
884}
885
886AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(AliHLTStopwatchGuard&)
887 :
888 fpStopwatch(NULL),
889 fpPrec(NULL)
890{
891 // copy constructor (not for use)
892}
893
894AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
895
896AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
897{
898 // destructor
899
900 // resume the preceeding guard if it controls a different stopwatch
901 int bStop=1;
902 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
903
904 // stop the stopwatch if the current guard controls a different one
905 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
906
907 // resume to the preceeding guard
908 fgpCurrent=fpPrec;
909}
910
911int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
912{
913 // see header file for function documentation
914 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
915 return fpStopwatch!=pSucc?1:0;
916}
917
918int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
919{
920 // see header file for function documentation
921 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
922 return fpStopwatch!=pSucc?1:0;
923}
924
925int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
926{
927 // see header file for function documentation
928 int iResult=0;
929 if (pSW!=NULL && type<kSWTypeCount) {
930 if (fpStopwatches) {
931 TObject* pObj=fpStopwatches->At((int)type);
932 if (pSW==NULL // explicit reset
933 || pObj==NULL) { // explicit set
934 fpStopwatches->AddAt(pSW, (int)type);
935 } else if (pObj!=pSW) {
936 HLTWarning("stopwatch %d already set, reset first", (int)type);
937 iResult=-EBUSY;
938 }
939 }
940 } else {
941 iResult=-EINVAL;
942 }
943 return iResult;
944}
945
946int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
947{
948 // see header file for function documentation
949 if (pStopwatches==NULL) return -EINVAL;
950
951 int iResult=0;
952 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
953 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
954 return iResult;
955}