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