]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTComponent.cxx
o) Performance studies added (mainly in runMultiplicitySelector) that evaluate the...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
8  *          for The ALICE Off-line Project.                               *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTComponent.cxx
20     @author Matthias Richter, Timm Steinbeck
21     @date   
22     @brief  Base class implementation for HLT components. */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTStdIncludes.h"
29 #include "AliHLTComponent.h"
30 #include "AliHLTComponentHandler.h"
31 #include "AliHLTMessage.h"
32 #include "TString.h"
33 #include "TObjArray.h"
34 #include "TClass.h"
35
36 /** ROOT macro for the implementation of ROOT specific class methods */
37 ClassImp(AliHLTComponent)
38
39 AliHLTComponent::AliHLTComponent()
40   :
41   fEnvironment(),
42   fCurrentEvent(0),
43   fEventCount(-1),
44   fFailedEvents(0),
45   fCurrentEventData(),
46   fpInputBlocks(NULL),
47   fCurrentInputBlock(-1),
48   fSearchDataType(kAliHLTVoidDataType),
49   fClassName(),
50   fpInputObjects(NULL),
51   fpOutputBuffer(NULL),
52   fOutputBufferSize(0),
53   fOutputBufferFilled(0),
54   fOutputBlocks()
55 {
56   // see header file for class documentation
57   // or
58   // refer to README to build package
59   // or
60   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
61   memset(&fEnvironment, 0, sizeof(AliHLTComponentEnvironment));
62   if (fgpComponentHandler)
63     fgpComponentHandler->ScheduleRegister(this);
64 }
65
66 AliHLTComponent::AliHLTComponent(const AliHLTComponent&)
67   :
68   AliHLTLogging(),
69   fEnvironment(),
70   fCurrentEvent(0),
71   fEventCount(-1),
72   fFailedEvents(0),
73   fCurrentEventData(),
74   fpInputBlocks(NULL),
75   fCurrentInputBlock(-1),
76   fSearchDataType(kAliHLTVoidDataType),
77   fClassName(),
78   fpInputObjects(NULL),
79   fpOutputBuffer(NULL),
80   fOutputBufferSize(0),
81   fOutputBufferFilled(0),
82   fOutputBlocks()
83 {
84   // see header file for class documentation
85   HLTFatal("copy constructor untested");
86 }
87
88 AliHLTComponent& AliHLTComponent::operator=(const AliHLTComponent&)
89
90   // see header file for class documentation
91   HLTFatal("assignment operator untested");
92   return *this;
93 }
94
95 AliHLTComponent::~AliHLTComponent()
96 {
97   // see header file for function documentation
98 }
99
100 AliHLTComponentHandler* AliHLTComponent::fgpComponentHandler=NULL;
101
102 int AliHLTComponent::SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite) 
103 {
104   // see header file for function documentation
105   int iResult=0;
106   if (fgpComponentHandler==NULL || bOverwrite!=0)
107     fgpComponentHandler=pCH;
108   else
109     iResult=-EPERM;
110   return iResult;
111 }
112
113 int AliHLTComponent::UnsetGlobalComponentHandler() 
114 {
115   // see header file for function documentation
116   return SetGlobalComponentHandler(NULL,1);
117 }
118
119 int AliHLTComponent::Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv )
120 {
121   // see header file for function documentation
122   int iResult=0;
123   if (environ) {
124     memcpy(&fEnvironment, environ, sizeof(AliHLTComponentEnvironment));
125     fEnvironment.fParam=environParam;
126   }
127   iResult=DoInit(argc, argv);
128   if (iResult>=0) fEventCount=0;
129   return iResult;
130 }
131
132 int AliHLTComponent::Deinit()
133 {
134   // see header file for function documentation
135   int iResult=0;
136   iResult=DoDeinit();
137   return iResult;
138 }
139
140 int AliHLTComponent::DoInit( int argc, const char** argv )
141 {
142   // see header file for function documentation
143   if (argc==0 && argv==NULL) {
144     // this is currently just to get rid of the warning "unused parameter"
145   }
146   return 0;
147 }
148
149 int AliHLTComponent::DoDeinit()
150 {
151   // see header file for function documentation
152   return 0;
153 }
154
155 void AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2] ) const
156 {
157   // see header file for function documentation
158   memset( output, 0, kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2 );
159   strncat( output, type.fOrigin, kAliHLTComponentDataTypefOriginSize );
160   strcat( output, ":" );
161   strncat( output, type.fID, kAliHLTComponentDataTypefIDsize );
162 }
163
164 string AliHLTComponent::DataType2Text( const AliHLTComponentDataType& type )
165 {
166   // see header file for function documentation
167   string out("");
168   
169   if (type==kAliHLTVoidDataType) {
170     out="VOID:VOID";
171   } else {
172     // some gymnastics in order to avoid a '0' which is part of either or both
173     // ID and origin terminating the whole string. Unfortunately, string doesn't
174     // stop appending at the '0' if the number of elements to append was 
175     // explicitely specified
176     string tmp("");
177     tmp.append(type.fOrigin, kAliHLTComponentDataTypefOriginSize);
178     out.append(tmp.c_str());
179     out.append(":");
180     tmp="";
181     tmp.append(type.fID, kAliHLTComponentDataTypefIDsize);
182     out.append(tmp.c_str());
183   }
184   return out;
185 }
186
187
188 void* AliHLTComponent::AllocMemory( unsigned long size ) 
189 {
190   // see header file for function documentation
191   if (fEnvironment.fAllocMemoryFunc)
192     return (*fEnvironment.fAllocMemoryFunc)(fEnvironment.fParam, size );
193   HLTFatal("no memory allocation handler registered");
194   return NULL;
195 }
196
197 int AliHLTComponent::MakeOutputDataBlockList( const vector<AliHLTComponentBlockData>& blocks, AliHLTUInt32_t* blockCount,
198                                               AliHLTComponentBlockData** outputBlocks ) 
199 {
200   // see header file for function documentation
201     if ( blockCount==NULL || outputBlocks==NULL )
202         return -EFAULT;
203     AliHLTUInt32_t count = blocks.size();
204     if ( !count )
205         {
206         *blockCount = 0;
207         *outputBlocks = NULL;
208         return 0;
209         }
210     *outputBlocks = reinterpret_cast<AliHLTComponentBlockData*>( AllocMemory( sizeof(AliHLTComponentBlockData)*count ) );
211     if ( !*outputBlocks )
212         return -ENOMEM;
213     for ( unsigned long i = 0; i < count; i++ ) {
214         (*outputBlocks)[i] = blocks[i];
215         if (blocks[i].fDataType==kAliHLTAnyDataType) {
216           (*outputBlocks)[i].fDataType=GetOutputDataType();
217           /* data type was set to the output data type by the PubSub AliRoot
218              Wrapper component, if data type of the block was ********:****.
219              Now handled by the component base class in order to have same
220              behavior when running embedded in AliRoot
221           memset((*outputBlocks)[i].fDataType.fID, '*', kAliHLTComponentDataTypefIDsize);
222           memset((*outputBlocks)[i].fDataType.fOrigin, '*', kAliHLTComponentDataTypefOriginSize);
223           */
224         }
225     }
226     *blockCount = count;
227     return 0;
228
229 }
230
231 int AliHLTComponent::GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd ) 
232 {
233   // see header file for function documentation
234   if (fEnvironment.fGetEventDoneDataFunc)
235     return (*fEnvironment.fGetEventDoneDataFunc)(fEnvironment.fParam, fCurrentEvent, size, edd );
236   return -ENOSYS;
237 }
238
239 int AliHLTComponent::FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList) 
240 {
241   // see header file for function documentation
242   int iResult=0;
243   if (pConsumer) {
244     vector<AliHLTComponentDataType> ctlist;
245     ((AliHLTComponent*)pConsumer)->GetInputDataTypes(ctlist);
246     vector<AliHLTComponentDataType>::iterator type=ctlist.begin();
247     //AliHLTComponentDataType ouptdt=GetOutputDataType();
248     //PrintDataTypeContent(ouptdt, "publisher \'%s\'");
249     while (type!=ctlist.end() && iResult==0) {
250       //PrintDataTypeContent((*type), "consumer \'%s\'");
251       if ((*type)==GetOutputDataType() ||
252           (*type)==kAliHLTAnyDataType) {
253         if (tgtList) tgtList->push_back(*type);
254         iResult++;
255         // this loop has to be changed in case of multiple output types
256         break;
257       }
258       type++;
259     }
260   } else {
261     iResult=-EINVAL;
262   }
263   return iResult;
264 }
265
266 void AliHLTComponent::PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format) const
267 {
268   const char* fmt="publisher \'%s\'";
269   if (format) fmt=format;
270   HLTMessage(fmt, (DataType2Text(dt)).c_str());
271   HLTMessage("%x %x %x %x %x %x %x %x : %x %x %x %x", 
272              dt.fID[0],
273              dt.fID[1],
274              dt.fID[2],
275              dt.fID[3],
276              dt.fID[4],
277              dt.fID[5],
278              dt.fID[6],
279              dt.fID[7],
280              dt.fOrigin[0],
281              dt.fOrigin[1],
282              dt.fOrigin[2],
283              dt.fOrigin[3]);
284 }
285
286 void AliHLTComponent::FillBlockData( AliHLTComponentBlockData& blockData ) const
287 {
288   // see header file for function documentation
289   blockData.fStructSize = sizeof(blockData);
290   FillShmData( blockData.fShmKey );
291   blockData.fOffset = ~(AliHLTUInt32_t)0;
292   blockData.fPtr = NULL;
293   blockData.fSize = 0;
294   FillDataType( blockData.fDataType );
295   blockData.fSpecification = kAliHLTVoidDataSpec;
296 }
297
298 void AliHLTComponent::FillShmData( AliHLTComponentShmData& shmData ) const
299 {
300   // see header file for function documentation
301   shmData.fStructSize = sizeof(shmData);
302   shmData.fShmType = gkAliHLTComponentInvalidShmType;
303   shmData.fShmID = gkAliHLTComponentInvalidShmID;
304 }
305
306 void AliHLTComponent::FillDataType( AliHLTComponentDataType& dataType ) const
307 {
308   // see header file for function documentation
309   dataType=kAliHLTAnyDataType;
310 }
311
312 void AliHLTComponent::CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt) 
313 {
314   // see header file for function documentation
315   memcpy(&tgtdt.fID[0], &srcdt.fID[0], kAliHLTComponentDataTypefIDsize);
316   memcpy(&tgtdt.fOrigin[0], &srcdt.fOrigin[0], kAliHLTComponentDataTypefOriginSize);
317 }
318
319 void AliHLTComponent::SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin) 
320 {
321   // see header file for function documentation
322   tgtdt.fStructSize = sizeof(AliHLTComponentDataType);
323   memset(&tgtdt.fID[0], 0, kAliHLTComponentDataTypefIDsize);
324   memset(&tgtdt.fOrigin[0], 0, kAliHLTComponentDataTypefOriginSize);
325
326   if ((int)strlen(id)>kAliHLTComponentDataTypefIDsize) {
327     HLTWarning("data type id %s is too long, truncated to %d", id, kAliHLTComponentDataTypefIDsize);
328   }
329   strncpy(&tgtdt.fID[0], id, kAliHLTComponentDataTypefIDsize);
330
331   if ((int)strlen(origin)>kAliHLTComponentDataTypefOriginSize) {
332     HLTWarning("data type origin %s is too long, truncated to %d", origin, kAliHLTComponentDataTypefOriginSize);
333   }
334   strncpy(&tgtdt.fOrigin[0], origin, kAliHLTComponentDataTypefOriginSize);
335 }
336
337 void AliHLTComponent::FillEventData(AliHLTComponentEventData& evtData)
338 {
339   // see header file for function documentation
340   memset(&evtData, 0, sizeof(AliHLTComponentEventData));
341   evtData.fStructSize=sizeof(AliHLTComponentEventData);
342 }
343
344 void AliHLTComponent::PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt) 
345 {
346   // see header file for function documentation
347   TString msg;
348   msg.Form("AliHLTComponentDataType(%d): ID=\"", dt.fStructSize);
349   for ( int i = 0; i < kAliHLTComponentDataTypefIDsize; i++ ) {
350    if (dt.fID[i]!=0) msg+=dt.fID[i];
351    else msg+="\\0";
352   }
353   msg+="\" Origin=\"";
354   for ( int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++ ) {
355    if (dt.fOrigin[i]!=0) msg+=dt.fOrigin[i];
356    else msg+="\\0";
357   }
358   msg+="\"";
359   AliHLTLogging::Message(NULL, kHLTLogNone, NULL , NULL, msg.Data());
360 }
361
362 int AliHLTComponent::GetEventCount() const
363 {
364   // see header file for function documentation
365   return fEventCount;
366 }
367
368 int AliHLTComponent::IncrementEventCounter()
369 {
370   // see header file for function documentation
371   if (fEventCount>=0) fEventCount++;
372   return fEventCount;
373 }
374
375 int AliHLTComponent::GetNumberOfInputBlocks()
376 {
377   // see header file for function documentation
378   if (fpInputBlocks!=NULL) {
379     return fCurrentEventData.fBlockCnt;
380   }
381   return 0;
382 }
383
384 const TObject* AliHLTComponent::GetFirstInputObject(const AliHLTComponentDataType& dt,
385                                                     const char* classname,
386                                                     int bForce)
387 {
388   // see header file for function documentation
389   fSearchDataType=dt;
390   if (classname) fClassName=classname;
391   else fClassName.clear();
392   int idx=FindInputBlock(fSearchDataType, 0);
393   //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(dt).c_str());
394   TObject* pObj=NULL;
395   if (idx>=0) {
396     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
397       fCurrentInputBlock=idx;
398     } else {
399     }
400   }
401   return pObj;
402 }
403
404 const TObject* AliHLTComponent::GetFirstInputObject(const char* dtID, 
405                                                     const char* dtOrigin,
406                                                     const char* classname,
407                                                     int         bForce)
408 {
409   // see header file for function documentation
410   AliHLTComponentDataType dt;
411   SetDataType(dt, dtID, dtOrigin);
412   return GetFirstInputObject(dt, classname, bForce);
413 }
414
415 const TObject* AliHLTComponent::GetNextInputObject(int bForce)
416 {
417   // see header file for function documentation
418   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
419   //HLTDebug("found block %d when searching for data type %s", idx, DataType2Text(fSearchDataType).c_str());
420   TObject* pObj=NULL;
421   if (idx>=0) {
422     if ((pObj=GetInputObject(idx, fClassName.c_str(), bForce))!=NULL) {
423       fCurrentInputBlock=idx;
424     }
425   }
426   return pObj;
427 }
428
429 int AliHLTComponent::FindInputBlock(const AliHLTComponentDataType& dt, int startIdx)
430 {
431   // see header file for function documentation
432   int iResult=-ENOENT;
433   if (fpInputBlocks!=NULL) {
434     int idx=startIdx<0?0:startIdx;
435     for ( ; (UInt_t)idx<fCurrentEventData.fBlockCnt && iResult==-ENOENT; idx++) {
436       if (dt == kAliHLTAnyDataType || fpInputBlocks[idx].fDataType == dt) {
437         iResult=idx;
438       }
439     }
440   }
441   return iResult;
442 }
443
444 TObject* AliHLTComponent::CreateInputObject(int idx, int bForce)
445 {
446   // see header file for function documentation
447   TObject* pObj=NULL;
448   if (fpInputBlocks!=NULL) {
449     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
450       if (fpInputBlocks[idx].fPtr) {
451         AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)fpInputBlocks[idx].fPtr);
452         if (firstWord==fpInputBlocks[idx].fSize-sizeof(AliHLTUInt32_t)) {
453           //HLTDebug("create object from block %d size %d", idx, fpInputBlocks[idx].fSize);
454           AliHLTMessage msg(fpInputBlocks[idx].fPtr, fpInputBlocks[idx].fSize);
455           pObj=msg.ReadObject(msg.GetClass());
456           if (pObj && msg.GetClass()) {
457             //HLTDebug("object %p type %s created", pObj, msg.GetClass()->GetName());
458           } else {
459           }
460         } else {
461           //    } else if (bForce!=0) {
462           HLTError("size missmatch: block size %d, indicated %d", fpInputBlocks[idx].fSize, firstWord+sizeof(AliHLTUInt32_t));
463         }
464       } else {
465         HLTFatal("block descriptor empty");
466       }
467     } else {
468       HLTError("index %d out of range %d", idx, fCurrentEventData.fBlockCnt);
469     }
470   } else {
471     HLTError("no input blocks available");
472   }
473   
474   return pObj;
475 }
476
477 TObject* AliHLTComponent::GetInputObject(int idx, const char* classname, int bForce)
478 {
479   // see header file for function documentation
480   if (fpInputObjects==NULL) {
481     fpInputObjects=new TObjArray(fCurrentEventData.fBlockCnt);
482   }
483   TObject* pObj=NULL;
484   if (fpInputObjects) {
485     pObj=fpInputObjects->At(idx);
486     if (pObj==NULL) {
487       pObj=CreateInputObject(idx, bForce);
488       if (pObj) {
489         fpInputObjects->AddAt(pObj, idx);
490       }
491     }
492   } else {
493     HLTFatal("memory allocation failed: TObjArray of size %d", fCurrentEventData.fBlockCnt);
494   }
495   return pObj;
496 }
497
498 AliHLTComponentDataType AliHLTComponent::GetDataType(const TObject* pObject)
499 {
500   // see header file for function documentation
501   AliHLTComponentDataType dt=kAliHLTVoidDataType;
502   int idx=fCurrentInputBlock;
503   if (pObject) {
504     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
505     } else {
506       HLTError("unknown object %p", pObject);
507     }
508   }
509   if (idx>=0) {
510     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
511       dt=fpInputBlocks[idx].fDataType;
512     } else {
513       HLTFatal("severe internal error, index out of range");
514     }
515   }
516   return dt;
517 }
518
519 AliHLTUInt32_t AliHLTComponent::GetSpecification(const TObject* pObject)
520 {
521   // see header file for function documentation
522   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
523   int idx=fCurrentInputBlock;
524   if (pObject) {
525     if (fpInputObjects==NULL || (idx=fpInputObjects->IndexOf(pObject))>=0) {
526     } else {
527       HLTError("unknown object %p", pObject);
528     }
529   }
530   if (idx>=0) {
531     if ((UInt_t)idx<fCurrentEventData.fBlockCnt) {
532       iSpec=fpInputBlocks[idx].fSpecification;
533     } else {
534       HLTFatal("severe internal error, index out of range");
535     }
536   }
537   return iSpec;
538 }
539
540 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const AliHLTComponentDataType& dt)
541 {
542   // see header file for function documentation
543   fSearchDataType=dt;
544   fClassName.clear();
545   int idx=FindInputBlock(fSearchDataType, 0);
546   const AliHLTComponentBlockData* pBlock=NULL;
547   if (idx>=0) {
548     // check for fpInputBlocks pointer done in FindInputBlock
549     pBlock=&fpInputBlocks[idx];
550   }
551   return pBlock;
552 }
553
554 const AliHLTComponentBlockData* AliHLTComponent::GetFirstInputBlock(const char* dtID, 
555                                                                     const char* dtOrigin)
556 {
557   // see header file for function documentation
558   AliHLTComponentDataType dt;
559   SetDataType(dt, dtID, dtOrigin);
560   return GetFirstInputBlock(dt);
561 }
562
563 const AliHLTComponentBlockData* AliHLTComponent::GetNextInputBlock()
564 {
565   // see header file for function documentation
566   int idx=FindInputBlock(fSearchDataType, fCurrentInputBlock+1);
567   const AliHLTComponentBlockData* pBlock=NULL;
568   if (idx>=0) {
569     // check for fpInputBlocks pointer done in FindInputBlock
570     pBlock=&fpInputBlocks[idx];
571   }
572   return pBlock;
573 }
574
575 int AliHLTComponent::FindInputBlock(const AliHLTComponentBlockData* pBlock)
576 {
577   // see header file for function documentation
578   int iResult=-ENOENT;
579   if (fpInputBlocks!=NULL) {
580     if (pBlock) {
581       if (pBlock>=fpInputBlocks && pBlock<fpInputBlocks+fCurrentEventData.fBlockCnt) {
582         iResult=(int)(pBlock-fpInputBlocks);
583       }
584     } else {
585       iResult=-EINVAL;
586     }
587   }
588   return iResult;
589 }
590
591 AliHLTUInt32_t AliHLTComponent::GetSpecification(const AliHLTComponentBlockData* pBlock)
592 {
593   // see header file for function documentation
594   AliHLTUInt32_t iSpec=kAliHLTVoidDataSpec;
595   int idx=fCurrentInputBlock;
596   if (pBlock) {
597     if (fpInputObjects==NULL || (idx=FindInputBlock(pBlock))>=0) {
598     } else {
599       HLTError("unknown Block %p", pBlock);
600     }
601   }
602   if (idx>=0) {
603     // check for fpInputBlocks pointer done in FindInputBlock
604     iSpec=fpInputBlocks[idx].fSpecification;
605   }
606   return iSpec;
607 }
608
609 int AliHLTComponent::PushBack(TObject* pObject, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
610 {
611   // see header file for function documentation
612   int iResult=0;
613   if (pObject) {
614     AliHLTMessage msg(kMESS_OBJECT);
615     msg.WriteObject(pObject);
616     Int_t iMsgLength=msg.Length();
617     if (iMsgLength>0) {
618       msg.SetLength(); // sets the length to the first (reserved) word
619       iResult=InsertOutputBlock(msg.Buffer(), iMsgLength, dt, spec);
620       if (iResult>=0) {
621         //HLTDebug("object %s (%p) inserted to output", pObject->ClassName(), pObject);
622       }
623     } else {
624       HLTError("object serialization failed for object %p", pObject);
625       iResult=-ENOMSG;
626     }
627   } else {
628     iResult=-EINVAL;
629   }
630   return iResult;
631 }
632
633 int AliHLTComponent::PushBack(TObject* pObject, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
634 {
635   // see header file for function documentation
636   AliHLTComponentDataType dt;
637   SetDataType(dt, dtID, dtOrigin);
638   return PushBack(pObject, dt, spec);
639 }
640
641 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
642 {
643   // see header file for function documentation
644   return InsertOutputBlock(pBuffer, iSize, dt, spec);
645 }
646
647 int AliHLTComponent::PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin, AliHLTUInt32_t spec)
648 {
649   // see header file for function documentation
650   AliHLTComponentDataType dt;
651   SetDataType(dt, dtID, dtOrigin);
652   return PushBack(pBuffer, iSize, dt, spec);
653 }
654
655 int AliHLTComponent::InsertOutputBlock(void* pBuffer, int iSize, const AliHLTComponentDataType& dt, AliHLTUInt32_t spec)
656 {
657   // see header file for function documentation
658   int iResult=0;
659   if (pBuffer) {
660     if (fpOutputBuffer && (fOutputBufferSize-fOutputBufferFilled)) {
661       AliHLTUInt8_t* pTgt=fpOutputBuffer+fOutputBufferFilled;
662       AliHLTComponentBlockData bd;
663       FillBlockData( bd );
664       bd.fOffset        = fOutputBufferFilled;
665       bd.fPtr           = pTgt;
666       bd.fSize          = iSize;
667       bd.fDataType      = dt;
668       bd.fSpecification = spec;
669       if (pBuffer!=NULL && pBuffer!=pTgt) {
670         memcpy(pTgt, pBuffer, iSize);
671         //AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer); 
672         //HLTDebug("copy %d bytes from %p to output buffer %p, first word %#x", iSize, pBuffer, pTgt, firstWord);
673       }
674       fOutputBufferFilled+=bd.fSize;
675       fOutputBlocks.push_back( bd );
676       //HLTDebug("buffer inserted to output: size %d data type %s spec %#x", iSize, DataType2Text(dt).c_str(), spec);
677     } else {
678       if (fpOutputBuffer) {
679         HLTError("too little space in output buffer: %d, required %d", fOutputBufferSize-fOutputBufferFilled, iSize);
680       } else {
681         HLTError("output buffer not available");
682       }
683       iResult=-ENOSPC;
684     }
685   } else {
686     iResult=-EINVAL;
687   }
688   return iResult;
689 }
690
691 int AliHLTComponent::CreateEventDoneData(AliHLTComponentEventDoneData edd)
692 {
693   // see header file for function documentation
694   int iResult=-ENOSYS;
695   //#warning  function not yet implemented
696   HLTWarning("function not yet implemented");
697   return iResult;
698 }
699
700 int AliHLTComponent::ProcessEvent( const AliHLTComponentEventData& evtData,
701                                    const AliHLTComponentBlockData* blocks, 
702                                    AliHLTComponentTriggerData& trigData,
703                                    AliHLTUInt8_t* outputPtr, 
704                                    AliHLTUInt32_t& size,
705                                    AliHLTUInt32_t& outputBlockCnt, 
706                                    AliHLTComponentBlockData*& outputBlocks,
707                                    AliHLTComponentEventDoneData*& edd )
708 {
709   // see header file for function documentation
710   int iResult=0;
711   fCurrentEvent=evtData.fEventID;
712   fCurrentEventData=evtData;
713   fpInputBlocks=blocks;
714   fCurrentInputBlock=-1;
715   fSearchDataType=kAliHLTAnyDataType;
716   fpOutputBuffer=outputPtr;
717   fOutputBufferSize=size;
718   fOutputBufferFilled=0;
719   fOutputBlocks.clear();
720   
721   vector<AliHLTComponentBlockData> blockData;
722   iResult=DoProcessing(evtData, blocks, trigData, outputPtr, size, blockData, edd);
723   if (iResult>=0) {
724     if (fOutputBlocks.size()>0) {
725       //HLTDebug("got %d block(s) via high level interface", fOutputBlocks.size());
726       if (blockData.size()>0) {
727         HLTError("low level and high interface must not be mixed; use PushBack methods to insert data blocks");
728         iResult=-EFAULT;
729       } else {
730         iResult=MakeOutputDataBlockList(fOutputBlocks, &outputBlockCnt, &outputBlocks);
731         size=fOutputBufferFilled;
732       }
733     } else {
734       iResult=MakeOutputDataBlockList(blockData, &outputBlockCnt, &outputBlocks);
735     }
736     if (iResult<0) {
737       HLTFatal("component %s (%p): can not convert output block descriptor list", GetComponentID(), this);
738     }
739   }
740   if (iResult<0) {
741     outputBlockCnt=0;
742     outputBlocks=NULL;
743   }
744   IncrementEventCounter();
745   return iResult;
746 }
747