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