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