more bugfixes on data type operator semantics: earlier workarounds have been cleaned now
[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 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #if __GNUC__>= 3
32 using namespace std;
33 #endif
34
35 //#include "AliHLTStdIncludes.h"
36 #include "AliHLTComponent.h"
37 #include "AliHLTComponentHandler.h"
38 #include "AliHLTMessage.h"
39 #include "TString.h"
40 #include "TMath.h"
41 #include "TObjArray.h"
42 #include "TObjectTable.h"
43 #include "TClass.h"
44 #include "TStopwatch.h"
45 #include "AliHLTMemoryFile.h"
46 #include "AliHLTMisc.h"
47 #include <cassert>
48
49 /** ROOT macro for the implementation of ROOT specific class methods */
50 ClassImp(AliHLTComponent);
51
52 /** stopwatch macro using the stopwatch guard */
53 #define ALIHLTCOMPONENT_STOPWATCH(type) AliHLTStopwatchGuard swguard(fpStopwatches!=NULL?reinterpret_cast<TStopwatch*>(fpStopwatches->At((int)type)):NULL)
54 //#define ALIHLTCOMPONENT_STOPWATCH(type) 
55
56 /** stopwatch macro for operations of the base class */
57 #define ALIHLTCOMPONENT_BASE_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWBase)
58 /** stopwatch macro for operations of the detector algorithm (DA) */
59 #define ALIHLTCOMPONENT_DA_STOPWATCH() ALIHLTCOMPONENT_STOPWATCH(kSWDA)
60
61 AliHLTComponent::AliHLTComponent()
62   :
63   fEnvironment(),
64   fCurrentEvent(0),
65   fEventCount(-1),
66   fFailedEvents(0),
67   fCurrentEventData(),
68   fpInputBlocks(NULL),
69   fCurrentInputBlock(-1),
70   fSearchDataType(kAliHLTVoidDataType),
71   fClassName(),
72   fpInputObjects(NULL),
73   fpOutputBuffer(NULL),
74   fOutputBufferSize(0),
75   fOutputBufferFilled(0),
76   fOutputBlocks(),
77   fpStopwatches(new TObjArray(kSWTypeCount)),
78   fMemFiles(),
79   fpRunDesc(NULL),
80   fpDDLList(NULL),
81   fCDBSetRunNoFunc(false),
82   fChainId()
83 {
84   // see header file for class documentation
85   // or
86   // refer to README to build package
87   // or
88   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
89   memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
90   if (fgpComponentHandler)
91     fgpComponentHandler->ScheduleRegister(this);
92   //SetLocalLoggingLevel(kHLTLogDefault);
93 }
94
95 AliHLTComponent::~AliHLTComponent()
96 {
97   // see header file for function documentation
98   CleanupInputObjects();
99   if (fpStopwatches!=NULL) delete fpStopwatches;
100   fpStopwatches=NULL;
101   AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
102   while (element!=fMemFiles.end()) {
103     if (*element) {
104       if ((*element)->IsClosed()==0) {
105         HLTWarning("memory file has not been closed, possible data loss or incomplete buffer");
106         // close but do not flush as we dont know whether the buffer is still valid
107         (*element)->CloseMemoryFile(0);
108       }
109       delete *element;
110       *element=NULL;
111     }
112     element++;
113   }
114 }
115
116 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
117
118 int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite) 
119 {
120   // see header file for function documentation
121   int iResult=0;
122   if (fgpComponentHandler==NULL || bOverwrite!=0)
123     fgpComponentHandler=pCH;
124   else
125     iResult=-EPERM;
126   return iResult;
127 }
128
129 int AliHLTComponent::UnsetGlobalComponentHandler() 
130 {
131   // see header file for function documentation
132   return SetGlobalComponentHandler(NULL,1);
133 }
134
135 int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv )
136 {
137   // see header file for function documentation
138   int iResult=0;
139   if (environ) {
140     memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment));
141     fEnvironment.fParam=environParam;
142   }
143   const char** pArguments=NULL;
144   int iNofChildArgs=0;
145   TString argument="";
146   int bMissingParam=0;
147   if (argc>0) {
148     pArguments=new const char*[argc];
149     if (pArguments) {
150       for (int i=0; i<argc && iResult>=0; i++) {
151         argument=argv[i];
152         if (argument.IsNull()) continue;
153
154         // benchmark
155         if (argument.CompareTo("benchmark")==0) {
156
157           // loglevel
158         } else if (argument.CompareTo("loglevel")==0) {
159           if ((bMissingParam=(++i>=argc))) break;
160           TString parameter(argv[i]);
161           parameter.Remove(TString::kLeading, ' '); // remove all blanks
162           if (parameter.BeginsWith("0x") &&
163               parameter.Replace(0,2,"",0).IsHex()) {
164             AliHLTComponentLogSeverity loglevel=kHLTLogNone;
165             sscanf(parameter.Data(),"%x", (unsigned int*)&loglevel);
166             SetLocalLoggingLevel(loglevel);
167           } else {
168             HLTError("wrong parameter for argument %s, hex number expected", argument.Data());
169             iResult=-EINVAL;
170           }
171         } else {
172           pArguments[iNofChildArgs++]=argv[i];
173         }
174       }
175     } else {
176       iResult=-ENOMEM;
177     }
178   }
179   if (bMissingParam) {
180     HLTError("missing parameter for argument %s", argument.Data());
181     iResult=-EINVAL;
182   }
183   if (iResult>=0) {
184     iResult=DoInit(iNofChildArgs, pArguments);
185   }
186   if (iResult>=0) fEventCount=0;
187   if (pArguments) delete [] pArguments;
188   return iResult;
189 }
190
191 int AliHLTComponent::Deinit()
192 {
193   // see header file for function documentation
194   int iResult=0;
195   iResult=DoDeinit();
196   if (fpRunDesc) {
197     HLTWarning("did not receive EOR for run %d", fpRunDesc->fRunNo);
198     AliHLTRunDesc* pRunDesc=fpRunDesc;
199     fpRunDesc=NULL;
200     delete pRunDesc;
201   }
202   fEventCount=0;
203   return iResult;
204 }
205
206 int AliHLTComponent::InitCDB(const char* cdbPath, AliHLTComponentHandler* pHandler)
207 {
208   // see header file for function documentation
209   int iResult=0;
210   if (cdbPath, pHandler) {
211   // I have to think about separating the library handling from the
212   // component handler. Requiring the component hanlder here is not
213   // the cleanest solution.
214   // We presume the library already to be loaded
215   // find the symbol
216   AliHLTMiscInitCDB_t pFunc=(AliHLTMiscInitCDB_t)pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_INIT_CDB);
217   if (pFunc) {
218     if ((iResult=(*pFunc)(cdbPath))>=0) {
219       if (!(fCDBSetRunNoFunc=pHandler->FindSymbol(ALIHLTMISC_LIBRARY, ALIHLTMISC_SET_CDB_RUNNO))) {
220         Message(NULL, kHLTLogWarning, "AliHLTComponent::InitCDB", "init CDB",
221                 "can not find function to set CDB run no");
222       }
223     }
224   } else {
225     Message(NULL, kHLTLogError, "AliHLTComponent::InitCDB", "init CDB",
226             "can not find initialization function");
227     iResult=-ENOSYS;
228   }
229   } else {
230     iResult=-EINVAL;
231   }
232   return iResult;
233 }
234
235 int AliHLTComponent::SetCDBRunNo(int runNo)
236 {
237   // see header file for function documentation
238   if (!fCDBSetRunNoFunc) return 0;
239   return (*((AliHLTMiscSetCDBRunNo_t)fCDBSetRunNoFunc))(runNo);
240 }
241
242 int AliHLTComponent::DoInit( int /*argc*/, const char** /*argv*/)
243 {
244   // default implementation, childs can overload
245   return 0;
246 }
247
248 int AliHLTComponent::DoDeinit()
249 {
250   // default implementation, childs can overload
251   return 0;
252 }
253
254 int AliHLTComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
255 {
256   // default implementation, childs can overload
257   return 0;
258 }
259
260 int AliHLTComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& /*tgtList*/)
261 {
262   // default implementation, childs can overload
263   HLTLogKeyword("dummy");
264   return 0;
265 }
266
267 void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
268 {
269   // see header file for function documentation
270   memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
271   strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
272   strcat( output, ":" );
273   strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
274 }
275
276 string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, int mode)
277 {
278   // see header file for function documentation
279   string out("");
280
281   if (mode==2) {
282     int i=0;
283     char tmp[8];
284     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
285       sprintf(tmp, "'%d", type.fOrigin[i]);
286       out+=tmp;
287     }
288     out+="':'";
289     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
290       sprintf(tmp, "%d'", type.fID[i]);
291       out+=tmp;
292     }
293     return out;
294   }
295
296   if (mode==1) {
297     int i=0;
298     char tmp[8];
299     for (i=0; i<kAliHLTComponentDataTypefOriginSize; i++) {
300       unsigned char* puc=(unsigned char*)type.fOrigin;
301       if ((puc[i])<32)
302         sprintf(tmp, "'\\%x", type.fOrigin[i]);
303       else
304         sprintf(tmp, "'%c", type.fOrigin[i]);
305       out+=tmp;
306     }
307     out+="':'";
308     for (i=0; i<kAliHLTComponentDataTypefIDsize; i++) {
309       unsigned char* puc=(unsigned char*)type.fID;
310       if (puc[i]<32)
311         sprintf(tmp, "\\%x'", type.fID[i]);
312       else
313         sprintf(tmp, "%c'", type.fID[i]);
314       out+=tmp;
315     }
316     return out;
317   }
318
319   if (type==kAliHLTVoidDataType) {
320     out="VOID:VOID";
321   } else {
322     // some gymnastics in order to avoid a '0' which is part of either or both
323     // ID and origin terminating the whole string. Unfortunately, string doesn't
324     // stop appending at the '0' if the number of elements to append was 
325     // explicitely specified
326     string tmp("");
327     tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
328     out.append(tmp.c_str());
329     out.append(":");
330     tmp="";
331     tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
332     out.append(tmp.c_str());
333   }
334   return out;
335 }
336
337
338 void* AliHLTComponent::AllocMemory( unsigned long size ) 
339 {
340   // see header file for function documentation
341   if (fEnvironment.fAllocMemoryFunc)
342     return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
343   HLTFatal("no memory allocation handler registered");
344   return NULL;
345 }
346
347 int AliHLTComponent::MakeOutputDataBlockList( const AliHLTComponentBlockDataList& blocks, AliHLTUInt32_t* blockCount,
348                                               AliHLTComponentBlockData** outputBlocks ) 
349 {
350   // see header file for function documentation
351     if ( blockCount==NULL || outputBlocks==NULL )
352         return -EFAULT;
353     AliHLTUInt32_t count = blocks.size();
354     if ( !count )
355         {
356         *blockCount = 0;
357         *outputBlocks = NULL;
358         return 0;
359         }
360     *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
361     if ( !*outputBlocks )
362         return -ENOMEM;
363     for ( unsigned long i = 0; i < count; i++ ) {
364         (*outputBlocks)[i] = blocks[i];
365         if (MatchExactly(blocks[i].fDataType, kAliHLTAnyDataType)) {
366           (*outputBlocks)[i].fDataType=GetOutputDataType();
367           /* data type was set to the output data type by the PubSub AliRoot
368              Wrapper component, if data type of the block was ********:****.
369              Now handled by the component base class in order to have same
370              behavior when running embedded in AliRoot
371           memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
372           memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
373           */
374         }
375     }
376     *blockCount = count;
377     return 0;
378
379 }
380
381 int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) 
382 {
383   // see header file for function documentation
384   if (fEnvironment.fGetEventDoneDataFunc)
385     return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
386   return -ENOSYS;
387 }
388
389 int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, AliHLTComponentDataTypeList* tgtList) 
390 {
391   // see header file for function documentation
392   int iResult=0;
393   if (pConsumer) {
394     AliHLTComponentDataTypeList itypes;
395     AliHLTComponentDataTypeList otypes;
396     otypes.push_back(GetOutputDataType());
397     if (otypes[0]==kAliHLTMultipleDataType) {
398       otypes.clear();
399       int count=0;
400       if ((count=GetOutputDataTypes(otypes))>0) {
401       } else if (GetComponentType()!=kSink) {
402         HLTWarning("component %s indicates multiple output data types but GetOutputDataTypes returns %d", GetComponentID(), count);
403       }
404     }
405     ((AliHLTComponent*)pConsumer)->GetInputDataTypes(itypes);
406     AliHLTComponentDataTypeList::iterator itype=itypes.begin();
407     while (itype!=itypes.end()) {
408       //PrintDataTypeContent((*itype), "consumer \'%s\'");
409       AliHLTComponentDataTypeList::iterator otype=otypes.begin();
410       while (otype!=otypes.end() && (*itype)!=(*otype)) otype++;
411       //if (otype!=otypes.end()) PrintDataTypeContent(*otype, "publisher \'%s\'");
412       if (otype!=otypes.end()) {
413         if (tgtList) tgtList->push_back(*itype);
414         iResult++;
415       }
416       itype++;
417     }
418   } else {
419     iResult=-EINVAL;
420   }
421   return iResult;
422 }
423
424 void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format) const
425 {
426   // see header file for function documentation
427   const char* fmt="publisher \'%s\'";
428   if (format) fmt=format;
429   HLTMessage(fmt, (DataType2Text(dt)).c_str());
430   HLTMessage("%x %x %x %x %x %x %x %x : %x %x %x %x", 
431              dt.fID[0],
432              dt.fID[1],
433              dt.fID[2],
434              dt.fID[3],
435              dt.fID[4],
436              dt.fID[5],
437              dt.fID[6],
438              dt.fID[7],
439              dt.fOrigin[0],
440              dt.fOrigin[1],
441              dt.fOrigin[2],
442              dt.fOrigin[3]);
443 }
444
445 void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData )
446 {
447   // see header file for function documentation
448   blockData.fStructSize = sizeof(blockData);
449   FillShmData( blockData.fShmKey );
450   blockData.fOffset = ~(AliHLTUInt32_t)0;
451   blockData.fPtr = NULL;
452   blockData.fSize = 0;
453   FillDataType( blockData.fDataType );
454   blockData.fSpecification = kAliHLTVoidDataSpec;
455 }
456
457 void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData )
458 {
459   // see header file for function documentation
460   shmData.fStructSize = sizeof(shmData);
461   shmData.fShmType = gkAliHLTComponentInvalidShmType;
462   shmData.fShmID = gkAliHLTComponentInvalidShmID;
463 }
464
465 void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType )
466 {
467   // see header file for function documentation
468   dataType=kAliHLTAnyDataType;
469 }
470
471 void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt) 
472 {
473   // see header file for function documentation
474   memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
475   memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
476 }
477
478 void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin) 
479 {
480   // see header file for function documentation
481   tgtdt.fStructSize=sizeof(AliHLTComponentDataType);
482   if (id) {
483     memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
484     strncpy(&tgtdt.fID[0], id, strlen(id)<(size_t)kAliHLTComponentDataTypefIDsize?strlen(id):kAliHLTComponentDataTypefIDsize);
485   }
486   if (origin) {
487     memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
488     strncpy(&tgtdt.fOrigin[0], origin, strlen(origin)<(size_t)kAliHLTComponentDataTypefOriginSize?strlen(origin):kAliHLTComponentDataTypefOriginSize);
489   }
490 }
491
492 void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
493 {
494   // see header file for function documentation
495   memset(&evtData, 0, sizeof(AliHLTComponentEventData));
496   evtData.fStructSize=sizeof(AliHLTComponentEventData);
497 }
498
499 void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt) 
500 {
501   // see header file for function documentation
502   TString msg;
503   msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
504   for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
505    if (dt.fID[i]!=0) msg+=dt.fID[i];
506    else msg+="\\0";
507   }
508   msg+="\" Origin=\"";
509   for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
510    if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
511    else msg+="\\0";
512   }
513   msg+="\"";
514   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
515 }
516
517 int AliHLTComponent::GetEventCount() const
518 {
519   // see header file for function documentation
520   return fEventCount;
521 }
522
523 int AliHLTComponent::IncrementEventCounter()
524 {
525   // see header file for function documentation
526   if (fEventCount>=0) fEventCount++;
527   return fEventCount;
528 }
529
530 int AliHLTComponent::GetNumberOfInputBlocks() const
531 {
532   // see header file for function documentation
533   if (fpInputBlocks!=NULL) {
534     return fCurrentEventData.fBlockCnt;
535   }
536   return 0;
537 }
538
539 const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
540                                                     const char* classname,
541                                                     int bForce)
542 {
543   // see header file for function documentation
544   ALIHLTCOMPONENT_BASE_STOPWATCH();
545   fSearchDataType=dt;
546   if (classname) fClassName=classname;
547   else fClassName.clear();
548   int idx=FindInputBlock(fSearchDataType, 0, 1);
549   TObject* pObj=NULL;
550   if (idx>=0) {
551     HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
552     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
553       fCurrentInputBlock=idx;
554     } else {
555     }
556   }
557   return pObj;
558 }
559
560 const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID, 
561                                                     const char* dtOrigin,
562                                                     const char* classname,
563                                                     int         bForce)
564 {
565   // see header file for function documentation
566   ALIHLTCOMPONENT_BASE_STOPWATCH();
567   AliHLTComponentDataType dt;
568   SetDataType(dt, dtID, dtOrigin);
569   return GetFirstInputObject(dt, classname, bForce);
570 }
571
572 const TObject* AliHLTComponent::GetNextInputObject(int bForce)
573 {
574   // see header file for function documentation
575   ALIHLTCOMPONENT_BASE_STOPWATCH();
576   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1, 1);
577   //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
578   TObject* pObj=NULL;
579   if (idx>=0) {
580     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
581       fCurrentInputBlock=idx;
582     }
583   }
584   return pObj;
585 }
586
587 int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx, int bObject) const
588 {
589   // see header file for function documentation
590   int iResult=-ENOENT;
591   if (fpInputBlocks!=NULL) {
592     int idx=startIdx<0?0:startIdx;
593     for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
594       if (bObject!=0) {
595         if (fpInputBlocks[idx].fPtr==NULL) continue;
596         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
597         if (firstWord!=fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) continue;
598       }
599       if (dt==fpInputBlocks[idx].fDataType) {
600         iResult=idx;
601       }
602     }
603   }
604   return iResult;
605 }
606
607 TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
608 {
609   // see header file for function documentation
610   TObject* pObj=NULL;
611   if (fpInputBlocks!=NULL) {
612     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
613       if (fpInputBlocks[idx].fPtr) {
614         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
615         if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
616           HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
617           AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
618           TClass* objclass=msg.GetClass();
619           pObj=msg.ReadObject(objclass);
620           if (pObj && objclass) {
621             HLTDebug("object %p type %s created", pObj, objclass->GetName());
622           } else {
623           }
624           //} else {
625         } else if (bForce!=0) {
626           HLTError("size missmatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
627         }
628       } else {
629         HLTFatal("block descriptor empty");
630       }
631     } else {
632       HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
633     }
634   } else {
635     HLTError("no input blocks available");
636   }
637   
638   return pObj;
639 }
640
641 TObject* AliHLTComponent::GetInputObject(int idx, const char* /*classname*/, int bForce)
642 {
643   // see header file for function documentation
644   if (fpInputObjects==NULL) {
645     fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
646   }
647   TObject* pObj=NULL;
648   if (fpInputObjects) {
649     pObj=fpInputObjects->At(idx);
650     if (pObj==NULL) {
651       pObj=CreateInputObject(idx, bForce);
652       if (pObj) {
653         fpInputObjects->AddAt(pObj, idx);
654       }
655     }
656   } else {
657     HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
658   }
659   return pObj;
660 }
661
662 int AliHLTComponent::CleanupInputObjects()
663 {
664   // see header file for function documentation
665   if (!fpInputObjects) return 0;
666   TObjArray* array=fpInputObjects;
667   fpInputObjects=NULL;
668   for (int i=0; i<array->GetEntries(); i++) {
669     TObject* pObj=array->At(i);
670     // grrr, garbage collection strikes back: When read via AliHLTMessage
671     // (CreateInputObject), and written to a TFile afterwards, the
672     // TFile::Close calls ROOOT's garbage collection. No clue why the
673     // object ended up in the key list and needs to be deleted
674     if (pObj && gObjectTable->PtrIsValid(pObj)) delete pObj;
675   }
676   delete array;
677   return 0;
678 }
679
680 AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
681 {
682   // see header file for function documentation
683   ALIHLTCOMPONENT_BASE_STOPWATCH();
684   AliHLTComponentDataType dt=kAliHLTVoidDataType;
685   int idx=fCurrentInputBlock;
686   if (pObject) {
687     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
688     } else {
689       HLTError("unknown object %p", pObject);
690     }
691   }
692   if (idx>=0) {
693     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
694       dt=fpInputBlocks[idx].fDataType;
695     } else {
696       HLTFatal("severe internal error, index out of range");
697     }
698   }
699   return dt;
700 }
701
702 AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
703 {
704   // see header file for function documentation
705   ALIHLTCOMPONENT_BASE_STOPWATCH();
706   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
707   int idx=fCurrentInputBlock;
708   if (pObject) {
709     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
710     } else {
711       HLTError("unknown object %p", pObject);
712     }
713   }
714   if (idx>=0) {
715     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
716       iSpec=fpInputBlocks[idx].fSpecification;
717     } else {
718       HLTFatal("severe internal error, index out of range");
719     }
720   }
721   return iSpec;
722 }
723
724 int AliHLTComponent::Forward(const TObject* pObject)
725 {
726   // see header file for function documentation
727   int iResult=0;
728   int idx=fCurrentInputBlock;
729   if (pObject) {
730     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
731     } else {
732       HLTError("unknown object %p", pObject);
733       iResult=-ENOENT;
734     }
735   }
736   if (idx>=0) {
737     fOutputBlocks.push_back(fpInputBlocks[idx]);
738   }
739   return iResult;
740 }
741
742 int AliHLTComponent::Forward(const AliHLTComponentBlockData* pBlock)
743 {
744   // see header file for function documentation
745   int iResult=0;
746   int idx=fCurrentInputBlock;
747   if (pBlock) {
748     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
749     } else {
750       HLTError("unknown Block %p", pBlock);
751       iResult=-ENOENT;      
752     }
753   }
754   if (idx>=0) {
755     // check for fpInputBlocks pointer done in FindInputBlock
756     fOutputBlocks.push_back(fpInputBlocks[idx]);
757   }
758   return iResult;
759 }
760
761 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
762 {
763   // see header file for function documentation
764   ALIHLTCOMPONENT_BASE_STOPWATCH();
765   fSearchDataType=dt;
766   fClassName.clear();
767   int idx=FindInputBlock(fSearchDataType, 0);
768   const AliHLTComponentBlockData* pBlock=NULL;
769   if (idx>=0) {
770     // check for fpInputBlocks pointer done in FindInputBlock
771     pBlock=&fpInputBlocks[idx];
772     fCurrentInputBlock=idx;
773   }
774   return pBlock;
775 }
776
777 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID, 
778                                                                     const char* dtOrigin)
779 {
780   // see header file for function documentation
781   ALIHLTCOMPONENT_BASE_STOPWATCH();
782   AliHLTComponentDataType dt;
783   SetDataType(dt, dtID, dtOrigin);
784   return GetFirstInputBlock(dt);
785 }
786
787 const AliHLTComponentBlockData* AliHLTComponent::GetInputBlock(int index)
788 {
789   // see header file for function documentation
790   ALIHLTCOMPONENT_BASE_STOPWATCH();
791   assert( 0 <= index and index < fCurrentEventData.fBlockCnt );
792   return &fpInputBlocks[index];
793 }
794
795 const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
796 {
797   // see header file for function documentation
798   ALIHLTCOMPONENT_BASE_STOPWATCH();
799   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
800   const AliHLTComponentBlockData* pBlock=NULL;
801   if (idx>=0) {
802     // check for fpInputBlocks pointer done in FindInputBlock
803     pBlock=&fpInputBlocks[idx];
804     fCurrentInputBlock=idx;
805   }
806   return pBlock;
807 }
808
809 int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock) const
810 {
811   // see header file for function documentation
812   int iResult=-ENOENT;
813   if (fpInputBlocks!=NULL) {
814     if (pBlock) {
815       if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
816         iResult=(int)(pBlock-fpInputBlocks);
817       }
818     } else {
819       iResult=-EINVAL;
820     }
821   }
822   return iResult;
823 }
824
825 AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
826 {
827   // see header file for function documentation
828   ALIHLTCOMPONENT_BASE_STOPWATCH();
829   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
830   int idx=fCurrentInputBlock;
831   if (pBlock) {
832     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
833     } else {
834       HLTError("unknown Block %p", pBlock);
835     }
836   }
837   if (idx>=0) {
838     // check for fpInputBlocks pointer done in FindInputBlock
839     iSpec=fpInputBlocks[idx].fSpecification;
840   }
841   return iSpec;
842 }
843
844 int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec, 
845                               void* pHeader, int headerSize)
846 {
847   // see header file for function documentation
848   ALIHLTCOMPONENT_BASE_STOPWATCH();
849   int iResult=0;
850   if (pObject) {
851     AliHLTMessage msg(kMESS_OBJECT);
852     msg.WriteObject(pObject);
853     Int_t iMsgLength=msg.Length();
854     if (iMsgLength>0) {
855       msg.SetLength(); // sets the length to the first (reserved) word
856       iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec, pHeader, headerSize);
857       if (iResult>=0) {
858         HLTDebug("object %s (%p) size %d inserted to output", pObject->ClassName(), pObject, iMsgLength);
859       }
860     } else {
861       HLTError("object serialization failed for object %p", pObject);
862       iResult=-ENOMSG;
863     }
864   } else {
865     iResult=-EINVAL;
866   }
867   return iResult;
868 }
869
870 int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
871                               void* pHeader, int headerSize)
872 {
873   // see header file for function documentation
874   ALIHLTCOMPONENT_BASE_STOPWATCH();
875   AliHLTComponentDataType dt;
876   SetDataType(dt, dtID, dtOrigin);
877   return PushBack(pObject, dt, spec, pHeader, headerSize);
878 }
879
880 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
881                               void* pHeader, int headerSize)
882 {
883   // see header file for function documentation
884   ALIHLTCOMPONENT_BASE_STOPWATCH();
885   return InsertOutputBlock(pBuffer, iSize, dt, spec, pHeader, headerSize);
886 }
887
888 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec,
889                               void* pHeader, int headerSize)
890 {
891   // see header file for function documentation
892   ALIHLTCOMPONENT_BASE_STOPWATCH();
893   AliHLTComponentDataType dt;
894   SetDataType(dt, dtID, dtOrigin);
895   return PushBack(pBuffer, iSize, dt, spec, pHeader, headerSize);
896 }
897
898 int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iBufferSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec,
899                               void* pHeader, int iHeaderSize)
900 {
901   // see header file for function documentation
902   int iResult=0;
903   int iBlkSize = iBufferSize + iHeaderSize;
904   if (pBuffer) {
905     if (fpOutputBuffer && iBlkSize<=(int)(fOutputBufferSize-fOutputBufferFilled)) {
906       AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
907       AliHLTComponentBlockData bd;
908       FillBlockData( bd );
909       bd.fOffset        = fOutputBufferFilled;
910       bd.fSize          = iBlkSize;
911       bd.fDataType      = dt;
912       bd.fSpecification = spec;
913       if (pHeader!=NULL && pHeader!=pTgt) {
914         memcpy(pTgt, pHeader, iHeaderSize);
915       }
916
917       pTgt += (AliHLTUInt8_t) iHeaderSize;
918
919       if (pBuffer!=NULL && pBuffer!=pTgt) {
920         memcpy(pTgt, pBuffer, iBufferSize);
921         
922         //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); 
923         //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iBufferSize, pBuffer, pTgt, firstWord);
924       }
925       fOutputBufferFilled+=bd.fSize;
926       fOutputBlocks.push_back( bd );
927       //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iBlkSize, DataType2Text(dt).c_str(), spec);
928     } else {
929       if (fpOutputBuffer) {
930         HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iBlkSize);
931       } else {
932         HLTError("output buffer not available");
933       }
934       iResult=-ENOSPC;
935     }
936   } else {
937     iResult=-EINVAL;
938   }
939   return iResult;
940 }
941
942 int AliHLTComponent::EstimateObjectSize(TObject* pObject) const
943 {
944   // see header file for function documentation
945   if (!pObject) return -EINVAL;
946     AliHLTMessage msg(kMESS_OBJECT);
947     msg.WriteObject(pObject);
948     return msg.Length();  
949 }
950
951 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity, const char* dtID,
952                                                     const char* dtOrigin,
953                                                     AliHLTUInt32_t spec)
954 {
955   // see header file for function documentation
956   ALIHLTCOMPONENT_BASE_STOPWATCH();
957   AliHLTComponentDataType dt;
958   SetDataType(dt, dtID, dtOrigin);
959   return CreateMemoryFile(capacity, dt, spec);
960 }
961
962 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(int capacity,
963                                                     const AliHLTComponentDataType& dt,
964                                                     AliHLTUInt32_t spec)
965 {
966   // see header file for function documentation
967   ALIHLTCOMPONENT_BASE_STOPWATCH();
968   AliHLTMemoryFile* pFile=NULL;
969   if (capacity>=0 && static_cast<unsigned int>(capacity)<=fOutputBufferSize-fOutputBufferFilled){
970     AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
971     pFile=new AliHLTMemoryFile((char*)pTgt, capacity);
972     if (pFile) {
973       unsigned int nofBlocks=fOutputBlocks.size();
974       if (nofBlocks+1>fMemFiles.size()) {
975         fMemFiles.resize(nofBlocks+1, NULL);
976       }
977       if (nofBlocks<fMemFiles.size()) {
978         fMemFiles[nofBlocks]=pFile;
979         AliHLTComponentBlockData bd;
980         FillBlockData( bd );
981         bd.fOffset        = fOutputBufferFilled;
982         bd.fSize          = capacity;
983         bd.fDataType      = dt;
984         bd.fSpecification = spec;
985         fOutputBufferFilled+=bd.fSize;
986         fOutputBlocks.push_back( bd );
987       } else {
988         HLTError("can not allocate/grow object array");
989         pFile->CloseMemoryFile(0);
990         delete pFile;
991         pFile=NULL;
992       }
993     }
994   } else {
995     HLTError("can not create memory file of size %d (%d available)", capacity, fOutputBufferSize-fOutputBufferFilled);
996   }
997   return pFile;
998 }
999
1000 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const char* dtID,
1001                                                     const char* dtOrigin,
1002                                                     AliHLTUInt32_t spec,
1003                                                     float capacity)
1004 {
1005   // see header file for function documentation
1006   ALIHLTCOMPONENT_BASE_STOPWATCH();
1007   AliHLTComponentDataType dt;
1008   SetDataType(dt, dtID, dtOrigin);
1009   int size=fOutputBufferSize-fOutputBufferFilled;
1010   if (capacity<0 || capacity>1.0) {
1011     HLTError("invalid parameter: capacity %f", capacity);
1012     return NULL;
1013   }
1014   size=(int)(size*capacity);
1015   return CreateMemoryFile(size, dt, spec);
1016 }
1017
1018 AliHLTMemoryFile* AliHLTComponent::CreateMemoryFile(const AliHLTComponentDataType& dt,
1019                                                     AliHLTUInt32_t spec,
1020                                                     float capacity)
1021 {
1022   // see header file for function documentation
1023   ALIHLTCOMPONENT_BASE_STOPWATCH();
1024   int size=fOutputBufferSize-fOutputBufferFilled;
1025   if (capacity<0 || capacity>1.0) {
1026     HLTError("invalid parameter: capacity %f", capacity);
1027     return NULL;
1028   }
1029   size=(int)(size*capacity);
1030   return CreateMemoryFile(size, dt, spec);
1031 }
1032
1033 int AliHLTComponent::Write(AliHLTMemoryFile* pFile, const TObject* pObject,
1034                            const char* key, int option)
1035 {
1036   // see header file for function documentation
1037   int iResult=0;
1038   if (pFile && pObject) {
1039     pFile->cd();
1040     iResult=pObject->Write(key, option);
1041     if (iResult>0) {
1042       // success
1043     } else {
1044       iResult=-pFile->GetErrno();
1045       if (iResult==-ENOSPC) {
1046         HLTError("error writing memory file, buffer too small");
1047       }
1048     }
1049   } else {
1050     iResult=-EINVAL;
1051   }
1052   return iResult;
1053 }
1054
1055 int AliHLTComponent::CloseMemoryFile(AliHLTMemoryFile* pFile)
1056 {
1057   // see header file for function documentation
1058   int iResult=0;
1059   if (pFile) {
1060     AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1061     int i=0;
1062     while (element!=fMemFiles.end() && iResult>=0) {
1063       if (*element && *element==pFile) {
1064         iResult=pFile->CloseMemoryFile();
1065         
1066         // sync memory files and descriptors
1067         if (iResult>=0) {
1068           fOutputBlocks[i].fSize=(*element)->GetSize()+(*element)->GetHeaderSize();
1069         }
1070         delete *element;
1071         *element=NULL;
1072         return iResult;
1073       }
1074       element++; i++;
1075     }
1076     HLTError("can not find memory file %p", pFile);
1077     iResult=-ENOENT;
1078   } else {
1079     iResult=-EINVAL;
1080   }
1081   return iResult;
1082 }
1083
1084 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData /*edd*/)
1085 {
1086   // see header file for function documentation
1087   int iResult=-ENOSYS;
1088   //#warning  function not yet implemented
1089   HLTWarning("function not yet implemented");
1090   return iResult;
1091 }
1092
1093 int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
1094                                    const AliHLTComponentBlockData* blocks, 
1095                                    AliHLTComponentTriggerData& trigData,
1096                                    AliHLTUInt8_t* outputPtr, 
1097                                    AliHLTUInt32_t& size,
1098                                    AliHLTUInt32_t& outputBlockCnt, 
1099                                    AliHLTComponentBlockData*& outputBlocks,
1100                                    AliHLTComponentEventDoneData*& edd )
1101 {
1102   // see header file for function documentation
1103   ALIHLTCOMPONENT_BASE_STOPWATCH();
1104   int iResult=0;
1105   fCurrentEvent=evtData.fEventID;
1106   fCurrentEventData=evtData;
1107   fpInputBlocks=blocks;
1108   fCurrentInputBlock=-1;
1109   fSearchDataType=kAliHLTAnyDataType;
1110   fpOutputBuffer=outputPtr;
1111   fOutputBufferSize=size;
1112   fOutputBufferFilled=0;
1113   fOutputBlocks.clear();
1114
1115   // find special events
1116   if (fpInputBlocks) {
1117     // first look for all special events and execute in the appropriate
1118     // sequence afterwords
1119     int indexComConfEvent=-1;
1120     int indexSOREvent=-1;
1121     int indexEOREvent=-1;
1122     for (unsigned int i=0; i<evtData.fBlockCnt && iResult>=0; i++) {
1123       if (fpInputBlocks[i].fDataType==kAliHLTDataTypeSOR) {
1124         indexSOREvent=i;
1125       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeEOR) {
1126         indexEOREvent=i;
1127       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeDDL) {
1128         // DDL list
1129         // this event is most likely deprecated
1130       } else if (fpInputBlocks[i].fDataType==kAliHLTDataTypeComConf) {
1131         indexComConfEvent=i;
1132       }
1133     }
1134     if (indexSOREvent>=0) {
1135       // start of run
1136       if (fpRunDesc==NULL) {
1137         fpRunDesc=new AliHLTRunDesc;
1138         if (fpRunDesc) {
1139           if ((iResult=CopyStruct(fpRunDesc, sizeof(AliHLTRunDesc), indexSOREvent, "AliHLTRunDesc", "SOR"))>0) {
1140             HLTDebug("set run decriptor, run no %d", fpRunDesc->fRunNo);
1141             SetCDBRunNo(fpRunDesc->fRunNo);
1142           }
1143         } else {
1144           iResult=-ENOMEM;
1145         }
1146       } else {
1147         HLTWarning("already received SOR event run no %d, ignoring SOR", fpRunDesc->fRunNo);
1148       }
1149     }
1150     if (indexEOREvent>=0) {
1151       if (fpRunDesc!=NULL) {
1152         if (fpRunDesc) {
1153           AliHLTRunDesc rundesc;
1154           if ((iResult=CopyStruct(&rundesc, sizeof(AliHLTRunDesc), indexEOREvent, "AliHLTRunDesc", "SOR"))>0) {
1155             if (fpRunDesc->fRunNo!=rundesc.fRunNo) {
1156               HLTWarning("run no missmatch: SOR %d, EOR %d", fpRunDesc->fRunNo, rundesc.fRunNo);
1157             } else {
1158               HLTDebug("EOR run no %d", fpRunDesc->fRunNo);
1159             }
1160           }
1161           AliHLTRunDesc* pRunDesc=fpRunDesc;
1162           fpRunDesc=NULL;
1163           delete pRunDesc;
1164         }
1165       } else {
1166         HLTWarning("did not receive SOR, ignoring EOR");
1167       }
1168     }
1169     if (indexComConfEvent>=0) {
1170       TString cdbEntry;
1171       if (fpInputBlocks[indexComConfEvent].fPtr!=NULL && fpInputBlocks[indexComConfEvent].fSize>0) {
1172         cdbEntry.Append(reinterpret_cast<const char*>(fpInputBlocks[indexComConfEvent].fPtr), fpInputBlocks[indexComConfEvent].fSize);
1173       }
1174       HLTDebug("received component configuration command: entry %s", cdbEntry.IsNull()?"none":cdbEntry.Data());
1175       int tmpResult=Reconfigure(cdbEntry[0]==0?NULL:cdbEntry.Data(), fChainId.c_str());
1176       if (tmpResult<0) {
1177         HLTWarning("reconfiguration of component %p (%s) failed with error code %d", this, GetComponentID(), tmpResult);
1178       }
1179     }
1180   }
1181   
1182   AliHLTComponentBlockDataList blockData;
1183   { // dont delete, sets the scope for the stopwatch guard
1184     ALIHLTCOMPONENT_DA_STOPWATCH();
1185     iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
1186   } // end of the scope of the stopwatch guard
1187   if (iResult>=0) {
1188     if (fOutputBlocks.size()>0) {
1189       //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
1190       
1191       // sync memory files and descriptors
1192       AliHLTMemoryFilePList::iterator element=fMemFiles.begin();
1193       int i=0;
1194       while (element!=fMemFiles.end() && iResult>=0) {
1195         if (*element) {
1196           if ((*element)->IsClosed()==0) {
1197             HLTWarning("memory file has not been closed, force flush");
1198             iResult=CloseMemoryFile(*element);
1199           }
1200         }
1201         element++; i++;
1202       }
1203
1204       if (iResult>=0) {
1205         // create the descriptor list
1206         if (blockData.size()>0) {
1207           HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
1208           iResult=-EFAULT;
1209         } else {
1210           iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
1211           size=fOutputBufferFilled;
1212         }
1213       }
1214     } else {
1215       iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
1216     }
1217     if (iResult<0) {
1218       HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
1219     }
1220   }
1221   if (iResult<0) {
1222     outputBlockCnt=0;
1223     outputBlocks=NULL;
1224   }
1225   CleanupInputObjects();
1226   if (iResult>=0) {
1227     IncrementEventCounter();
1228   }
1229   return iResult;
1230 }
1231
1232 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard()
1233   :
1234   fpStopwatch(NULL),
1235   fpPrec(NULL)
1236 {
1237   // standard constructor (not for use)
1238 }
1239
1240 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(TStopwatch* pStopwatch)
1241   :
1242   fpStopwatch(pStopwatch),
1243   fpPrec(NULL)
1244 {
1245   // constructor
1246
1247   // check for already existing guard
1248   if (fgpCurrent) fpPrec=fgpCurrent;
1249   fgpCurrent=this;
1250
1251   // stop the preceeding guard if it controls a different stopwatch
1252   int bStart=1;
1253   if (fpPrec && fpPrec!=this) bStart=fpPrec->Hold(fpStopwatch);
1254
1255   // start the stopwatch if the current guard controls a different one
1256   if (fpStopwatch && bStart==1) fpStopwatch->Start(kFALSE);
1257 }
1258
1259 AliHLTComponent::AliHLTStopwatchGuard::AliHLTStopwatchGuard(const AliHLTStopwatchGuard&)
1260   :
1261   fpStopwatch(NULL),
1262   fpPrec(NULL)
1263 {
1264   //
1265   // copy constructor not for use
1266   //
1267 }
1268
1269 AliHLTComponent::AliHLTStopwatchGuard& AliHLTComponent::AliHLTStopwatchGuard::operator=(const AliHLTStopwatchGuard&)
1270 {
1271   //
1272   // assignment operator not for use
1273   //
1274   fpStopwatch=NULL;
1275   fpPrec=NULL;
1276   return *this;
1277 }
1278
1279 AliHLTComponent::AliHLTStopwatchGuard* AliHLTComponent::AliHLTStopwatchGuard::fgpCurrent=NULL;
1280
1281 AliHLTComponent::AliHLTStopwatchGuard::~AliHLTStopwatchGuard()
1282 {
1283   // destructor
1284
1285   // resume the preceeding guard if it controls a different stopwatch
1286   int bStop=1;
1287   if (fpPrec && fpPrec!=this) bStop=fpPrec->Resume(fpStopwatch);
1288
1289   // stop the stopwatch if the current guard controls a different one
1290   if (fpStopwatch && bStop==1) fpStopwatch->Stop();
1291
1292   // resume to the preceeding guard
1293   fgpCurrent=fpPrec;
1294 }
1295
1296 int AliHLTComponent::AliHLTStopwatchGuard::Hold(TStopwatch* pSucc)
1297 {
1298   // see header file for function documentation
1299   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Stop();
1300   return fpStopwatch!=pSucc?1:0;
1301 }
1302
1303 int AliHLTComponent::AliHLTStopwatchGuard::Resume(TStopwatch* pSucc)
1304 {
1305   // see header file for function documentation
1306   if (fpStopwatch!=NULL && fpStopwatch!=pSucc) fpStopwatch->Start(kFALSE);
1307   return fpStopwatch!=pSucc?1:0;
1308 }
1309
1310 int AliHLTComponent::SetStopwatch(TObject* pSW, AliHLTStopwatchType type) 
1311 {
1312   // see header file for function documentation
1313   int iResult=0;
1314   if (pSW!=NULL && type<kSWTypeCount) {
1315     if (fpStopwatches) {
1316       TObject* pObj=fpStopwatches->At((int)type);
1317       if (pSW==NULL        // explicit reset
1318           || pObj==NULL) { // explicit set
1319         fpStopwatches->AddAt(pSW, (int)type);
1320       } else if (pObj!=pSW) {
1321         HLTWarning("stopwatch %d already set, reset first", (int)type);
1322         iResult=-EBUSY;
1323       }
1324     }
1325   } else {
1326     iResult=-EINVAL;
1327   }
1328   return iResult;
1329 }
1330
1331 int AliHLTComponent::SetStopwatches(TObjArray* pStopwatches)
1332 {
1333   // see header file for function documentation
1334   if (pStopwatches==NULL) return -EINVAL;
1335
1336   int iResult=0;
1337   for (int i=0 ; i<(int)kSWTypeCount && pStopwatches->GetEntries(); i++)
1338     SetStopwatch(pStopwatches->At(i), (AliHLTStopwatchType)i);
1339   return iResult;
1340 }
1341
1342 AliHLTUInt32_t AliHLTComponent::GetRunNo() const
1343 {
1344   // see header file for function documentation
1345   if (fpRunDesc==NULL) return 0;
1346   return fpRunDesc->fRunNo;
1347 }
1348
1349 AliHLTUInt32_t AliHLTComponent::GetRunType() const
1350 {
1351   // see header file for function documentation
1352   if (fpRunDesc==NULL) return 0;
1353   return fpRunDesc->fRunType;
1354 }
1355
1356 int AliHLTComponent::CopyStruct(void* pStruct, unsigned int iStructSize, unsigned int iBlockNo,
1357                                 const char* structname, const char* eventname)
1358 {
1359   // see header file for function documentation
1360   int iResult=0;
1361   if (pStruct!=NULL && iStructSize>sizeof(AliHLTUInt32_t)) {
1362     if (fpInputBlocks!=NULL && iBlockNo<fCurrentEventData.fBlockCnt) {
1363       AliHLTUInt32_t* pTgt=(AliHLTUInt32_t*)pStruct;
1364       if (fpInputBlocks[iBlockNo].fPtr && fpInputBlocks[iBlockNo].fSize) {
1365         AliHLTUInt32_t copy=*((AliHLTUInt32_t*)fpInputBlocks[iBlockNo].fPtr);
1366         if (fpInputBlocks[iBlockNo].fSize!=copy) {
1367           HLTWarning("%s event: missmatch of block size (%d) and structure size (%d)", eventname, fpInputBlocks[iBlockNo].fSize, copy);
1368           if (copy>fpInputBlocks[iBlockNo].fSize) copy=fpInputBlocks[iBlockNo].fSize;
1369         }
1370         if (copy!=iStructSize) {
1371           HLTWarning("%s event: missmatch in %s version (data type version %d)", eventname, structname, ALIHLT_DATA_TYPES_VERSION);
1372           if (copy>iStructSize) {
1373             copy=iStructSize;
1374           } else {
1375             memset(pTgt, 0, iStructSize);
1376           }
1377         }
1378         memcpy(pTgt, fpInputBlocks[iBlockNo].fPtr, copy);
1379         *pTgt=iStructSize;
1380         iResult=copy;
1381       } else {
1382         HLTWarning("%s event: missing data block", eventname);
1383       }
1384     } else {
1385       iResult=-ENODATA;
1386     }
1387   } else {
1388     HLTError("invalid struct");
1389     iResult=-EINVAL;
1390   }
1391   return iResult;
1392 }
1393
1394 void AliHLTComponent::SetDDLBit(AliHLTEventDDL &list, Int_t ddlId, Bool_t state ) const
1395 {
1396   // see header file for function documentation
1397   
1398   // -- Detector offset
1399   Int_t ddlIdBase =  TMath::FloorNint( (Double_t) ddlId / 256.0 );
1400   
1401   // -- Word Base = 1. word of detector ( TPC has 8 words, TOF 3 ) 
1402   Int_t wordBase = 0;
1403
1404   if ( ddlIdBase <= 3 )
1405     wordBase = ddlIdBase;
1406   else if ( ddlIdBase > 3 && ddlIdBase < 5 )
1407     wordBase = ddlIdBase + 7;
1408   else 
1409     wordBase = ddlIdBase + 9;
1410
1411   // -- Bit index in Word
1412   Int_t bitIdx = ddlId % 32;
1413
1414   // -- Index of word
1415   Int_t wordIdx = wordBase;
1416
1417   // -- if TPC (3) or TOD (5) add word idx
1418   if ( ( ddlIdBase == 3 ) || ( ddlIdBase == 5 ) ) {
1419     wordIdx += TMath::FloorNint( (Double_t) ( ddlId - ( ddlIdBase * 256 ) ) / 32.0 );
1420   }
1421
1422   // -- Set -- 'OR' word with bit mask;
1423   if ( state )
1424     list.fList[wordIdx] |= ( 0x00000001 << bitIdx );
1425   // -- Unset -- 'AND' word with bit mask;
1426   else
1427     list.fList[wordIdx] &= ( 0xFFFFFFFF ^ ( 0x00000001 << bitIdx ) );
1428 }
1429
1430 Int_t AliHLTComponent::GetFirstUsedDDLWord(AliHLTEventDDL &list) const
1431 {
1432   // see header file for function documentation
1433
1434   Int_t iResult = -1;
1435
1436   for ( Int_t wordNdx = 0 ; wordNdx < gkAliHLTDDLListSize ; wordNdx++ ) {
1437
1438     if ( list.fList[wordNdx] != 0 && iResult == -1 ) {
1439       // check for special cases TPC and TOF
1440       if ( wordNdx > 3 && wordNdx <= 10 ) {
1441         wordNdx = 10;
1442         iResult = 3;
1443       }
1444       else if ( wordNdx > 12 && wordNdx <= 14 ) {
1445         wordNdx = 14;
1446         iResult = 12;
1447       }
1448       else
1449         iResult = wordNdx;
1450     }
1451     else if ( list.fList[wordNdx] != 0 && iResult >= 0 ) {
1452       HLTError( "DDLIDs for minimum of TWO detectors ( %d, %d ) set, this function works only for ONE detector.", iResult, wordNdx );
1453       iResult = -1;
1454       break;
1455     }
1456   }
1457
1458   return iResult;
1459 }