bugfix in high level interface: GetFirst/NextObject/Block
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTComponent.h
1 //-*- Mode: C++ -*-
2 // @(#) $Id$
3
4 #ifndef ALIHLTCOMPONENT_H
5 #define ALIHLTCOMPONENT_H
6 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
7  * See cxx source for full Copyright notice                               */
8
9 /** @file   AliHLTComponent.h
10     @author Matthias Richter, Timm Steinbeck
11     @date   
12     @brief  Base class declaration for HLT components. 
13     @note   The class is both used in Online (PubSub) and Offline (AliRoot)
14             context
15
16 // see below for class documentation
17 // or
18 // refer to README to build package
19 // or
20 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
21                                                                           */
22 /**
23  * @defgroup alihlt_component Component handling of the HLT module
24  * This section describes the the component handling for the HLT module.
25  */
26
27 #include <vector>
28 #include <string>
29 #include "AliHLTLogging.h"
30 #include "AliHLTDataTypes.h"
31 //#include "AliHLTDefinitions.h"
32
33 /* Matthias Dec 2006
34  * The names have been changed for Aliroot's coding conventions sake
35  * The old names are defined for backward compatibility with the 
36  * stand alone SampleLib package
37  */
38 typedef AliHLTComponentLogSeverity AliHLTComponent_LogSeverity;
39 typedef AliHLTComponentEventData AliHLTComponent_EventData;
40 typedef AliHLTComponentShmData AliHLTComponent_ShmData;
41 typedef AliHLTComponentDataType AliHLTComponent_DataType;
42 typedef AliHLTComponentBlockData AliHLTComponent_BlockData;
43 typedef AliHLTComponentTriggerData AliHLTComponent_TriggerData;
44 typedef AliHLTComponentEventDoneData AliHLTComponent_EventDoneData;
45
46 class AliHLTComponentHandler;
47 class TObjArray;
48 class TStopwatch;
49
50 /**
51  * @class AliHLTComponent
52  * Base class of HLT data processing components.
53  * The class provides a common interface for HLT data processing components.
54  * The interface can be accessed from the online HLT framework or the AliRoot
55  * offline analysis framework.
56  * @section alihltcomponent-properties Component identification and properties
57  * Each component must provide a unique ID, input and output data type indications,
58  * and a spawn function.
59  * @subsection alihltcomponent-req-methods Required property methods
60  * - @ref GetComponentID
61  * - @ref GetInputDataTypes (see @ref alihltcomponent-type for default
62  *   implementations.)
63  * - @ref GetOutputDataType (see @ref alihltcomponent-type for default
64  *   implementations.)
65  * - @ref GetOutputDataSize (see @ref alihltcomponent-type for default
66  *   implementations.)
67  * - @ref Spawn
68  *
69  * @subsection alihltcomponent-opt-mehods Optional handlers
70  * - @ref DoInit
71  * - @ref DoDeinit
72  *
73  * @subsection alihltcomponent-processing-mehods Data processing
74  * 
75  * 
76  * @subsection alihltcomponent-type Component type
77  * Components can be of type
78  * - @ref kSource     components which only produce data 
79  * - @ref kProcessor  components which consume and produce data
80  * - @ref kSink       components which only consume data
81  *
82  * where data production and consumption refer to the analysis data stream. In
83  * order to indicate the type, a child component can overload the
84  * @ref GetComponentType function.
85  * @subsubsection alihltcomponent-type-std Standard implementations
86  * Components in general do not need to implement this function, standard
87  * implementations of the 3 types are available:
88  * - AliHLTDataSource for components of type @ref kSource <br>
89  *   All types of data sources can inherit from AliHLTDataSource and must
90  *   implement the @ref AliHLTDataSource::GetEvent method. The class
91  *   also implements a standard method for @ref GetInputDataTypes.
92  *   
93  * - AliHLTProcessor for components of type @ref kProcessor <br>
94  *   All types of data processors can inherit from AliHLTDataSource and must
95  *   implement the @ref AliHLTProcessor::DoEvent method.
96  *
97  * - AliHLTDataSink for components of type @ref kSink <br>
98  *   All types of data processors can inherit from AliHLTDataSource and must
99  *   implement the @ref AliHLTDataSink::DumpEvent method. The class
100  *   also implements a standard method for @ref GetOutputDataType and @ref
101  *   GetOutputDataSize.
102  *
103  * @subsection alihltcomponent-environment Running environment
104  *
105  * In order to adapt to different environments (on-line/off-line), the component
106  * gets an environment structure with function pointers. The base class provides
107  * member functions for those environment dependend functions. The member 
108  * functions are used by the component implementation and are re-mapped to the
109  * corresponding functions.
110  * @section alihltcomponent-interfaces Component interfaces
111  * Each of the 3 standard component base classes AliHLTProcessor, AliHLTDataSource
112  * and AliHLTDataSink provides it's own processing method (see
113  * @ref alihltcomponent-type-std), which splits into a high and a low-level
114  * method. For the @ref alihltcomponent-low-level-interface, all parameters are
115  * shipped as function arguments, the component is supposed to dump data to the
116  * output buffer and handle all block descriptors. 
117  * The @ref alihltcomponent-high-level-interface is the standard processing
118  * method and will be used whenever the low-level method is not overloaded.
119  *
120  * @subsection alihltcomponent-high-level-interface High-level interface
121  * The high-level component interface provides functionality to exchange ROOT
122  * structures between components. In contrast to the 
123  * @ref alihltcomponent-low-level-interface, a couple of functions can be used
124  * to access data blocks of the input stream
125  * and send data blocks or ROOT TObject's to the output stream. The functionality
126  * is hidden from the user and is implemented by using ROOT's TMessage class.
127  *
128  * @subsubsection alihltcomponent-high-level-int-methods Interface methods
129  * The interface provides a couple of methods in order to get objects from the
130  * input, data blocks (non TObject) from the input, and to push back objects and
131  * data blocks to the output. For convenience there are several functions of 
132  * identical name (and similar behavior) with different parameters defined.
133  * Please refer to the function documentation.
134  * - @ref GetNumberOfInputBlocks <br>
135  *        return the number of data blocks in the input stream
136  * - @ref GetFirstInputObject <br>
137  *        get the first object of a specific data type
138  * - @ref GetNextInputObject <br>
139  *        get the next object of same data type as last GetFirstInputObject/Block call
140  * - @ref GetFirstInputBlock <br>
141  *        get the first block of a specific data type
142  * - @ref GetNextInputBlock <br>
143  *        get the next block of same data type as last GetFirstInputBlock/Block call
144  * - @ref PushBack <br>
145  *        insert an object or data buffer into the output
146  * - @ref CreateEventDoneData <br>
147  *        add event information to the output
148  * 
149  * In addition, the processing methods are simplified a bit by cutting out most of
150  * the parameters. The component implementation 
151  * @see AliHLTProcessor AliHLTDataSource AliHLTDataSink
152  *
153  * \em IMPORTANT: objects and block descriptors provided by the high-level interface
154  *  <b>MUST NOT BE DELETED</b> by the caller.
155  *
156  * @subsubsection alihltcomponent-high-level-int-guidelines High-level interface guidelines
157  * - Structures must inherit from the ROOT object base class TObject in order be 
158  * transported by the transportation framework.
159  * - all pointer members must be transient (marked <tt>//!</tt> behind the member
160  * definition), i.e. will not be stored/transported, or properly marked
161  * (<tt>//-></tt>) in order to call the streamer of the object the member is pointing
162  * to. The latter is not recomended. Structures to be transported between components
163  * should be streamlined.
164  * - no use of stl vectors/strings, use appropriate ROOT classes instead 
165  * 
166  * @subsection alihltcomponent-low-level-interface Low-level interface
167  * The low-level component interface consists of the specific data processing
168  * methods for @ref AliHLTProcessor, @ref AliHLTDataSource, and @ref AliHLTDataSink.
169  * - @ref AliHLTProcessor::DoEvent
170  * - @ref AliHLTDataSource::GetEvent
171  * - @ref AliHLTDataSink::DumpEvent
172  * 
173  * 
174  * @section alihltcomponent-handling Component handling 
175  * The handling of HLT analysis components is carried out by the AliHLTComponentHandler.
176  * Component are registered automatically at load-time of the component shared library
177  * under the following suppositions:
178  * - the component library has to be loaded from the AliHLTComponentHandler using the
179  *   @ref AliHLTComponentHandler::LoadLibrary method.
180  * - the component implementation defines one global object (which is generated
181  *   when the library is loaded)
182  *
183  * @subsection alihltcomponent-design-rules General design considerations
184  * The analysis code should be implemented in one or more destict class(es). A 
185  * \em component should be implemented which interface the destict analysis code to the
186  * component interface. This component generates the analysis object dynamically. <br>
187  *
188  * Assume you have an implemetation <tt> AliHLTDetMyAnalysis </tt>, another class <tt>
189  * AliHLTDetMyAnalysisComponent </tt> contains:
190  * <pre>
191  * private:
192  *   AliHLTDetMyAnalysis* fMyAnalysis;  //!
193  * </pre>
194  * The object should then be instantiated in the DoInit handler of 
195  * <tt>AliHLTDetMyAnalysisComponent </tt>, and cleaned in the DoDeinit handler.
196  *
197  * Further rules:
198  * - avoid big static arrays in the component, allocate the memory at runtime
199  *
200  * @ingroup alihlt_component
201  * @section alihltcomponent-members Class members
202  */
203 class AliHLTComponent : public AliHLTLogging {
204  public:
205   /** standard constructor */
206   AliHLTComponent();
207   /** not a valid copy constructor, defined according to effective C++ style */
208   AliHLTComponent(const AliHLTComponent&);
209   /** not a valid assignment op, but defined according to effective C++ style */
210   AliHLTComponent& operator=(const AliHLTComponent&);
211   /** standard destructor */
212   virtual ~AliHLTComponent();
213
214   /** component type definitions */
215   enum TComponentType { kUnknown=0, kSource=1, kProcessor=2, kSink=3 };
216
217   /**
218    * Init function to prepare data processing.
219    * Initialization of common data structures for a sequence of events.
220    * The call is redirected to the internal method @ref DoInit which can be
221    * overridden by the child class.<br>
222    * During Init also the environment structure is passed to the component.
223    * @param environ        environment pointer with environment dependend function
224    *                       calls
225    * @param environParam   additionel parameter for function calls, the pointer
226    *                       is passed as it is
227    * @param argc           size of the argument array
228    * @param argv           agument array for component initialization
229    */
230   virtual int Init( AliHLTComponentEnvironment* environ, void* environParam, int argc, const char** argv );
231
232   /**
233    * Clean-up function to terminate data processing.
234    * Clean-up of common data structures after data processing.
235    * The call is redirected to the internal method @ref DoDeinit which can be
236    * overridden by the child class.
237    */
238   virtual int Deinit();
239
240   /**
241    * Processing of one event.
242    * The method is the entrance of the event processing. The parameters are
243    * cached for uses with the high-level interface and the DoProcessing
244    * implementation is called.
245    *
246    * @param evtData
247    * @param blocks
248    * @param trigData
249    * @param outputPtr
250    * @param size
251    * @param outputBlockCnt  out: size of the output block array, set by the component
252    * @param outputBlocks    out: the output block array is allocated internally
253    * @param edd
254    * @return neg. error code if failed
255    */
256   int ProcessEvent( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, 
257                             AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, 
258                             AliHLTUInt32_t& size, AliHLTUInt32_t& outputBlockCnt, 
259                             AliHLTComponentBlockData*& outputBlocks,
260                             AliHLTComponentEventDoneData*& edd );
261
262   /**
263    * Internal processing of one event.
264    * The method is pure virtual and implemented by the child classes 
265    * - @ref AliHLTProcessor
266    * - @ref AliHLTDataSource
267    * - @ref AliHLTDataSink
268    *
269    * @param evtData
270    * @param blocks
271    * @param trigData
272    * @param outputPtr
273    * @param size
274    * @param outputBlocks    out: the output block array is allocated internally
275    * @param edd
276    * @return neg. error code if failed
277    */
278   virtual int DoProcessing( const AliHLTComponentEventData& evtData, const AliHLTComponentBlockData* blocks, 
279                             AliHLTComponentTriggerData& trigData, AliHLTUInt8_t* outputPtr, 
280                             AliHLTUInt32_t& size,
281                             vector<AliHLTComponentBlockData>& outputBlocks,
282                             AliHLTComponentEventDoneData*& edd ) = 0;
283
284   // Information member functions for registration.
285
286   /**
287    * Get the type of the component.
288    * The function is pure virtual and must be implemented by the child class.
289    * @return component type id
290    */
291   virtual TComponentType GetComponentType() = 0; // Source, sink, or processor
292
293   /**
294    * Get the id of the component.
295    * Each component is identified by a unique id.
296    * The function is pure virtual and must be implemented by the child class.
297    * @return component id (string)
298    */
299   virtual const char* GetComponentID() = 0;
300
301   /**
302    * Get the input data types of the component.
303    * The function is pure virtual and must be implemented by the child class.
304    * @return list of data types in the vector reference
305    */
306   virtual void GetInputDataTypes( vector<AliHLTComponentDataType>& ) = 0;
307
308   /**
309    * Get the output data type of the component.
310    * The function is pure virtual and must be implemented by the child class.
311    * @return output data type
312    */
313   virtual AliHLTComponentDataType GetOutputDataType() = 0;
314
315   /**
316    * Get a ratio by how much the data volume is shrinked or enhanced.
317    * The function is pure virtual and must be implemented by the child class.
318    * @param constBase        <i>return</i>: additive part, independent of the
319    *                                   input data volume  
320    * @param inputMultiplier  <i>return</i>: multiplication ratio
321    * @return values in the reference variables
322    */
323   virtual void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) = 0;
324
325   /**
326    * Spawn function.
327    * Each component must implement a spawn function to create a new instance of 
328    * the class. Basically the function must return <i>new <b>my_class_name</b></i>.
329    * @return new class instance
330    */
331   virtual AliHLTComponent* Spawn() = 0;
332
333   /**
334    * Find matching data types between this component and a consumer component.
335    * Currently, a component can produce only one type of data. This restriction is most
336    * likely to be abolished in the future.
337    * @param pConsumer a component and consumer of the data produced by this component
338    * @param tgtList   reference to a vector list to receive the matching data types.
339    * @return >= 0 success, neg. error code if failed
340    */ 
341   int FindMatchingDataTypes(AliHLTComponent* pConsumer, vector<AliHLTComponentDataType>* tgtList);
342  
343   /**
344    * Set the global component handler.
345    * The static method is needed for the automatic registration of components. 
346    */
347   static int SetGlobalComponentHandler(AliHLTComponentHandler* pCH, int bOverwrite=0);
348
349   /**
350    * Clear the global component handler.
351    * The static method is needed for the automatic registration of components. 
352    */
353   static int UnsetGlobalComponentHandler();
354
355   /**
356    * Helper function to convert the data type to a string.
357    */
358   static string DataType2Text( const AliHLTComponentDataType& type );
359
360   /**
361    * Helper function to print content of data type.
362    */
363   void PrintDataTypeContent(AliHLTComponentDataType& dt, const char* format=NULL) const;
364
365   /**
366    * helper function to initialize AliHLTComponentEventData structure
367    */
368   static void FillEventData(AliHLTComponentEventData& evtData);
369
370   /**
371    * Print info on an AliHLTComponentDataType structure
372    * This is just a helper function to examine an @ref AliHLTComponentDataType
373    * structur.
374    */
375   void PrintComponentDataTypeInfo(const AliHLTComponentDataType& dt);
376
377   /**
378    * Stopwatch type for benchmarking.
379    */
380   enum AliHLTStopwatchType {
381     /** total time for event processing */
382     kSWBase,
383     /** detector algorithm w/o interface callbacks */
384     kSWDA,
385     /** data sources */
386     kSWInput,
387     /** data sinks */
388     kSWOutput,
389     /** number of types */
390     kSWTypeCount
391   };
392
393   /**
394    * Helper class for starting and stopping a stopwatch.
395    * The guard can be used by instantiating an object in a function. The
396    * specified stopwatch is started and the previous stopwatch put on
397    * hold. When the function is terminated, the object is deleted automatically
398    * deleted, stopping the stopwatch and starting the one on hold.<br>
399    * \em IMPORTANT: never create dynamic objects from this guard as this violates
400    * the idea of a guard.
401    */
402   class AliHLTStopwatchGuard {
403   public:
404     /** standard constructor (not for use) */
405     AliHLTStopwatchGuard();
406     /** constructor */
407     AliHLTStopwatchGuard(TStopwatch* pStart);
408     /** copy constructor (not for use) */
409     AliHLTStopwatchGuard(AliHLTStopwatchGuard&);
410     /** destructor */
411     ~AliHLTStopwatchGuard();
412
413   private:
414     /**
415      * Hold the previous guard for the existence of this guard.
416      * Checks whether this guard controls a new stopwatch. In that case, the
417      * previous guard and its stopwatch are put on hold.
418      * @param pSucc        instance of the stopwatch of the new guard
419      * @return    1 if pSucc is a different stopwatch which should
420      *            be started<br>
421      *            0 if it controls the same stopwatch
422      */
423     int Hold(TStopwatch* pSucc);
424
425     /**
426      * Resume the previous guard.
427      * Checks whether the peceeding guard controls a different stopwatch. In that
428      * case, the its stopwatch is resumed.
429      * @param pSucc        instance of the stopwatch of the new guard
430      * @return    1 if pSucc is a different stopwatch which should
431      *            be stopped<br>
432      *            0 if it controls the same stopwatch
433      */
434     int Resume(TStopwatch* pSucc);
435
436     /** the stopwatch controlled by this guard */
437     TStopwatch* fpStopwatch;                                                //!transient
438
439     /** previous stopwatch guard, put on hold during existence of the guard */
440     AliHLTStopwatchGuard* fpPrec;                                           //!transient
441
442     /** active stopwatch guard */
443     static AliHLTStopwatchGuard* fgpCurrent;                                //!transient
444   };
445
446   /**
447    * Set a stopwatch for a given purpose.
448    * @param pSW         stopwatch object
449    * @param type        type of the stopwatch
450    */
451   int SetStopwatch(TObject* pSW, AliHLTStopwatchType type=kSWBase);
452
453   /**
454    * Init a set of stopwatches.
455    * @param pStopwatches object array of stopwatches
456    */
457   int SetStopwatches(TObjArray* pStopwatches);
458
459  protected:
460
461   /**
462    * Fill AliHLTComponentBlockData structure with default values.
463    * @param blockData   reference to data structure
464    */
465   void FillBlockData( AliHLTComponentBlockData& blockData ) const;
466
467   /**
468    * Fill AliHLTComponentShmData structure with default values.
469    * @param shmData   reference to data structure
470    */
471   void FillShmData( AliHLTComponentShmData& shmData ) const;
472
473   /**
474    * Fill AliHLTComponentDataType structure with default values.
475    * @param dataType   reference to data structure
476    */
477   void FillDataType( AliHLTComponentDataType& dataType ) const;
478   
479   /**
480    * Copy data type structure
481    * Copies the value an AliHLTComponentDataType structure to another one
482    * @param[out] tgtdt   target structure
483    * @param[in] srcdt   source structure
484    */
485   void CopyDataType(AliHLTComponentDataType& tgtdt, const AliHLTComponentDataType& srcdt);
486
487   /**
488    * Set the ID and Origin of an AliHLTComponentDataType structure.
489    * The function sets the fStructureSize member and copies the strings
490    * to the ID and Origin. Only characters from the valid part of the string
491    * are copied, the rest is fille with 0's.
492    * Please note that the fID and fOrigin members are not strings, just arrays of
493    * chars of size @ref kAliHLTComponentDataTypefIDsize and
494    * @ref kAliHLTComponentDataTypefOriginSize respectively and not necessarily with
495    * a terminating zero.
496    * @param tgtdt   target data type structure
497    * @param id      ID string
498    * @param origin  Origin string
499    */
500   void SetDataType(AliHLTComponentDataType& tgtdt, const char* id, const char* origin);
501
502   /**
503    * Default method for the internal initialization.
504    * The method is called by @ref Init
505    */
506   virtual int DoInit( int argc, const char** argv );
507
508   /**
509    * Default method for the internal clean-up.
510    * The method is called by @ref Deinit
511    */
512   virtual int DoDeinit();
513
514   /**
515    * General memory allocation method.
516    * All memory which is going to be used 'outside' of the interface must
517    * be provided by the framework (online or offline).
518    * The method is redirected to a function provided by the current
519    * framework. Function pointers are transferred via the @ref
520    * AliHLTComponentEnvironment structure.
521    */
522   void* AllocMemory( unsigned long size );
523
524   /**
525    * Helper function to create a monolithic BlockData description block out
526    * of a list BlockData descriptors.
527    * For convenience, inside the interface vector lists are used, to make the
528    * interface pure C style, monilithic blocks must be exchanged. 
529    * The method is redirected to a function provided by the current
530    * framework. Function pointers are transferred via the @ref
531    * AliHLTComponentEnvironment structure.
532    */
533   int MakeOutputDataBlockList( const vector<AliHLTComponentBlockData>& blocks, AliHLTUInt32_t* blockCount,
534                                AliHLTComponentBlockData** outputBlocks );
535
536   /**
537    * Fill the EventDoneData structure.
538    * The method is redirected to a function provided by the current
539    * framework. Function pointers are transferred via the @ref
540    * AliHLTComponentEnvironment structure.
541    */
542   int GetEventDoneData( unsigned long size, AliHLTComponentEventDoneData** edd );
543
544   /**
545    * Helper function to convert the data type to a string.
546    */
547   void DataType2Text(const AliHLTComponentDataType& type, char output[kAliHLTComponentDataTypefIDsize+kAliHLTComponentDataTypefOriginSize+2]) const;
548
549   /**
550    * Get event number.
551    * @return value of the internal event counter
552    */
553   int GetEventCount() const;
554
555   /**
556    * Get the number of input blocks.
557    * @return number of input blocks
558    */
559   int GetNumberOfInputBlocks() const;
560
561   /**
562    * Get the first object of a specific data type from the input data.
563    * The hight-level methods provide functionality to transfer ROOT data
564    * structures which inherit from TObject.
565    * The method looks for the first ROOT object of type dt in the input stream.
566    * If also the class name is provided, the object is checked for the right
567    * class type. The input data block needs a certain structure, namely the 
568    * buffer size as first word. If the cross check fails, the retrieval is
569    * silently abondoned, unless the \em bForce parameter is set.<br>
570    * \em Note: THE OBJECT MUST NOT BE DELETED by the caller.
571    * @param dt          data type of the object
572    * @param classname   class name of the object
573    * @param bForce      force the retrieval of an object, error messages
574    *                    are suppressed if \em bForce is not set
575    * @return pointer to @ref TObject, NULL if no objects of specified type
576    *         available
577    */
578   const TObject* GetFirstInputObject(const AliHLTComponentDataType& dt=kAliHLTAnyDataType,
579                                      const char* classname=NULL,
580                                      int bForce=0);
581
582   /**
583    * Get the first object of a specific data type from the input data.
584    * The hight-level methods provide functionality to transfer ROOT data
585    * structures which inherit from TObject.
586    * The method looks for the first ROOT object of type specified by the ID and 
587    * Origin strings in the input stream.
588    * If also the class name is provided, the object is checked for the right
589    * class type. The input data block needs a certain structure, namely the 
590    * buffer size as first word. If the cross check fails, the retrieval is
591    * silently abondoned, unless the \em bForce parameter is set.<br>
592    * \em Note: THE OBJECT MUST NOT BE DELETED by the caller.
593    * @param dtID        data type ID of the object
594    * @param dtOrigin    data type origin of the object
595    * @param classname   class name of the object
596    * @param bForce      force the retrieval of an object, error messages
597    *                    are suppressed if \em bForce is not set
598    * @return pointer to @ref TObject, NULL if no objects of specified type
599    *         available
600    */
601   const TObject* GetFirstInputObject(const char* dtID, 
602                                      const char* dtOrigin,
603                                      const char* classname=NULL,
604                                      int bForce=0);
605
606   /**
607    * Get the next object of a specific data type from the input data.
608    * The hight-level methods provide functionality to transfer ROOT data
609    * structures which inherit from TObject.
610    * The method looks for the next ROOT object of type and class specified
611    * to the previous @ref GetFirstInputObject call.<br>
612    * \em Note: THE OBJECT MUST NOT BE DELETED by the caller.
613    * @param bForce      force the retrieval of an object, error messages
614    *                    are suppressed if \em bForce is not set
615    * @return pointer to @ref TObject, NULL if no more objects available
616    */
617   const TObject* GetNextInputObject(int bForce=0);
618
619   /**
620    * Get data type of an input block.
621    * Get data type of the object previously fetched via
622    * GetFirstInputObject/NextInputObject or the last one if no object
623    * specified.
624    * @param pObject     pointer to TObject
625    * @return data specification, kAliHLTVoidDataSpec if failed
626    */
627   AliHLTComponentDataType GetDataType(const TObject* pObject=NULL);
628
629   /**
630    * Get data specification of an input block.
631    * Get data specification of the object previously fetched via
632    * GetFirstInputObject/NextInputObject or the last one if no object
633    * specified.
634    * @param pObject     pointer to TObject
635    * @return data specification, kAliHLTVoidDataSpec if failed
636    */
637   AliHLTUInt32_t GetSpecification(const TObject* pObject=NULL);
638
639   /**
640    * Get the first block of a specific data type from the input data.
641    * The method looks for the first block of type dt in the input stream. It is intended
642    * to be used within the high-level interface.<br>
643    * \em Note: THE BLOCK DESCRIPTOR MUST NOT BE DELETED by the caller.
644    * @param dt          data type of the block
645    * @return pointer to @ref AliHLTComponentBlockData
646    */
647   const AliHLTComponentBlockData* GetFirstInputBlock(const AliHLTComponentDataType& dt=kAliHLTAnyDataType);
648
649   /**
650    * Get the first block of a specific data type from the input data.
651    * The method looks for the first block of type specified by the ID and 
652    * Origin strings in the input stream.  It is intended
653    * to be used within the high-level interface.<br>
654    * \em Note: THE BLOCK DESCRIPTOR MUST NOT BE DELETED by the caller.
655    * @param dtID        data type ID of the block
656    * @param dtOrigin    data type origin of the block
657    * @return pointer to @ref AliHLTComponentBlockData
658    */
659   const AliHLTComponentBlockData* GetFirstInputBlock(const char* dtID, 
660                                                       const char* dtOrigin);
661
662   /**
663    * Get input block by index.<br>
664    * \em Note: THE BLOCK DESCRIPTOR MUST NOT BE DELETED by the caller.
665    * @return pointer to AliHLTComponentBlockData, NULL if index out of range
666    */
667   const AliHLTComponentBlockData* GetInputBlock(int index);
668
669   /**
670    * Get the next block of a specific data type from the input data.
671    * The method looks for the next block  of type and class specified
672    * to the previous @ref GetFirstInputBlock call.
673    * To be used within the high-level interface.<br>
674    * \em Note: THE BLOCK DESCRIPTOR MUST NOT BE DELETED by the caller.
675    */
676   const AliHLTComponentBlockData* GetNextInputBlock();
677
678   /**
679    * Get data specification of an input block.
680    * Get data specification of the input bblock previously fetched via
681    * GetFirstInputObject/NextInputObject or the last one if no block
682    * specified.
683    * @param pBlock     pointer to input block
684    * @return data specification, kAliHLTVoidDataSpec if failed
685    */
686   AliHLTUInt32_t GetSpecification(const AliHLTComponentBlockData* pBlock=NULL);
687
688   /**
689    * Insert an object into the output.
690    * @param pObject     pointer to root object
691    * @param dt          data type of the object
692    * @param spec        data specification
693    * @return neg. error code if failed 
694    */
695   int PushBack(TObject* pObject, const AliHLTComponentDataType& dt, 
696                AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
697
698   /**
699    * Insert an object into the output.
700    * @param pObject     pointer to root object
701    * @param dtID        data type ID of the object
702    * @param dtOrigin    data type origin of the object
703    * @param spec        data specification
704    * @return neg. error code if failed 
705    */
706   int PushBack(TObject* pObject, const char* dtID, const char* dtOrigin,
707                AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
708
709   /**
710    * Insert an object into the output.
711    * @param pBuffer     pointer to buffer
712    * @param iSize       size of the buffer
713    * @param dt          data type of the object
714    * @param spec        data specification
715    * @return neg. error code if failed 
716    */
717   int PushBack(void* pBuffer, int iSize, const AliHLTComponentDataType& dt,
718                AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
719
720   /**
721    * Insert an object into the output.
722    * @param pBuffer     pointer to buffer
723    * @param iSize       size of the buffer
724    * @param dtID        data type ID of the object
725    * @param dtOrigin    data type origin of the object
726    * @param spec        data specification
727    * @return neg. error code if failed 
728    */
729   int PushBack(void* pBuffer, int iSize, const char* dtID, const char* dtOrigin,
730                AliHLTUInt32_t spec=kAliHLTVoidDataSpec);
731
732   /**
733    * Estimate size of a TObject
734    * @param pObject
735    * @return buffer size in byte
736    */
737   int EstimateObjectSize(TObject* pObject) const;
738
739   /**
740    * Insert event-done data information into the output.
741    * @param edd          event-done data information
742    */
743   int CreateEventDoneData(AliHLTComponentEventDoneData edd);
744
745  private:
746   /**
747    * Increment the internal event counter.
748    * To be used by the friend classes AliHLTProcessor, AliHLTDataSource
749    * and AliHLTDataSink.
750    * @return new value of the internal event counter
751    * @internal
752    */
753   int IncrementEventCounter();
754
755   /**
756    * Find the first input block of specified data type beginning at index.
757    * Input blocks containing a TObject have the size of the object as an
758    * unsigned 32 bit number in the first 4 bytes. This has to match the block
759    * size minus 4.
760    * @param dt          data type
761    * @param startIdx    index to start the search
762    * @param bObject     check if this is an object
763    * @return index of the block, -ENOENT if no block found
764    *
765    * @internal
766    */
767   int FindInputBlock(const AliHLTComponentDataType& dt, int startIdx=-1, int bObject=0) const;
768
769   /**
770    * Get index in the array of input bocks.
771    * Calculate index and check integrety of a block data structure pointer.
772    * @param pBlock      pointer to block data
773    * @return index of the block, -ENOENT if no block found
774    *
775    * @internal
776    */
777   int FindInputBlock(const AliHLTComponentBlockData* pBlock) const;
778
779   /**
780    * Create an object from a specified input block.
781    * @param idx         index of the input block
782    * @param bForce      force the retrieval of an object, error messages
783    *                    are suppressed if \em bForce is not set
784    * @return pointer to TObject, caller must delete the object after use
785    *
786    * @internal
787    */
788   TObject* CreateInputObject(int idx, int bForce=0);
789
790   /**
791    * Get input object
792    * Get object from the input block list. The methods first checks whether the
793    * object was already created. If not, it is created by @ref CreateInputObject
794    * and inserted into the list of objects.
795    * @param idx         index in the input block list
796    * @param classname   name of the class, object is checked for correct class
797    *                    name if set
798    * @param bForce      force the retrieval of an object, error messages
799    *                    are suppressed if \em bForce is not set
800    * @return pointer to TObject
801    *
802    * @internal
803    */
804   TObject* GetInputObject(int idx, const char* classname=NULL, int bForce=0);
805
806   /**
807    * Clean the list of input objects.
808    * Cleanup is done at the end of each event processing.
809    */
810   int CleanupInputObjects();
811
812   /**
813    * Insert a buffer into the output block stream.
814    * This is the only method to insert blocks into the output stream, called
815    * from all types of the Pushback method. The actual data might have been
816    * written to the output buffer already. In that case NULL can be provided
817    * as buffer, only the block descriptor will be build.
818    * @param pBuffer     pointer to buffer
819    * @param iSize       size of the buffer in byte
820    * @param dt          data type
821    * @param spec        data specification
822    */
823   int InsertOutputBlock(void* pBuffer, int iSize,
824                         const AliHLTComponentDataType& dt,
825                         AliHLTUInt32_t spec);
826
827
828   /** The global component handler instance */
829   static AliHLTComponentHandler* fgpComponentHandler;              //! transient
830
831   /** The environment where the component is running in */
832   AliHLTComponentEnvironment fEnvironment;                         // see above
833
834   /** Set by ProcessEvent before the processing starts */
835   AliHLTEventID_t fCurrentEvent;                                   // see above
836
837   /** internal event no */
838   int fEventCount;                                                 // see above
839
840   /** the number of failed events */
841   int fFailedEvents;                                               // see above
842
843   /** event data struct of the current event under processing */
844   AliHLTComponentEventData fCurrentEventData;                      // see above
845
846   /** array of input data blocks of the current event */
847   const AliHLTComponentBlockData* fpInputBlocks;                   //! transient
848
849   /** index of the current input block */
850   int fCurrentInputBlock;                                          // see above
851
852   /** data type of the last block search */
853   AliHLTComponentDataType fSearchDataType;                         // see above
854
855   /** name of the class for the object to search for */
856   string fClassName;                                               // see above
857
858   /** array of generated input objects */
859   TObjArray* fpInputObjects;                                       //! transient
860  
861   /** the output buffer */
862   AliHLTUInt8_t* fpOutputBuffer;                                   //! transient
863
864   /** size of the output buffer */
865   AliHLTUInt32_t fOutputBufferSize;                                // see above
866
867   /** size of data written to output buffer */
868   AliHLTUInt32_t fOutputBufferFilled;                              // see above
869
870   /** list of ouput block data descriptors */
871   vector<AliHLTComponentBlockData> fOutputBlocks;                  // see above
872
873   /** stopwatch array */
874   TObjArray* fpStopwatches;                                        //! transient
875
876   ClassDef(AliHLTComponent, 2)
877 };
878 #endif