]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTComponent.cxx
expanding compnent statistic structure to store cycle time
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
CommitLineData
f23a6e1a 1// $Id$
2
3dd8541e 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//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
f23a6e1a 19
bfccbf68 20/** @file AliHLTComponent.cxx
21 @author Matthias Richter, Timm Steinbeck
22 @date
23 @brief Base class implementation for HLT components. */
f23a6e1a 24
0c0c9d99 25#if __GNUC__>= 3
f23a6e1a 26using namespace std;
27#endif
28
66043029 29//#include "AliHLTStdIncludes.h"
f23a6e1a 30#include "AliHLTComponent.h"
31#include "AliHLTComponentHandler.h"
a655eae3 32#include "AliHLTMessage.h"
70ed7d01 33#include "TString.h"
ed504011 34#include "TMath.h"
a655eae3 35#include "TObjArray.h"
79c114b5 36#include "TObjectTable.h"
a655eae3 37#include "TClass.h"
90ebac25 38#include "TStopwatch.h"
79c114b5 39#include "AliHLTMemoryFile.h"
579d9eb7 40#include "AliHLTMisc.h"
ec25e4ca 41#include <cassert>
0da432fa 42#include <stdint.h>
f23a6e1a 43
9ace7282 44/**
45 * default compression level for ROOT objects
46 */
47#define ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION 5
2e3fd14f 48#define ALIHLTCOMPONENT_STATTIME_SCALER 1000000
9ace7282 49
b22e91eb 50/** ROOT macro for the implementation of ROOT specific class methods */
90ebac25 51ClassImp(AliHLTComponent);
52
53/** stopwatch macro using the stopwatch guard */
54#define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
55//#define ALIHLTCOMPONENT_STOPWATCH(type)
56
57/** stopwatch macro for operations of the base class */
58#define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
59/** stopwatch macro for operations of the detector algorithm (DA) */
60#define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
f23a6e1a 61
f23a6e1a 62AliHLTComponent::AliHLTComponent()
85869391 63 :
53feaef5 64 fEnvironment(),
3cde846d 65 fCurrentEvent(0),
a655eae3 66 fEventCount(-1),
67 fFailedEvents(0),
68 fCurrentEventData(),
69 fpInputBlocks(NULL),
70 fCurrentInputBlock(-1),
71 fSearchDataType(kAliHLTVoidDataType),
72 fClassName(),
73 fpInputObjects(NULL),
74 fpOutputBuffer(NULL),
75 fOutputBufferSize(0),
76 fOutputBufferFilled(0),
90ebac25 77 fOutputBlocks(),
79c114b5 78 fpStopwatches(new TObjArray(kSWTypeCount)),
559631d5 79 fMemFiles(),
80 fpRunDesc(NULL),
579d9eb7 81 fpDDLList(NULL),
82c58a87 82 fCDBSetRunNoFunc(false),
a0aeb701 83 fChainId(),
48abe484 84 fChainIdCrc(0),
a0aeb701 85 fpBenchmark(NULL),
48abe484 86 fRequireSteeringBlocks(false),
abb52c8f 87 fEventType(gkAliEventTypeUnknown),
eafbc306 88 fComponentArgs(),
89 fEventDoneData(NULL),
9ace7282 90 fEventDoneDataSize(0),
91 fCompressionLevel(ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION)
b3f4766b 92 , fLastObjectSize(0)
70ed7d01 93{
94 // see header file for class documentation
95 // or
96 // refer to README to build package
97 // or
98 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
a3c9b745 99 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
70ed7d01 100 if (fgpComponentHandler)
101 fgpComponentHandler->ScheduleRegister(this);
7c781d33 102 //SetLocalLoggingLevel(kHLTLogDefault);
70ed7d01 103}
104
f23a6e1a 105AliHLTComponent::~AliHLTComponent()
106{
70ed7d01 107 // see header file for function documentation
a0aeb701 108 if (fpBenchmark) delete fpBenchmark;
109 fpBenchmark=NULL;
110
8451168b 111 CleanupInputObjects();
4498d7d1 112 if (fpStopwatches!=NULL) delete fpStopwatches;
113 fpStopwatches=NULL;
2be3f004 114 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 115 while (element!=fMemFiles.end()) {
116 if (*element) {
117 if ((*element)->IsClosed()==0) {
118 HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
119 // close but do not flush as we dont know whether the buffer is still valid
29312178 120 (*element)->CloseMemoryFile(0);
79c114b5 121 }
122 delete *element;
123 *element=NULL;
124 }
125 element++;
126 }
45c0a780 127 if (fpRunDesc) {
128 delete fpRunDesc;
129 fpRunDesc=NULL;
130 }
eafbc306 131 if (fEventDoneData)
132 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
f23a6e1a 133}
134
70ed7d01 135AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
b22e91eb 136
85869391 137int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite)
138{
70ed7d01 139 // see header file for function documentation
85869391 140 int iResult=0;
70ed7d01 141 if (fgpComponentHandler==NULL || bOverwrite!=0)
142 fgpComponentHandler=pCH;
85869391 143 else
144 iResult=-EPERM;
145 return iResult;
146}
147
70ed7d01 148int AliHLTComponent::UnsetGlobalComponentHandler()
149{
150 // see header file for function documentation
85869391 151 return SetGlobalComponentHandler(NULL,1);
152}
153
a3c9b745 154int AliHLTComponent::Init(const AliHLTAnalysisEnvironment* comenv, void* environParam, int argc, const char** argv )
f23a6e1a 155{
70ed7d01 156 // see header file for function documentation
66108417 157 HLTLogKeyword(fChainId.c_str());
f23a6e1a 158 int iResult=0;
f7561f8d 159 if (comenv) {
a3c9b745 160 memset(&fEnvironment, 0, sizeof(AliHLTAnalysisEnvironment));
161 memcpy(&fEnvironment, comenv, comenv->fStructSize<sizeof(AliHLTAnalysisEnvironment)?comenv->fStructSize:sizeof(AliHLTAnalysisEnvironment));
162 fEnvironment.fStructSize=sizeof(AliHLTAnalysisEnvironment);
70ed7d01 163 fEnvironment.fParam=environParam;
f23a6e1a 164 }
abb52c8f 165 fComponentArgs="";
8451168b 166 const char** pArguments=NULL;
167 int iNofChildArgs=0;
168 TString argument="";
169 int bMissingParam=0;
170 if (argc>0) {
171 pArguments=new const char*[argc];
172 if (pArguments) {
173 for (int i=0; i<argc && iResult>=0; i++) {
abb52c8f 174 if (fComponentArgs.size()>0) fComponentArgs+=" ";
175 fComponentArgs+=argv[i];
8451168b 176 argument=argv[i];
177 if (argument.IsNull()) continue;
178
179 // benchmark
66108417 180 if (argument.CompareTo("-benchmark")==0) {
8451168b 181
66108417 182 // -loglevel=
183 } else if (argument.BeginsWith("-loglevel=")) {
184 TString parameter=argument.ReplaceAll("-loglevel=", "");
8451168b 185 parameter.Remove(TString::kLeading, ' '); // remove all blanks
186 if (parameter.BeginsWith("0x") &&
187 parameter.Replace(0,2,"",0).IsHex()) {
bd6cac58 188 unsigned int loglevel=kHLTLogNone;
189 sscanf(parameter.Data(),"%x", &loglevel);
190 SetLocalLoggingLevel((AliHLTComponentLogSeverity)loglevel);
8451168b 191 } else {
192 HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
193 iResult=-EINVAL;
194 }
9ace7282 195 // -object-compression=
196 } else if (argument.BeginsWith("-object-compression=")) {
197 argument.ReplaceAll("-object-compression=", "");
198 if (argument.IsDigit()) {
199 fCompressionLevel=argument.Atoi();
200 if (fCompressionLevel<0 || fCompressionLevel>9) {
201 HLTWarning("invalid compression level %d, setting to default %d", fCompressionLevel, ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION);
202 fCompressionLevel=ALIHLTCOMPONENT_DEFAULT_OBJECT_COMPRESSION;
203 }
204 } else {
205 HLTError("wrong parameter for argument -object-compression, number expected");
206 }
8451168b 207 } else {
208 pArguments[iNofChildArgs++]=argv[i];
209 }
210 }
211 } else {
212 iResult=-ENOMEM;
213 }
214 }
215 if (bMissingParam) {
216 HLTError("missing parameter for argument %s", argument.Data());
217 iResult=-EINVAL;
218 }
219 if (iResult>=0) {
220 iResult=DoInit(iNofChildArgs, pArguments);
221 }
a0aeb701 222 if (iResult>=0) {
223 fEventCount=0;
224
225 // find out if the component wants to get the steering events
226 // explicitly
227 AliHLTComponentDataTypeList inputDt;
228 GetInputDataTypes(inputDt);
229 for (AliHLTComponentDataTypeList::iterator dt=inputDt.begin();
230 dt!=inputDt.end() && !fRequireSteeringBlocks;
231 dt++) {
232 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeSOR);
233 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeRunType);
234 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeEOR);
235 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeDDL);
236 fRequireSteeringBlocks|=MatchExactly(*dt,kAliHLTDataTypeComponentStatistics);
237 }
238 }
8451168b 239 if (pArguments) delete [] pArguments;
a0aeb701 240
241#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
242 // benchmarking stopwatch for the component statistics
243 fpBenchmark=new TStopwatch;
a0aeb701 244#endif
245
f23a6e1a 246 return iResult;
247}
248
249int AliHLTComponent::Deinit()
250{
70ed7d01 251 // see header file for function documentation
66108417 252 HLTLogKeyword(fChainId.c_str());
f23a6e1a 253 int iResult=0;
254 iResult=DoDeinit();
559631d5 255 if (fpRunDesc) {
256 HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
257 AliHLTRunDesc* pRunDesc=fpRunDesc;
258 fpRunDesc=NULL;
259 delete pRunDesc;
260 }
579d9eb7 261 fEventCount=0;
f23a6e1a 262 return iResult;
263}
fa2e9b7c 264
82c58a87 265int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
53feaef5 266{
82c58a87 267 // see header file for function documentation
579d9eb7 268 int iResult=0;
703bcca6 269 if (pHandler) {
82c58a87 270 // I have to think about separating the library handling from the
271 // component handler. Requiring the component hanlder here is not
272 // the cleanest solution.
273 // We presume the library already to be loaded
579d9eb7 274 // find the symbol
82c58a87 275 AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
579d9eb7 276 if (pFunc) {
703bcca6 277 TString path;
278 if (cdbPath && cdbPath[0]!=0) {
279 path=cdbPath;
280 // very temporary fix, have to check for other formats
281 if (!path.BeginsWith("local://")) {
282 path="local://";
283 path+=cdbPath;
284 }
8f30c1ea 285 }
286 if ((iResult=(*pFunc)(path.Data()))>=0) {
82c58a87 287 if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
288 Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
289 "can not find function to set CDB run no");
290 }
291 }
579d9eb7 292 } else {
293 Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
294 "can not find initialization function");
295 iResult=-ENOSYS;
53feaef5 296 }
82c58a87 297 } else {
298 iResult=-EINVAL;
299 }
579d9eb7 300 return iResult;
301}
302
303int AliHLTComponent::SetCDBRunNo(int runNo)
304{
82c58a87 305 // see header file for function documentation
306 if (!fCDBSetRunNoFunc) return 0;
307 return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
579d9eb7 308}
309
45c0a780 310int AliHLTComponent::SetRunDescription(const AliHLTRunDesc* desc, const char* /*runType*/)
311{
312 // see header file for function documentation
313 if (!desc) return -EINVAL;
314 if (desc->fStructSize!=sizeof(AliHLTRunDesc)) {
315 HLTError("invalid size of RunDesc struct (%ul)", desc->fStructSize);
316 return -EINVAL;
317 }
318
319 if (!fpRunDesc) {
320 fpRunDesc=new AliHLTRunDesc;
321 if (!fpRunDesc) return -ENOMEM;
322 *fpRunDesc=kAliHLTVoidRunDesc;
323 }
324
325 if (fpRunDesc->fRunNo!=kAliHLTVoidRunNo && fpRunDesc->fRunNo!=desc->fRunNo) {
326 HLTWarning("Run description has already been set");
327 }
328 *fpRunDesc=*desc;
329 SetCDBRunNo(fpRunDesc->fRunNo);
330 // TODO: we have to decide about the runType
331 return 0;
332}
333
9a0ef890 334int AliHLTComponent::SetComponentDescription(const char* desc)
335{
48abe484 336 // see header file for function documentation
9a0ef890 337 int iResult=0;
338 if (!desc) return 0;
339
340 TString descriptor=desc;
341 TObjArray* pTokens=descriptor.Tokenize(" ");
342 if (pTokens) {
343 for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
344 TString argument=((TObjString*)pTokens->At(i++))->GetString();
345 if (!argument || argument.IsNull()) continue;
346
a3c9b745 347 // chainid
348 if (argument.BeginsWith("chainid")) {
349 argument.ReplaceAll("chainid", "");
9a0ef890 350 if (argument.BeginsWith("=")) {
351 fChainId=argument.Replace(0,1,"");
48abe484 352 fChainIdCrc=CalculateChecksum((const AliHLTUInt8_t*)fChainId.c_str(), fChainId.length());
353 HLTDebug("setting component description: chain id %s crc 0x%8x", fChainId.c_str(), fChainIdCrc);
9a0ef890 354 } else {
355 fChainId="";
356 }
357 } else {
48abe484 358 HLTWarning("unknown component description %s", argument.Data());
9a0ef890 359 }
360 }
361 }
362
363 return iResult;
364}
365
579d9eb7 366int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
367{
368 // default implementation, childs can overload
b543e186 369 HLTLogKeyword("dummy");
53feaef5 370 return 0;
371}
372
373int AliHLTComponent::DoDeinit()
374{
579d9eb7 375 // default implementation, childs can overload
b543e186 376 HLTLogKeyword("dummy");
579d9eb7 377 return 0;
378}
379
380int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
381{
382 // default implementation, childs can overload
b543e186 383 HLTLogKeyword("dummy");
384 return 0;
385}
386
387int AliHLTComponent::ReadPreprocessorValues(const char* /*modules*/)
388{
389 // default implementation, childs can overload
390 HLTLogKeyword("dummy");
53feaef5 391 return 0;
392}
393
45c0a780 394int AliHLTComponent::StartOfRun()
395{
396 // default implementation, childs can overload
397 HLTLogKeyword("dummy");
398 return 0;
399}
400
401int AliHLTComponent::EndOfRun()
402{
403 // default implementation, childs can overload
404 HLTLogKeyword("dummy");
405 return 0;
406}
407
408
2be3f004 409int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
de6593d0 410{
82c58a87 411 // default implementation, childs can overload
3a7c0444 412 HLTLogKeyword("dummy");
de6593d0 413 return 0;
414}
415
70ed7d01 416void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
417{
418 // see header file for function documentation
9ce4bf4a 419 memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
420 strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
421 strcat( output, ":" );
422 strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
fa2e9b7c 423}
424
fbdb63fd 425string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
9ce4bf4a 426{
70ed7d01 427 // see header file for function documentation
9ce4bf4a 428 string out("");
fbdb63fd 429
430 if (mode==2) {
431 int i=0;
432 char tmp[8];
433 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
434 sprintf(tmp, "'%d", type.fOrigin[i]);
435 out+=tmp;
436 }
437 out+="':'";
438 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
439 sprintf(tmp, "%d'", type.fID[i]);
440 out+=tmp;
441 }
442 return out;
443 }
444
445 if (mode==1) {
446 int i=0;
447 char tmp[8];
448 for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
449 unsigned char* puc=(unsigned char*)type.fOrigin;
450 if ((puc[i])<32)
451 sprintf(tmp, "'\\%x", type.fOrigin[i]);
452 else
453 sprintf(tmp, "'%c", type.fOrigin[i]);
454 out+=tmp;
455 }
456 out+="':'";
457 for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
458 unsigned char* puc=(unsigned char*)type.fID;
459 if (puc[i]<32)
460 sprintf(tmp, "\\%x'", type.fID[i]);
461 else
462 sprintf(tmp, "%c'", type.fID[i]);
463 out+=tmp;
464 }
465 return out;
466 }
467
9ce4bf4a 468 if (type==kAliHLTVoidDataType) {
469 out="VOID:VOID";
470 } else {
3cde846d 471 // some gymnastics in order to avoid a '0' which is part of either or both
472 // ID and origin terminating the whole string. Unfortunately, string doesn't
473 // stop appending at the '0' if the number of elements to append was
474 // explicitely specified
475 string tmp("");
476 tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
477 out.append(tmp.c_str());
9ce4bf4a 478 out.append(":");
3cde846d 479 tmp="";
480 tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
481 out.append(tmp.c_str());
9ce4bf4a 482 }
483 return out;
484}
485
486
70ed7d01 487void* AliHLTComponent::AllocMemory( unsigned long size )
488{
489 // see header file for function documentation
85869391 490 if (fEnvironment.fAllocMemoryFunc)
491 return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
9ce4bf4a 492 HLTFatal("no memory allocation handler registered");
85869391 493 return NULL;
494}
495
2be3f004 496int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
70ed7d01 497 AliHLTComponentBlockData** outputBlocks )
498{
499 // see header file for function documentation
9ce4bf4a 500 if ( blockCount==NULL || outputBlocks==NULL )
2d7ff710 501 return -EFAULT;
fa2e9b7c 502 AliHLTUInt32_t count = blocks.size();
503 if ( !count )
504 {
505 *blockCount = 0;
506 *outputBlocks = NULL;
507 return 0;
508 }
8ede8717 509 *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
fa2e9b7c 510 if ( !*outputBlocks )
2d7ff710 511 return -ENOMEM;
ca8524df 512 for ( unsigned long i = 0; i < count; i++ ) {
fa2e9b7c 513 (*outputBlocks)[i] = blocks[i];
732e8f50 514 if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
5f5b708b 515 (*outputBlocks)[i].fDataType=GetOutputDataType();
516 /* data type was set to the output data type by the PubSub AliRoot
517 Wrapper component, if data type of the block was ********:****.
518 Now handled by the component base class in order to have same
519 behavior when running embedded in AliRoot
ca8524df 520 memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
521 memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
5f5b708b 522 */
ca8524df 523 }
524 }
fa2e9b7c 525 *blockCount = count;
526 return 0;
527
528}
0c0c9d99 529
70ed7d01 530int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd )
531{
532 // see header file for function documentation
85869391 533 if (fEnvironment.fGetEventDoneDataFunc)
534 return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
535 return -ENOSYS;
536}
537
eafbc306 538int AliHLTComponent::ReserveEventDoneData( unsigned long size )
539{
540 // see header file for function documentation
541 int iResult=0;
542
543
544 if (size>fEventDoneDataSize) {
545 AliHLTComponentEventDoneData* newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+size ] );
546 if (!newEDD)
547 return -ENOMEM;
548 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
549 newEDD->fDataSize = 0;
550 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
551 if (fEventDoneData) {
552 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
553 newEDD->fDataSize = fEventDoneData->fDataSize;
554 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
555 }
556 fEventDoneData = newEDD;
557 fEventDoneDataSize = size;
558 }
559 return iResult;
560
561}
562
563int AliHLTComponent::PushEventDoneData( AliHLTUInt32_t eddDataWord )
564{
565 if (!fEventDoneData)
566 return -ENOMEM;
567 if (fEventDoneData->fDataSize+sizeof(AliHLTUInt32_t)>fEventDoneDataSize)
568 return -ENOSPC;
569 *reinterpret_cast<AliHLTUInt32_t*>((reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize)) = eddDataWord;
570 fEventDoneData->fDataSize += sizeof(AliHLTUInt32_t);
571 return 0;
572}
573
574void AliHLTComponent::ReleaseEventDoneData()
575{
576 if (fEventDoneData)
577 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
578 fEventDoneData = NULL;
579 fEventDoneDataSize = 0;
580}
581
582
2be3f004 583int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList)
0c0c9d99 584{
70ed7d01 585 // see header file for function documentation
0c0c9d99 586 int iResult=0;
587 if (pConsumer) {
8a106878 588 AliHLTComponentDataTypeList itypes;
589 AliHLTComponentDataTypeList otypes;
590 otypes.push_back(GetOutputDataType());
591 if (otypes[0]==kAliHLTMultipleDataType) {
592 otypes.clear();
593 int count=0;
594 if ((count=GetOutputDataTypes(otypes))>0) {
595 } else if (GetComponentType()!=kSink) {
596 HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
597 }
598 }
599 ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
48abe484 600 AliHLTComponentDataTypeList::iterator otype=otypes.begin();
601 for (;otype!=otypes.end();otype++) {
602 //PrintDataTypeContent((*otype), "publisher \'%s\'");
603 if ((*otype)==(kAliHLTAnyDataType|kAliHLTDataOriginPrivate)) {
604 if (tgtList) tgtList->push_back(*otype);
605 iResult++;
606 continue;
607 }
608
609 AliHLTComponentDataTypeList::iterator itype=itypes.begin();
32f88fc5 610 for ( ; itype!=itypes.end() && (*itype)!=(*otype) ; itype++) {/* empty body */};
48abe484 611 //if (itype!=itypes.end()) PrintDataTypeContent(*itype, "consumer \'%s\'");
612 if (itype!=itypes.end()) {
613 if (tgtList) tgtList->push_back(*otype);
0c0c9d99 614 iResult++;
0c0c9d99 615 }
0c0c9d99 616 }
617 } else {
618 iResult=-EINVAL;
619 }
620 return iResult;
621}
2d7ff710 622
8b97f4f1 623void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format)
5f5b708b 624{
66043029 625 // see header file for function documentation
8b97f4f1 626 const char* fmt="\'%s\'";
5f5b708b 627 if (format) fmt=format;
8b97f4f1 628 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, Form(fmt, (DataType2Text(dt)).c_str()));
629 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL,
630 Form("%x %x %x %x %x %x %x %x : %x %x %x %x",
631 dt.fID[0],
632 dt.fID[1],
633 dt.fID[2],
634 dt.fID[3],
635 dt.fID[4],
636 dt.fID[5],
637 dt.fID[6],
638 dt.fID[7],
639 dt.fOrigin[0],
640 dt.fOrigin[1],
641 dt.fOrigin[2],
642 dt.fOrigin[3]));
5f5b708b 643}
644
fbdb63fd 645void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
70ed7d01 646{
647 // see header file for function documentation
2d7ff710 648 blockData.fStructSize = sizeof(blockData);
649 FillShmData( blockData.fShmKey );
650 blockData.fOffset = ~(AliHLTUInt32_t)0;
651 blockData.fPtr = NULL;
652 blockData.fSize = 0;
653 FillDataType( blockData.fDataType );
a655eae3 654 blockData.fSpecification = kAliHLTVoidDataSpec;
2d7ff710 655}
656
fbdb63fd 657void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
70ed7d01 658{
659 // see header file for function documentation
2d7ff710 660 shmData.fStructSize = sizeof(shmData);
661 shmData.fShmType = gkAliHLTComponentInvalidShmType;
662 shmData.fShmID = gkAliHLTComponentInvalidShmID;
663}
664
fbdb63fd 665void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
70ed7d01 666{
667 // see header file for function documentation
ca8524df 668 dataType=kAliHLTAnyDataType;
2d7ff710 669}
670
70ed7d01 671void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt)
672{
673 // see header file for function documentation
2d7ff710 674 memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
675 memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
676}
677
70ed7d01 678void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin)
679{
680 // see header file for function documentation
7e3efc8f 681 tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
682 if (id) {
683 memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
d76bc02a 684 strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
7e3efc8f 685 }
686 if (origin) {
687 memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
d76bc02a 688 strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
7e3efc8f 689 }
2d7ff710 690}
9ce4bf4a 691
18b56222 692void AliHLTComponent::SetDataType(AliHLTComponentDataType& dt, AliHLTUInt64_t id, AliHLTUInt32_t origin)
693{
694 // see header file for function documentation
695 dt.fStructSize=sizeof(AliHLTComponentDataType);
696 assert(kAliHLTComponentDataTypefIDsize==sizeof(id));
697 assert(kAliHLTComponentDataTypefOriginSize==sizeof(origin));
698 memcpy(&dt.fID, &id, kAliHLTComponentDataTypefIDsize);
699 memcpy(&dt.fOrigin, &origin, kAliHLTComponentDataTypefOriginSize);
700}
701
9ce4bf4a 702void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
703{
70ed7d01 704 // see header file for function documentation
9ce4bf4a 705 memset(&evtData, 0, sizeof(AliHLTComponentEventData));
706 evtData.fStructSize=sizeof(AliHLTComponentEventData);
48abe484 707 evtData.fEventID=kAliHLTVoidEventID;
9ce4bf4a 708}
709
70ed7d01 710void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt)
711{
712 // see header file for function documentation
9ce4bf4a 713 TString msg;
714 msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
715 for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
716 if (dt.fID[i]!=0) msg+=dt.fID[i];
717 else msg+="\\0";
718 }
719 msg+="\" Origin=\"";
720 for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
721 if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
722 else msg+="\\0";
723 }
724 msg+="\"";
3cde846d 725 AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
9ce4bf4a 726}
727
70ed7d01 728int AliHLTComponent::GetEventCount() const
3cde846d 729{
70ed7d01 730 // see header file for function documentation
3cde846d 731 return fEventCount;
732}
733
734int AliHLTComponent::IncrementEventCounter()
735{
70ed7d01 736 // see header file for function documentation
3cde846d 737 if (fEventCount>=0) fEventCount++;
738 return fEventCount;
739}
740
66043029 741int AliHLTComponent::GetNumberOfInputBlocks() const
a655eae3 742{
743 // see header file for function documentation
744 if (fpInputBlocks!=NULL) {
745 return fCurrentEventData.fBlockCnt;
746 }
747 return 0;
748}
749
4646c6e3 750AliHLTEventID_t AliHLTComponent::GetEventId() const
751{
752 // see header file for function documentation
753 if (fpInputBlocks!=NULL) {
754 return fCurrentEventData.fEventID;
755 }
756 return 0;
757}
758
a655eae3 759const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
760 const char* classname,
761 int bForce)
762{
763 // see header file for function documentation
90ebac25 764 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 765 fSearchDataType=dt;
766 if (classname) fClassName=classname;
767 else fClassName.clear();
1edbbe49 768 int idx=FindInputBlock(fSearchDataType, 0, 1);
a655eae3 769 TObject* pObj=NULL;
770 if (idx>=0) {
79c114b5 771 HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
a655eae3 772 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
773 fCurrentInputBlock=idx;
774 } else {
775 }
776 }
777 return pObj;
778}
779
780const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID,
781 const char* dtOrigin,
782 const char* classname,
783 int bForce)
784{
785 // see header file for function documentation
90ebac25 786 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 787 AliHLTComponentDataType dt;
788 SetDataType(dt, dtID, dtOrigin);
789 return GetFirstInputObject(dt, classname, bForce);
790}
791
792const TObject* AliHLTComponent::GetNextInputObject(int bForce)
793{
794 // see header file for function documentation
90ebac25 795 ALIHLTCOMPONENT_BASE_STOPWATCH();
1edbbe49 796 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
a655eae3 797 //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
798 TObject* pObj=NULL;
799 if (idx>=0) {
800 if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
801 fCurrentInputBlock=idx;
802 }
803 }
804 return pObj;
805}
806
1edbbe49 807int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
a655eae3 808{
809 // see header file for function documentation
810 int iResult=-ENOENT;
811 if (fpInputBlocks!=NULL) {
812 int idx=startIdx<0?0:startIdx;
4b98eadb 813 for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
3dd8541e 814 if (dt!=fpInputBlocks[idx].fDataType) continue;
815
1edbbe49 816 if (bObject!=0) {
817 if (fpInputBlocks[idx].fPtr==NULL) continue;
3294f81a 818 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
819 if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
1edbbe49 820 }
3dd8541e 821 iResult=idx;
a655eae3 822 }
823 }
824 return iResult;
825}
826
827TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
828{
829 // see header file for function documentation
830 TObject* pObj=NULL;
831 if (fpInputBlocks!=NULL) {
4b98eadb 832 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 833 if (fpInputBlocks[idx].fPtr) {
3294f81a 834 AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
a655eae3 835 if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
8451168b 836 HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
3294f81a 837 AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
66043029 838 TClass* objclass=msg.GetClass();
839 pObj=msg.ReadObject(objclass);
840 if (pObj && objclass) {
841 HLTDebug("object %p type %s created", pObj, objclass->GetName());
a655eae3 842 } else {
843 }
1edbbe49 844 //} else {
845 } else if (bForce!=0) {
c5123824 846 HLTError("size mismatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
a655eae3 847 }
848 } else {
849 HLTFatal("block descriptor empty");
850 }
851 } else {
852 HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
853 }
854 } else {
855 HLTError("no input blocks available");
856 }
857
858 return pObj;
859}
860
298ef463 861TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
a655eae3 862{
863 // see header file for function documentation
864 if (fpInputObjects==NULL) {
865 fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
866 }
867 TObject* pObj=NULL;
868 if (fpInputObjects) {
869 pObj=fpInputObjects->At(idx);
870 if (pObj==NULL) {
871 pObj=CreateInputObject(idx, bForce);
872 if (pObj) {
873 fpInputObjects->AddAt(pObj, idx);
874 }
875 }
876 } else {
877 HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
878 }
879 return pObj;
880}
881
8451168b 882int AliHLTComponent::CleanupInputObjects()
883{
66043029 884 // see header file for function documentation
8451168b 885 if (!fpInputObjects) return 0;
886 TObjArray* array=fpInputObjects;
887 fpInputObjects=NULL;
888 for (int i=0; i<array->GetEntries(); i++) {
889 TObject* pObj=array->At(i);
79c114b5 890 // grrr, garbage collection strikes back: When read via AliHLTMessage
891 // (CreateInputObject), and written to a TFile afterwards, the
892 // TFile::Close calls ROOOT's garbage collection. No clue why the
893 // object ended up in the key list and needs to be deleted
a6c7a8bc 894 //
895 // Matthias 09.11.2008 follow up
896 // This approach doesn't actually work in all cases: the object table
897 // can be switched off globally, the flag needs to be checked here as
898 // well in order to avoid memory leaks.
899 // This means we have to find another solution for the problem if it
900 // pops up again.
901 if (pObj &&
902 (!TObject::GetObjectStat() || gObjectTable->PtrIsValid(pObj))) {
903 delete pObj;
904 }
8451168b 905 }
906 delete array;
90ebac25 907 return 0;
8451168b 908}
909
a655eae3 910AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
911{
912 // see header file for function documentation
90ebac25 913 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 914 AliHLTComponentDataType dt=kAliHLTVoidDataType;
915 int idx=fCurrentInputBlock;
916 if (pObject) {
917 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
918 } else {
919 HLTError("unknown object %p", pObject);
920 }
921 }
922 if (idx>=0) {
4b98eadb 923 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 924 dt=fpInputBlocks[idx].fDataType;
925 } else {
926 HLTFatal("severe internal error, index out of range");
927 }
928 }
929 return dt;
930}
931
932AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
933{
934 // see header file for function documentation
90ebac25 935 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 936 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
937 int idx=fCurrentInputBlock;
938 if (pObject) {
939 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
940 } else {
941 HLTError("unknown object %p", pObject);
942 }
943 }
944 if (idx>=0) {
4b98eadb 945 if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
a655eae3 946 iSpec=fpInputBlocks[idx].fSpecification;
947 } else {
948 HLTFatal("severe internal error, index out of range");
949 }
950 }
951 return iSpec;
952}
953
c7e9e2f2 954int AliHLTComponent::Forward(const TObject* pObject)
955{
956 // see header file for function documentation
957 int iResult=0;
958 int idx=fCurrentInputBlock;
959 if (pObject) {
960 if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
961 } else {
962 HLTError("unknown object %p", pObject);
963 iResult=-ENOENT;
964 }
965 }
966 if (idx>=0) {
967 fOutputBlocks.push_back(fpInputBlocks[idx]);
968 }
969 return iResult;
970}
971
972int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
973{
974 // see header file for function documentation
975 int iResult=0;
976 int idx=fCurrentInputBlock;
977 if (pBlock) {
978 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
979 } else {
980 HLTError("unknown Block %p", pBlock);
981 iResult=-ENOENT;
982 }
983 }
984 if (idx>=0) {
985 // check for fpInputBlocks pointer done in FindInputBlock
986 fOutputBlocks.push_back(fpInputBlocks[idx]);
987 }
988 return iResult;
989}
990
a655eae3 991const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
992{
993 // see header file for function documentation
90ebac25 994 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 995 fSearchDataType=dt;
996 fClassName.clear();
997 int idx=FindInputBlock(fSearchDataType, 0);
998 const AliHLTComponentBlockData* pBlock=NULL;
999 if (idx>=0) {
1000 // check for fpInputBlocks pointer done in FindInputBlock
1001 pBlock=&fpInputBlocks[idx];
1edbbe49 1002 fCurrentInputBlock=idx;
a655eae3 1003 }
1004 return pBlock;
1005}
1006
1007const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID,
1008 const char* dtOrigin)
1009{
1010 // see header file for function documentation
90ebac25 1011 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1012 AliHLTComponentDataType dt;
1013 SetDataType(dt, dtID, dtOrigin);
1014 return GetFirstInputBlock(dt);
1015}
1016
10b9cbf9 1017const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index) const
ec25e4ca 1018{
1019 // see header file for function documentation
1020 ALIHLTCOMPONENT_BASE_STOPWATCH();
13398559 1021 assert( 0 <= index and index < (int)fCurrentEventData.fBlockCnt );
ec25e4ca 1022 return &fpInputBlocks[index];
1023}
1024
a655eae3 1025const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
1026{
1027 // see header file for function documentation
90ebac25 1028 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1029 int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
1030 const AliHLTComponentBlockData* pBlock=NULL;
1031 if (idx>=0) {
1032 // check for fpInputBlocks pointer done in FindInputBlock
1033 pBlock=&fpInputBlocks[idx];
1edbbe49 1034 fCurrentInputBlock=idx;
a655eae3 1035 }
1036 return pBlock;
1037}
1038
66043029 1039int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
a655eae3 1040{
1041 // see header file for function documentation
1042 int iResult=-ENOENT;
1043 if (fpInputBlocks!=NULL) {
1044 if (pBlock) {
1045 if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
132ca004 1046 iResult=(int)(pBlock-fpInputBlocks);
a655eae3 1047 }
1048 } else {
1049 iResult=-EINVAL;
1050 }
1051 }
1052 return iResult;
1053}
1054
1055AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
1056{
1057 // see header file for function documentation
90ebac25 1058 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1059 AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
1060 int idx=fCurrentInputBlock;
1061 if (pBlock) {
1062 if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
1063 } else {
1064 HLTError("unknown Block %p", pBlock);
1065 }
1066 }
1067 if (idx>=0) {
1068 // check for fpInputBlocks pointer done in FindInputBlock
1069 iSpec=fpInputBlocks[idx].fSpecification;
1070 }
1071 return iSpec;
1072}
1073
79c114b5 1074int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1075 void* pHeader, int headerSize)
a655eae3 1076{
1077 // see header file for function documentation
90ebac25 1078 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1079 int iResult=0;
b3f4766b 1080 fLastObjectSize=0;
a655eae3 1081 if (pObject) {
1082 AliHLTMessage msg(kMESS_OBJECT);
9ace7282 1083 msg.SetCompressionLevel(fCompressionLevel);
a655eae3 1084 msg.WriteObject(pObject);
1085 Int_t iMsgLength=msg.Length();
1086 if (iMsgLength>0) {
9ace7282 1087 // Matthias Sep 2008
1088 // NOTE: AliHLTMessage does implement it's own SetLength method
1089 // which is not architecture independent. The original SetLength
1090 // stores the size always in network byte order.
1091 // I'm trying to remember the rational for that, might be that
1092 // it was just some lack of knowledge. Want to change this, but
1093 // has to be done carefullt to be backward compatible.
a655eae3 1094 msg.SetLength(); // sets the length to the first (reserved) word
9ace7282 1095
1096 // does nothing if the level is 0
1097 msg.Compress();
1098
1099 char *mbuf = msg.Buffer();
1100 if (msg.CompBuffer()) {
1101 msg.SetLength(); // set once more to have to byte order
1102 mbuf = msg.CompBuffer();
1103 iMsgLength = msg.CompLength();
1104 }
1105 assert(mbuf!=NULL);
1106 iResult=InsertOutputBlock(mbuf, iMsgLength, dt, spec, pHeader, headerSize);
a655eae3 1107 if (iResult>=0) {
9ace7282 1108 HLTDebug("object %s (%p) size %d compression %d inserted to output", pObject->ClassName(), pObject, iMsgLength, msg.GetCompressionLevel());
a655eae3 1109 }
b3f4766b 1110 fLastObjectSize=iMsgLength;
a655eae3 1111 } else {
1112 HLTError("object serialization failed for object %p", pObject);
1113 iResult=-ENOMSG;
1114 }
1115 } else {
1116 iResult=-EINVAL;
1117 }
1118 return iResult;
1119}
1120
79c114b5 1121int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1122 void* pHeader, int headerSize)
a655eae3 1123{
1124 // see header file for function documentation
90ebac25 1125 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1126 AliHLTComponentDataType dt;
1127 SetDataType(dt, dtID, dtOrigin);
79c114b5 1128 return PushBack(pObject, dt, spec, pHeader, headerSize);
a655eae3 1129}
1130
438635e3 1131int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1132 const void* pHeader, int headerSize)
a655eae3 1133{
1134 // see header file for function documentation
90ebac25 1135 ALIHLTCOMPONENT_BASE_STOPWATCH();
9d9ffd37 1136 return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1137}
1138
438635e3 1139int AliHLTComponent::PushBack(const void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
1140 const void* pHeader, int headerSize)
a655eae3 1141{
1142 // see header file for function documentation
90ebac25 1143 ALIHLTCOMPONENT_BASE_STOPWATCH();
a655eae3 1144 AliHLTComponentDataType dt;
1145 SetDataType(dt, dtID, dtOrigin);
9d9ffd37 1146 return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
a655eae3 1147}
1148
438635e3 1149int AliHLTComponent::InsertOutputBlock(const void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
1150 const void* pHeader, int iHeaderSize)
a655eae3 1151{
1152 // see header file for function documentation
1153 int iResult=0;
79c114b5 1154 int iBlkSize = iBufferSize + iHeaderSize;
438635e3 1155
1156 if ((pBuffer!=NULL && iBufferSize>0) || (pHeader!=NULL && iHeaderSize>0)) {
79c114b5 1157 if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
a655eae3 1158 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
438635e3 1159
1160 // copy header if provided but skip if the header is the target location
1161 // in that case it has already been copied
79c114b5 1162 if (pHeader!=NULL && pHeader!=pTgt) {
1163 memcpy(pTgt, pHeader, iHeaderSize);
1164 }
1165
1166 pTgt += (AliHLTUInt8_t) iHeaderSize;
1167
438635e3 1168 // copy buffer if provided but skip if buffer is the target location
1169 // in that case it has already been copied
a655eae3 1170 if (pBuffer!=NULL && pBuffer!=pTgt) {
79c114b5 1171 memcpy(pTgt, pBuffer, iBufferSize);
1172
4b98eadb 1173 //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
79c114b5 1174 //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
a655eae3 1175 }
79c114b5 1176 //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
a655eae3 1177 } else {
1178 if (fpOutputBuffer) {
b3f4766b 1179 HLTError("too little space in output buffer: %d of %d, required %d", fOutputBufferSize-fOutputBufferFilled, fOutputBufferSize, iBlkSize);
a655eae3 1180 } else {
1181 HLTError("output buffer not available");
1182 }
1183 iResult=-ENOSPC;
1184 }
a655eae3 1185 }
438635e3 1186 if (iResult>=0) {
1187 AliHLTComponentBlockData bd;
1188 FillBlockData( bd );
1189 bd.fOffset = fOutputBufferFilled;
1190 bd.fSize = iBlkSize;
1191 bd.fDataType = dt;
1192 bd.fSpecification = spec;
1193 fOutputBlocks.push_back( bd );
1194 fOutputBufferFilled+=bd.fSize;
1195 }
1196
a655eae3 1197 return iResult;
1198}
1199
8451168b 1200int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
1201{
66043029 1202 // see header file for function documentation
8451168b 1203 if (!pObject) return -EINVAL;
1204 AliHLTMessage msg(kMESS_OBJECT);
1205 msg.WriteObject(pObject);
1206 return msg.Length();
1207}
1208
79c114b5 1209AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
1210 const char* dtOrigin,
1211 AliHLTUInt32_t spec)
1212{
1213 // see header file for function documentation
1214 ALIHLTCOMPONENT_BASE_STOPWATCH();
1215 AliHLTComponentDataType dt;
1216 SetDataType(dt, dtID, dtOrigin);
1217 return CreateMemoryFile(capacity, dt, spec);
1218}
1219
1220AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
1221 const AliHLTComponentDataType& dt,
1222 AliHLTUInt32_t spec)
1223{
1224 // see header file for function documentation
1225 ALIHLTCOMPONENT_BASE_STOPWATCH();
1226 AliHLTMemoryFile* pFile=NULL;
83fec083 1227 if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
79c114b5 1228 AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
1229 pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
1230 if (pFile) {
83fec083 1231 unsigned int nofBlocks=fOutputBlocks.size();
79c114b5 1232 if (nofBlocks+1>fMemFiles.size()) {
1233 fMemFiles.resize(nofBlocks+1, NULL);
1234 }
1235 if (nofBlocks<fMemFiles.size()) {
1236 fMemFiles[nofBlocks]=pFile;
1237 AliHLTComponentBlockData bd;
1238 FillBlockData( bd );
1239 bd.fOffset = fOutputBufferFilled;
79c114b5 1240 bd.fSize = capacity;
1241 bd.fDataType = dt;
1242 bd.fSpecification = spec;
1243 fOutputBufferFilled+=bd.fSize;
1244 fOutputBlocks.push_back( bd );
1245 } else {
1246 HLTError("can not allocate/grow object array");
29312178 1247 pFile->CloseMemoryFile(0);
79c114b5 1248 delete pFile;
1249 pFile=NULL;
1250 }
1251 }
1252 } else {
1253 HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
1254 }
1255 return pFile;
1256}
1257
1258AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1259 const char* dtOrigin,
1260 AliHLTUInt32_t spec,
1261 float capacity)
1262{
1263 // see header file for function documentation
1264 ALIHLTCOMPONENT_BASE_STOPWATCH();
1265 AliHLTComponentDataType dt;
1266 SetDataType(dt, dtID, dtOrigin);
1267 int size=fOutputBufferSize-fOutputBufferFilled;
1268 if (capacity<0 || capacity>1.0) {
1269 HLTError("invalid parameter: capacity %f", capacity);
1270 return NULL;
1271 }
1272 size=(int)(size*capacity);
1273 return CreateMemoryFile(size, dt, spec);
1274}
1275
1276AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1277 AliHLTUInt32_t spec,
1278 float capacity)
1279{
1280 // see header file for function documentation
1281 ALIHLTCOMPONENT_BASE_STOPWATCH();
1282 int size=fOutputBufferSize-fOutputBufferFilled;
1283 if (capacity<0 || capacity>1.0) {
1284 HLTError("invalid parameter: capacity %f", capacity);
1285 return NULL;
1286 }
1287 size=(int)(size*capacity);
1288 return CreateMemoryFile(size, dt, spec);
1289}
1290
1291int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1292 const char* key, int option)
1293{
3a7c0444 1294 // see header file for function documentation
79c114b5 1295 int iResult=0;
1296 if (pFile && pObject) {
1297 pFile->cd();
1298 iResult=pObject->Write(key, option);
1299 if (iResult>0) {
1300 // success
1301 } else {
1302 iResult=-pFile->GetErrno();
1303 if (iResult==-ENOSPC) {
1304 HLTError("error writing memory file, buffer too small");
1305 }
1306 }
1307 } else {
1308 iResult=-EINVAL;
1309 }
1310 return iResult;
1311}
1312
1313int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1314{
3a7c0444 1315 // see header file for function documentation
79c114b5 1316 int iResult=0;
1317 if (pFile) {
2be3f004 1318 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1319 int i=0;
1320 while (element!=fMemFiles.end() && iResult>=0) {
1321 if (*element && *element==pFile) {
29312178 1322 iResult=pFile->CloseMemoryFile();
79c114b5 1323
1324 // sync memory files and descriptors
1325 if (iResult>=0) {
1326 fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1327 }
1328 delete *element;
1329 *element=NULL;
1330 return iResult;
1331 }
1332 element++; i++;
1333 }
1334 HLTError("can not find memory file %p", pFile);
1335 iResult=-ENOENT;
1336 } else {
1337 iResult=-EINVAL;
1338 }
1339 return iResult;
1340}
1341
eafbc306 1342int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
a655eae3 1343{
1344 // see header file for function documentation
eafbc306 1345 int iResult=0;
1346
1347 AliHLTComponentEventDoneData* newEDD = NULL;
1348
1349 unsigned long newSize=edd.fDataSize;
1350 if (fEventDoneData)
1351 newSize += fEventDoneData->fDataSize;
1352
1353 if (newSize>fEventDoneDataSize) {
1354 newEDD = reinterpret_cast<AliHLTComponentEventDoneData*>( new AliHLTUInt8_t[ sizeof(AliHLTComponentEventDoneData)+newSize ] );
1355 if (!newEDD)
1356 return -ENOMEM;
1357 newEDD->fStructSize = sizeof(AliHLTComponentEventDoneData);
1358 newEDD->fDataSize = newSize;
1359 newEDD->fData = reinterpret_cast<AliHLTUInt8_t*>(newEDD)+newEDD->fStructSize;
1360 unsigned long long offset = 0;
1361 if (fEventDoneData) {
1362 memcpy( newEDD->fData, fEventDoneData->fData, fEventDoneData->fDataSize );
1363 offset += fEventDoneData->fDataSize;
1364 }
1365 memcpy( reinterpret_cast<AliHLTUInt8_t*>(newEDD->fData)+offset, edd.fData, edd.fDataSize );
1366 if (fEventDoneData)
1367 delete [] reinterpret_cast<AliHLTUInt8_t*>( fEventDoneData );
1368 fEventDoneData = newEDD;
1369 fEventDoneDataSize = newSize;
1370 }
1371 else {
1372 memcpy( reinterpret_cast<AliHLTUInt8_t*>(fEventDoneData->fData)+fEventDoneData->fDataSize, edd.fData, edd.fDataSize );
1373 fEventDoneData->fDataSize += edd.fDataSize;
1374 }
a655eae3 1375 return iResult;
1376}
1377
3cde846d 1378int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1379 const AliHLTComponentBlockData* blocks,
1380 AliHLTComponentTriggerData& trigData,
1381 AliHLTUInt8_t* outputPtr,
1382 AliHLTUInt32_t& size,
1383 AliHLTUInt32_t& outputBlockCnt,
1384 AliHLTComponentBlockData*& outputBlocks,
1385 AliHLTComponentEventDoneData*& edd )
1386{
70ed7d01 1387 // see header file for function documentation
66108417 1388 HLTLogKeyword(fChainId.c_str());
90ebac25 1389 ALIHLTCOMPONENT_BASE_STOPWATCH();
3cde846d 1390 int iResult=0;
1391 fCurrentEvent=evtData.fEventID;
a655eae3 1392 fCurrentEventData=evtData;
1393 fpInputBlocks=blocks;
1394 fCurrentInputBlock=-1;
1395 fSearchDataType=kAliHLTAnyDataType;
1396 fpOutputBuffer=outputPtr;
1397 fOutputBufferSize=size;
1398 fOutputBufferFilled=0;
1399 fOutputBlocks.clear();
96f9673a 1400 outputBlockCnt=0;
1401 outputBlocks=NULL;
438635e3 1402
1403 AliHLTComponentBlockDataList forwardedBlocks;
1404
1405 // optional component statistics
a0aeb701 1406 AliHLTComponentStatisticsList compStats;
438635e3 1407 bool bAddComponentTableEntry=false;
abb52c8f 1408 vector<AliHLTUInt32_t> parentComponentTables;
a0aeb701 1409#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
1410 AliHLTComponentStatistics outputStat;
1411 memset(&outputStat, 0, sizeof(AliHLTComponentStatistics));
2e3fd14f 1412 outputStat.fStructSize=sizeof(AliHLTComponentStatistics);
48abe484 1413 outputStat.fId=fChainIdCrc;
a0aeb701 1414 if (fpBenchmark) {
2e3fd14f 1415 fpBenchmark->Stop();
1416 outputStat.fComponentCycleTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
a0aeb701 1417 fpBenchmark->Reset();
1418 fpBenchmark->Start();
1419 }
2e3fd14f 1420 compStats.push_back(outputStat);
a0aeb701 1421#endif
559631d5 1422
48abe484 1423 // data processing is skipped
1424 // - if there are only steering events in the block list.
1425 // For the sake of data source components data processing
1426 // is not skipped if there is no block list at all or if it
1427 // just contains the eventType block
1428 // - always skipped if the event is of type
1429 // - gkAliEventTypeConfiguration
1430 // - gkAliEventTypeReadPreprocessor
45c0a780 1431 const unsigned int skipModeDefault=0x1;
1432 const unsigned int skipModeForce=0x2;
1433 unsigned int bSkipDataProcessing=skipModeDefault;
1434
559631d5 1435 // find special events
45c0a780 1436 if (fpInputBlocks && evtData.fBlockCnt>0) {
579d9eb7 1437 // first look for all special events and execute in the appropriate
1438 // sequence afterwords
1439 int indexComConfEvent=-1;
b543e186 1440 int indexUpdtDCSEvent=-1;
579d9eb7 1441 int indexSOREvent=-1;
1442 int indexEOREvent=-1;
83fec083 1443 for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
559631d5 1444 if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
579d9eb7 1445 indexSOREvent=i;
45c0a780 1446 // the AliHLTCalibrationProcessor relies on the SOR and EOR events
1447 bSkipDataProcessing&=~skipModeDefault;
1448 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeRunType) {
1449 // run type string
1450 // handling is not clear yet
1451 if (fpInputBlocks[i].fPtr) {
1452 HLTDebug("got run type \"%s\"\n", fpInputBlocks[i].fPtr);
1453 }
579d9eb7 1454 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1455 indexEOREvent=i;
45c0a780 1456 // the calibration processor relies on the SOR and EOR events
1457 bSkipDataProcessing&=~skipModeDefault;
579d9eb7 1458 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1459 // DDL list
1460 // this event is most likely deprecated
1461 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1462 indexComConfEvent=i;
b543e186 1463 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeUpdtDCS) {
1464 indexUpdtDCSEvent=i;
1465 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEvent) {
48abe484 1466 fEventType=fpInputBlocks[i].fSpecification;
1467
1468 // skip always in case of gkAliEventTypeConfiguration
45c0a780 1469 if (fpInputBlocks[i].fSpecification==gkAliEventTypeConfiguration) bSkipDataProcessing|=skipModeForce;
48abe484 1470
1471 // skip always in case of gkAliEventTypeReadPreprocessor
45c0a780 1472 if (fpInputBlocks[i].fSpecification==gkAliEventTypeReadPreprocessor) bSkipDataProcessing|=skipModeForce;
48abe484 1473
1474 // never skip if the event type block is the only block
1475 if (evtData.fBlockCnt==1) bSkipDataProcessing&=~skipModeDefault;
1476
a0aeb701 1477 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentStatistics) {
1478 if (compStats.size()>0) {
1479 AliHLTUInt8_t* pData=reinterpret_cast<AliHLTUInt8_t*>(fpInputBlocks[i].fPtr);
1480 for (AliHLTUInt32_t offset=0;
1481 offset+sizeof(AliHLTComponentStatistics)<=fpInputBlocks[i].fSize;
1482 offset+=sizeof(AliHLTComponentStatistics)) {
1483 AliHLTComponentStatistics* pStat=reinterpret_cast<AliHLTComponentStatistics*>(pData+offset);
1484 if (pStat && compStats[0].fLevel<=pStat->fLevel) {
1485 compStats[0].fLevel=pStat->fLevel+1;
1486 }
1487 compStats.push_back(*pStat);
1488 }
1489 }
438635e3 1490 } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComponentTable) {
1491 forwardedBlocks.push_back(fpInputBlocks[i]);
abb52c8f 1492 parentComponentTables.push_back(fpInputBlocks[i].fSpecification);
45c0a780 1493 } else {
1494 // the processing function is called if there is at least one
1495 // non-steering data block. Steering blocks are not filtered out
1496 // for sake of performance
1497 bSkipDataProcessing&=~skipModeDefault;
a0aeb701 1498 if (compStats.size()>0) {
1499 compStats[0].fInputBlockCount++;
1500 compStats[0].fTotalInputSize+=fpInputBlocks[i].fSize;
1501 }
579d9eb7 1502 }
1503 }
45c0a780 1504
579d9eb7 1505 if (indexSOREvent>=0) {
1506 // start of run
438635e3 1507 bAddComponentTableEntry=true;
579d9eb7 1508 if (fpRunDesc==NULL) {
1509 fpRunDesc=new AliHLTRunDesc;
48abe484 1510 if (fpRunDesc) *fpRunDesc=kAliHLTVoidRunDesc;
45c0a780 1511 }
1512 if (fpRunDesc) {
1513 AliHLTRunDesc rundesc;
1514 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1515 if (fpRunDesc->fRunNo==kAliHLTVoidRunNo) {
1516 *fpRunDesc=rundesc;
579d9eb7 1517 HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1518 SetCDBRunNo(fpRunDesc->fRunNo);
45c0a780 1519 } else if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1520 HLTWarning("already set run properties run no %d, ignoring SOR with run no %d", fpRunDesc->fRunNo, rundesc.fRunNo);
559631d5 1521 }
559631d5 1522 }
579d9eb7 1523 } else {
45c0a780 1524 iResult=-ENOMEM;
579d9eb7 1525 }
1526 }
1527 if (indexEOREvent>=0) {
438635e3 1528 bAddComponentTableEntry=true;
579d9eb7 1529 if (fpRunDesc!=NULL) {
1530 if (fpRunDesc) {
1531 AliHLTRunDesc rundesc;
1532 if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1533 if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
c5123824 1534 HLTWarning("run no mismatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
579d9eb7 1535 } else {
1536 HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
559631d5 1537 }
559631d5 1538 }
579d9eb7 1539 AliHLTRunDesc* pRunDesc=fpRunDesc;
1540 fpRunDesc=NULL;
1541 delete pRunDesc;
559631d5 1542 }
579d9eb7 1543 } else {
1544 HLTWarning("did not receive SOR, ignoring EOR");
1545 }
1546 }
48abe484 1547 if (indexComConfEvent>=0 || fEventType==gkAliEventTypeConfiguration) {
579d9eb7 1548 TString cdbEntry;
b543e186 1549 if (indexComConfEvent>=0 && fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
579d9eb7 1550 cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1551 }
1552 HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1553 int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1554 if (tmpResult<0) {
1555 HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
559631d5 1556 }
1557 }
48abe484 1558 if (indexUpdtDCSEvent>=0 || fEventType==gkAliEventTypeReadPreprocessor) {
b543e186 1559 TString modules;
1560 if (fpInputBlocks[indexUpdtDCSEvent].fPtr!=NULL && fpInputBlocks[indexUpdtDCSEvent].fSize>0) {
1561 modules.Append(reinterpret_cast<const char*>(fpInputBlocks[indexUpdtDCSEvent].fPtr), fpInputBlocks[indexUpdtDCSEvent].fSize);
1562 }
d6b69874 1563 HLTDebug("received preprocessor update command: detectors %s", modules.IsNull()?"ALL":modules.Data());
1564 int tmpResult=ReadPreprocessorValues(modules[0]==0?"ALL":modules.Data());
b543e186 1565 if (tmpResult<0) {
1566 HLTWarning("preprocessor update of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1567 }
1568 }
45c0a780 1569 } else {
1570 // processing function needs to be called if there are no input data
1571 // blocks in order to make data source components working.
1572 bSkipDataProcessing&=~skipModeDefault;
559631d5 1573 }
a0aeb701 1574
1575 // data processing is not skipped if the component explicitly asks
1576 // for the private blocks
1577 if (fRequireSteeringBlocks) bSkipDataProcessing=0;
1578
2be3f004 1579 AliHLTComponentBlockDataList blockData;
45c0a780 1580 if (iResult>=0 && !bSkipDataProcessing)
90ebac25 1581 { // dont delete, sets the scope for the stopwatch guard
f7561f8d 1582 // do not use ALIHLTCOMPONENT_DA_STOPWATCH(); macro
1583 // in order to avoid 'shadowed variable' warning
1584 AliHLTStopwatchGuard swguard2(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)kSWDA)):NULL);
90ebac25 1585 iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1586 } // end of the scope of the stopwatch guard
b543e186 1587 if (iResult>=0 && !bSkipDataProcessing) {
a655eae3 1588 if (fOutputBlocks.size()>0) {
df61f928 1589 // High Level interface
1590
1591 //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
79c114b5 1592 // sync memory files and descriptors
2be3f004 1593 AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
79c114b5 1594 int i=0;
1595 while (element!=fMemFiles.end() && iResult>=0) {
1596 if (*element) {
1597 if ((*element)->IsClosed()==0) {
1598 HLTWarning("memory file has not been closed, force flush");
1599 iResult=CloseMemoryFile(*element);
1600 }
1601 }
1602 element++; i++;
1603 }
1604
1605 if (iResult>=0) {
1606 // create the descriptor list
1607 if (blockData.size()>0) {
1608 HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1609 iResult=-EFAULT;
1610 } else {
abb52c8f 1611 if (compStats.size()>0 && IsDataEvent()) {
a0aeb701 1612 int offset=AddComponentStatistics(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, compStats);
1613 if (offset>0) fOutputBufferFilled+=offset;
1614 }
438635e3 1615 if (bAddComponentTableEntry) {
abb52c8f 1616 int offset=AddComponentTableEntry(fOutputBlocks, fpOutputBuffer, fOutputBufferSize, fOutputBufferFilled, parentComponentTables);
438635e3 1617 if (offset>0) size+=offset;
1618 }
1619 if (forwardedBlocks.size()>0) {
1620 fOutputBlocks.insert(fOutputBlocks.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1621 }
79c114b5 1622 iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1623 size=fOutputBufferFilled;
1624 }
a655eae3 1625 }
1626 } else {
df61f928 1627 // Low Level interface
a0aeb701 1628 if (compStats.size()>0) {
1629 int offset=AddComponentStatistics(blockData, fpOutputBuffer, fOutputBufferSize, size, compStats);
1630 if (offset>0) size+=offset;
1631 }
438635e3 1632 if (bAddComponentTableEntry) {
abb52c8f 1633 int offset=AddComponentTableEntry(blockData, fpOutputBuffer, fOutputBufferSize, size, parentComponentTables);
438635e3 1634 if (offset>0) size+=offset;
1635 }
1636 if (forwardedBlocks.size()>0) {
1637 blockData.insert(blockData.end(), forwardedBlocks.begin(), forwardedBlocks.end());
1638 }
a655eae3 1639 iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1640 }
1641 if (iResult<0) {
1642 HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1643 }
1644 }
b543e186 1645 if (iResult<0 || bSkipDataProcessing) {
a655eae3 1646 outputBlockCnt=0;
1647 outputBlocks=NULL;
1648 }
8451168b 1649 CleanupInputObjects();
48abe484 1650 if (iResult>=0 && IsDataEvent()) {
f8bc6d99 1651 IncrementEventCounter();
1652 }
96f9673a 1653 if (outputBlockCnt==0) {
1654 // no output blocks, set size to 0
1655 size=0;
1656 }
4646c6e3 1657 FillEventData(fCurrentEventData);
3cde846d 1658 return iResult;
1659}
a655eae3 1660
a0aeb701 1661int AliHLTComponent::AddComponentStatistics(AliHLTComponentBlockDataList& blocks,
1662 AliHLTUInt8_t* buffer,
1663 AliHLTUInt32_t bufferSize,
1664 AliHLTUInt32_t offset,
1665 AliHLTComponentStatisticsList& stats) const
1666{
1667 // see header file for function documentation
1668 int iResult=0;
438635e3 1669#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
a0aeb701 1670 if (stats.size()==0) return -ENOENT;
1671 stats[0].fTotalOutputSize=offset;
1672 stats[0].fOutputBlockCount=blocks.size();
1673 if (fpBenchmark) {
2e3fd14f 1674 fpBenchmark->Stop();
1675 stats[0].fTime=(AliHLTUInt32_t)(fpBenchmark->RealTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1676 stats[0].fCTime=(AliHLTUInt32_t)(fpBenchmark->CpuTime()*ALIHLTCOMPONENT_STATTIME_SCALER);
1677 fpBenchmark->Continue();
a0aeb701 1678 }
1679 if (offset+stats.size()*sizeof(AliHLTComponentStatistics)<=bufferSize) {
1680 AliHLTComponentBlockData bd;
1681 FillBlockData( bd );
1682 bd.fOffset = offset;
1683 bd.fSize = stats.size()*sizeof(AliHLTComponentStatistics);
1684 bd.fDataType = kAliHLTDataTypeComponentStatistics;
1685 bd.fSpecification = kAliHLTVoidDataSpec;
1686 unsigned int master=0;
1687 for (unsigned int i=1; i<blocks.size(); i++) {
1688 if (blocks[i].fSize>blocks[master].fSize &&
1689 !MatchExactly(blocks[i].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate))
1690 master=i;
1691 }
1692 if (blocks.size()>0 && !MatchExactly(blocks[master].fDataType, kAliHLTVoidDataType|kAliHLTDataOriginPrivate)) {
1693 // take the data origin of the biggest block as specification
1694 // this is similar to the treatment in the HOMER interface. For traditional
1695 // reasons, the bytes are swapped there on a little endian architecture, so
1696 // we do it as well.
1697 memcpy(&bd.fSpecification, &blocks[master].fDataType.fOrigin, sizeof(bd.fSpecification));
1698#ifdef R__BYTESWAP // set on little endian architectures
1699 bd.fSpecification=((bd.fSpecification & 0xFFULL) << 24) |
1700 ((bd.fSpecification & 0xFF00ULL) << 8) |
1701 ((bd.fSpecification & 0xFF0000ULL) >> 8) |
1702 ((bd.fSpecification & 0xFF000000ULL) >> 24);
1703#endif
1704 }
1705 memcpy(buffer+offset, &(stats[0]), bd.fSize);
1706 blocks.push_back(bd);
1707 iResult=bd.fSize;
1708 }
bd6cac58 1709#else
1710 if (blocks.size() && buffer && bufferSize && offset && stats.size()) {
1711 // get rid of warning
1712 }
438635e3 1713#endif
1714 return iResult;
1715}
1716
1717int AliHLTComponent::AddComponentTableEntry(AliHLTComponentBlockDataList& blocks,
1718 AliHLTUInt8_t* buffer,
1719 AliHLTUInt32_t bufferSize,
abb52c8f 1720 AliHLTUInt32_t offset,
1721 const vector<AliHLTUInt32_t>& parents) const
438635e3 1722{
1723 // see header file for function documentation
1724 int iResult=0;
1725#if defined(__DEBUG) || defined(HLT_COMPONENT_STATISTICS)
abb52c8f 1726 // the payload consists of the AliHLTComponentTableEntry struct,
1727 // followed by a an array of 32bit crc chain ids and the component
1728 // description string
1729 unsigned int payloadSize=sizeof(AliHLTComponentTableEntry);
1730 payloadSize+=parents.size()*sizeof(AliHLTUInt32_t);
1731
1732 // the component description has the following format:
1733 // chain-id{component-id:arguments}
1734 const char* componentId=const_cast<AliHLTComponent*>(this)->GetComponentID();
1735 unsigned int descriptionSize=fChainId.size()+1;
1736 descriptionSize+=2; // the '{}' around the component id
1737 descriptionSize+=strlen(componentId);
1738 descriptionSize+=1; // the ':' between component id and arguments
1739 descriptionSize+=fComponentArgs.size();
1740
1741 payloadSize+=descriptionSize;
1742 if (buffer && (offset+payloadSize<=bufferSize)) {
1743 AliHLTUInt8_t* pTgt=buffer+offset;
1744 memset(pTgt, 0, payloadSize);
1745
1746 // write entry
1747 AliHLTComponentTableEntry* pEntry=reinterpret_cast<AliHLTComponentTableEntry*>(pTgt);
1748 pEntry->fStructSize=sizeof(AliHLTComponentTableEntry);
1749 pEntry->fNofParents=parents.size();
1750 pEntry->fSizeDescription=descriptionSize;
1751 pTgt=pEntry->fBuffer;
1752
1753 // write array of parents
1754 if (parents.size()>0) {
1755 unsigned int copy=parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type);
1756 memcpy(pTgt, &parents[0], parents.size()*sizeof(vector<AliHLTUInt32_t>::value_type));
1757 pTgt+=copy;
1758 }
1759
1760 // write component description
1761 memcpy(pTgt, fChainId.c_str(), fChainId.size());
1762 pTgt+=fChainId.size();
1763 *pTgt++='{';
1764 memcpy(pTgt, componentId, strlen(componentId));
1765 pTgt+=strlen(componentId);
1766 *pTgt++=':';
1767 memcpy(pTgt, fComponentArgs.c_str(), fComponentArgs.size());
1768 pTgt+=fComponentArgs.size();
1769 *pTgt++='}';
1770 *pTgt++=0;
1771
438635e3 1772 AliHLTComponentBlockData bd;
1773 FillBlockData( bd );
1774 bd.fOffset = offset;
abb52c8f 1775 bd.fSize = payloadSize;
438635e3 1776 bd.fDataType = kAliHLTDataTypeComponentTable;
1777 bd.fSpecification = fChainIdCrc;
438635e3 1778 blocks.push_back(bd);
1779 iResult=bd.fSize;
1780 }
bd6cac58 1781#else
1782 if (blocks.size() && buffer && bufferSize && offset && parents.size()) {
1783 // get rid of warning
1784 }
438635e3 1785 #endif
a0aeb701 1786 return iResult;
1787}
1788
90ebac25 1789AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1790 :
1791 fpStopwatch(NULL),
1792 fpPrec(NULL)
1793{
1794 // standard constructor (not for use)
1795}
1796
1797AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1798 :
1799 fpStopwatch(pStopwatch),
1800 fpPrec(NULL)
1801{
1802 // constructor
1803
1804 // check for already existing guard
1805 if (fgpCurrent) fpPrec=fgpCurrent;
1806 fgpCurrent=this;
1807
1808 // stop the preceeding guard if it controls a different stopwatch
1809 int bStart=1;
1810 if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1811
1812 // start the stopwatch if the current guard controls a different one
1813 if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1814}
1815
e419b223 1816AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
90ebac25 1817 :
1818 fpStopwatch(NULL),
1819 fpPrec(NULL)
1820{
e419b223 1821 //
1822 // copy constructor not for use
1823 //
1824}
1825
1826AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1827{
1828 //
1829 // assignment operator not for use
1830 //
1831 fpStopwatch=NULL;
1832 fpPrec=NULL;
1833 return *this;
90ebac25 1834}
1835
1836AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1837
1838AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1839{
1840 // destructor
1841
1842 // resume the preceeding guard if it controls a different stopwatch
1843 int bStop=1;
1844 if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1845
1846 // stop the stopwatch if the current guard controls a different one
1847 if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1848
1849 // resume to the preceeding guard
1850 fgpCurrent=fpPrec;
1851}
1852
1853int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1854{
1855 // see header file for function documentation
1856 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1857 return fpStopwatch!=pSucc?1:0;
1858}
1859
1860int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1861{
1862 // see header file for function documentation
1863 if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1864 return fpStopwatch!=pSucc?1:0;
1865}
1866
1867int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type)
1868{
1869 // see header file for function documentation
1870 int iResult=0;
1871 if (pSW!=NULL && type<kSWTypeCount) {
1872 if (fpStopwatches) {
1873 TObject* pObj=fpStopwatches->At((int)type);
1874 if (pSW==NULL // explicit reset
1875 || pObj==NULL) { // explicit set
1876 fpStopwatches->AddAt(pSW, (int)type);
1877 } else if (pObj!=pSW) {
1878 HLTWarning("stopwatch %d already set, reset first", (int)type);
1879 iResult=-EBUSY;
1880 }
1881 }
1882 } else {
1883 iResult=-EINVAL;
1884 }
1885 return iResult;
1886}
1887
1888int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1889{
1890 // see header file for function documentation
1891 if (pStopwatches==NULL) return -EINVAL;
1892
1893 int iResult=0;
1894 for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1895 SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1896 return iResult;
1897}
559631d5 1898
1899AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1900{
29312178 1901 // see header file for function documentation
45c0a780 1902 if (fpRunDesc==NULL) return kAliHLTVoidRunNo;
559631d5 1903 return fpRunDesc->fRunNo;
1904}
1905
1906AliHLTUInt32_t AliHLTComponent::GetRunType() const
1907{
29312178 1908 // see header file for function documentation
45c0a780 1909 if (fpRunDesc==NULL) return kAliHLTVoidRunType;
559631d5 1910 return fpRunDesc->fRunType;
1911}
1912
48abe484 1913bool AliHLTComponent::IsDataEvent(AliHLTUInt32_t* pTgt)
1914{
1915 // see header file for function documentation
1916 if (pTgt) *pTgt=fEventType;
1917 return (fEventType==gkAliEventTypeData ||
1918 fEventType==gkAliEventTypeDataReplay ||
1919 fEventType==gkAliEventTypeCalibration);
1920}
1921
83fec083 1922int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
559631d5 1923 const char* structname, const char* eventname)
1924{
29312178 1925 // see header file for function documentation
559631d5 1926 int iResult=0;
1927 if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1928 if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1929 AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1930 if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
3294f81a 1931 AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
559631d5 1932 if (fpInputBlocks[iBlockNo].fSize!=copy) {
c5123824 1933 HLTWarning("%s event: mismatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
559631d5 1934 if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1935 }
1936 if (copy!=iStructSize) {
c5123824 1937 HLTWarning("%s event: mismatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
559631d5 1938 if (copy>iStructSize) {
1939 copy=iStructSize;
1940 } else {
1941 memset(pTgt, 0, iStructSize);
1942 }
1943 }
3294f81a 1944 memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
559631d5 1945 *pTgt=iStructSize;
1946 iResult=copy;
1947 } else {
1948 HLTWarning("%s event: missing data block", eventname);
1949 }
1950 } else {
1951 iResult=-ENODATA;
1952 }
1953 } else {
1954 HLTError("invalid struct");
1955 iResult=-EINVAL;
1956 }
1957 return iResult;
1958}
ed504011 1959
1960void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1961{
1962 // see header file for function documentation
1963
1964 // -- Detector offset
1965 Int_t ddlIdBase = TMath::FloorNint( (Double_t) ddlId / 256.0 );
1966
1967 // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 )
1968 Int_t wordBase = 0;
1969
1970 if ( ddlIdBase <= 3 )
1971 wordBase = ddlIdBase;
1972 else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1973 wordBase = ddlIdBase + 7;
1974 else
1975 wordBase = ddlIdBase + 9;
1976
1977 // -- Bit index in Word
1978 Int_t bitIdx = ddlId % 32;
1979
1980 // -- Index of word
1981 Int_t wordIdx = wordBase;
1982
1983 // -- if TPC (3) or TOD (5) add word idx
1984 if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1985 wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1986 }
1987
1988 // -- Set -- 'OR' word with bit mask;
1989 if ( state )
1990 list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1991 // -- Unset -- 'AND' word with bit mask;
1992 else
1993 list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1994}
1995
1996Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1997{
1998 // see header file for function documentation
1999
2000 Int_t iResult = -1;
2001
2002 for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
2003
2004 if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
2005 // check for special cases TPC and TOF
2006 if ( wordNdx > 3 && wordNdx <= 10 ) {
2007 wordNdx = 10;
2008 iResult = 3;
2009 }
2010 else if ( wordNdx > 12 && wordNdx <= 14 ) {
2011 wordNdx = 14;
2012 iResult = 12;
2013 }
2014 else
2015 iResult = wordNdx;
2016 }
2017 else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
2018 HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
2019 iResult = -1;
2020 break;
2021 }
2022 }
2023
2024 return iResult;
2025}
48abe484 2026
2027AliHLTUInt32_t AliHLTComponent::CalculateChecksum(const AliHLTUInt8_t* buffer, int size)
2028{
2029 // see header file for function documentation
2030 AliHLTUInt32_t remainder = 0;
2031 const AliHLTUInt8_t crcwidth=(8*sizeof(AliHLTUInt32_t));
2032 const AliHLTUInt32_t topbit=1 << (crcwidth-1);
2033 const AliHLTUInt32_t polynomial=0xD8; /* 11011 followed by 0's */
2034
2035 // code from
2036 // http://www.netrino.com/Embedded-Systems/How-To/CRC-Calculation-C-Code
2037
2038 /*
2039 * Perform modulo-2 division, a byte at a time.
2040 */
2041 for (int byte = 0; byte < size; ++byte)
2042 {
2043 /*
2044 * Bring the next byte into the remainder.
2045 */
2046 remainder ^= (buffer[byte] << (crcwidth - 8));
2047
2048 /*
2049 * Perform modulo-2 division, a bit at a time.
2050 */
2051 for (uint8_t bit = 8; bit > 0; --bit)
2052 {
2053 /*
2054 * Try to divide the current data bit.
2055 */
2056 if (remainder & topbit)
2057 {
2058 remainder = (remainder << 1) ^ polynomial;
2059 }
2060 else
2061 {
2062 remainder = (remainder << 1);
2063 }
2064 }
2065 }
2066
2067 /*
2068 * The final remainder is the CRC result.
2069 */
2070 return (remainder);
2071}
abb52c8f 2072
2073int AliHLTComponent::ExtractComponentTableEntry(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
2074 string& retChainId, string& retCompId, string& retCompArgs,
2075 vector<AliHLTUInt32_t>& parents)
2076{
2077 // see header file for function documentation
2078 retChainId.clear();
2079 retCompId.clear();
2080 retCompArgs.clear();
2081 parents.clear();
2082 if (!pBuffer || size==0) return 0;
2083
2084 const AliHLTComponentTableEntry* pEntry=reinterpret_cast<const AliHLTComponentTableEntry*>(pBuffer);
2085 if (size<8/* the initial size of the structure*/ ||
2086 pEntry==NULL || pEntry->fStructSize<8) return -ENOMSG;
2087 const AliHLTUInt32_t* pParents=reinterpret_cast<const AliHLTUInt32_t*>(pEntry->fBuffer);
2088 const AliHLTUInt8_t* pEnd=pBuffer+size;
2089
2090 if (pParents+pEntry->fNofParents>=reinterpret_cast<const AliHLTUInt32_t*>(pEnd)) return -ENODEV;
2091 for (unsigned int i=0; i<pEntry->fNofParents; i++, pParents++) {
2092 parents.push_back(*pParents);
2093 }
2094
2095 const char* pDescription=reinterpret_cast<const char*>(pParents);
2096 if (pDescription+pEntry->fSizeDescription>=reinterpret_cast<const char*>(pEnd) ||
2097 *(pDescription+pEntry->fSizeDescription)!=0) {
2098 return -EBADF;
2099 }
2100
2101 TString descriptor=reinterpret_cast<const char*>(pDescription);
2102 TString chainId;
2103 TString compId;
2104 TString compArgs;
2105 TObjArray* pTokens=descriptor.Tokenize("{");
2106 if (pTokens) {
2107 int n=0;
2108 if (pTokens->GetEntries()>n) {
2109 retChainId=((TObjString*)pTokens->At(n++))->GetString();
2110 }
2111 if (pTokens->GetEntries()>n) {
2112 compId=((TObjString*)pTokens->At(n++))->GetString();
2113 }
2114 delete pTokens;
2115 }
2116 if (!compId.IsNull() && (pTokens=compId.Tokenize(":"))!=NULL) {
2117 int n=0;
2118 if (pTokens->GetEntries()>n) {
2119 compId=((TObjString*)pTokens->At(n++))->GetString();
2120 }
2121 if (pTokens->GetEntries()>n) {
2122 compArgs=((TObjString*)pTokens->At(n++))->GetString();
2123 }
2124 delete pTokens;
2125 }
2126 compId.ReplaceAll("}", "");
2127 compArgs.ReplaceAll("}", "");
2128
2129 retCompId=compId;
2130 retCompArgs=compArgs;
2131
2132 if (retChainId.size()==0) return -ENODATA;
2133
2134 return 1;
2135}
97d2b87a 2136
2137int AliHLTComponent::LoggingVarargs(AliHLTComponentLogSeverity severity,
2138 const char* originClass, const char* originFunc,
2139 const char* file, int line, ... ) const
2140{
2141 // see header file for function documentation
2142 int iResult=0;
2143
2144 va_list args;
2145 va_start(args, line);
2146
2147 // logging function needs to be const in order to be called from const member functions
2148 // without problems. But at this point we face the problem with virtual members which
2149 // are not necessarily const.
2150 AliHLTComponent* nonconst=const_cast<AliHLTComponent*>(this);
2151 AliHLTLogging::SetLogString("%s (%s, %p): ",
2152 fChainId[0]!=0?fChainId.c_str():nonconst->GetComponentID(),
2153 nonconst->GetComponentID(), this);
2154 iResult=SendMessage(severity, originClass, originFunc, file, line, AliHLTLogging::BuildLogString(NULL, args, true /*append*/));
2155 va_end(args);
2156
2157 return iResult;
2158}