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