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