f38102b9f7b732358f5532aafc0e1726e7ca31e1
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTBlockFilterComponent.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 //*                  for The ALICE HLT 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   AliHLTBlockFilterComponent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  A simple data block filter and merger, merges block descriptors
23 */
24
25 #include <cstdlib>
26 #include "AliHLTBlockFilterComponent.h"
27 #include "TString.h"
28
29 /** ROOT macro for the implementation of ROOT specific class methods */
30 ClassImp(AliHLTBlockFilterComponent)
31
32 AliHLTBlockFilterComponent::AliHLTBlockFilterComponent()
33   :
34   fFilterRules()
35 {
36   // see header file for class documentation
37   // or
38   // refer to README to build package
39   // or
40   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
41 }
42
43 AliHLTBlockFilterComponent::~AliHLTBlockFilterComponent()
44 {
45   // see header file for class documentation
46 }
47
48 void AliHLTBlockFilterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
49 {
50   // see header file for class documentation
51   list.clear();
52   list.push_back(kAliHLTAnyDataType);
53 }
54
55 AliHLTComponentDataType AliHLTBlockFilterComponent::GetOutputDataType()
56 {
57   // see header file for class documentation
58   if (fFilterRules.size()==1) return fFilterRules[0].fDataType;
59   if (fFilterRules.size()==0) return kAliHLTAnyDataType;
60   return kAliHLTMultipleDataType;
61 }
62
63 int AliHLTBlockFilterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
64 {
65   // see header file for class documentation
66   tgtList.clear();
67   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
68   while (desc!=fFilterRules.end()) {
69     AliHLTComponentDataTypeList::iterator type=tgtList.begin();
70     while (type!=tgtList.end()) {
71       if (*type==(*desc).fDataType) break;
72       type++;
73     }
74     if (type==tgtList.end()) tgtList.push_back((*desc).fDataType);
75     desc++;
76   }
77   return tgtList.size();
78 }
79
80 void AliHLTBlockFilterComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
81 {
82   // see header file for class documentation
83   constBase=0;
84   inputMultiplier=0.0; // there is no new data, just forwarded descriptors
85 }
86
87 int AliHLTBlockFilterComponent::DoInit( int argc, const char** argv )
88 {
89   int iResult=0;
90   TString argument="";
91   int bMissingParam=0;
92   AliHLTComponentBlockData rule;
93   FillBlockData(rule);
94   for (int i=0; i<argc && iResult>=0; i++) {
95     argument=argv[i];
96     if (argument.IsNull()) continue;
97
98     // -datatype
99     if (argument.CompareTo("-datatype")==0) {
100       if ((bMissingParam=(i+2>=argc))) break;
101
102       if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
103         // the data type has already been set, add to list
104         // and reset
105         fFilterRules.push_back(rule);
106         FillBlockData(rule);
107       }
108
109       SetDataType(rule.fDataType, argv[i+1], argv[i+2]);
110       i+=2;
111
112       // -origin
113     } else if (argument.CompareTo("-origin")==0) {
114       if ((bMissingParam=(i+1>=argc))) break;
115
116       if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
117         // the data type has already been set, add to list
118         // and reset
119         fFilterRules.push_back(rule);
120         FillBlockData(rule);
121       }
122
123       SetDataType(rule.fDataType, NULL, argv[i+1]);
124       i+=1;
125
126       // -typeid
127     } else if (argument.CompareTo("-typeid")==0) {
128       if ((bMissingParam=(i+1>=argc))) break;
129
130       if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
131         // the data type has already been set, add to list
132         // and reset
133         fFilterRules.push_back(rule);
134         FillBlockData(rule);
135       }
136
137       SetDataType(rule.fDataType, argv[i+1], NULL);
138       i+=1;
139
140       // -dataspec
141     } else if (argument.CompareTo("-dataspec")==0) {
142       if ((bMissingParam=(++i>=argc))) break;
143
144       if (rule.fSpecification!=kAliHLTVoidDataSpec) {
145         // the specification has already been set, add to list
146         // and reset
147         fFilterRules.push_back(rule);
148         FillBlockData(rule);
149       }
150
151       TString parameter(argv[i]);
152       parameter.Remove(TString::kLeading, ' '); // remove all blanks
153       char* pRemnant=NULL;
154       rule.fSpecification=strtoul(parameter.Data(), &pRemnant, 0);
155       if (pRemnant!=NULL && pRemnant[0]!=0) {
156         HLTError("invalid parameter/remnant (%s) for argument %s, number expected", pRemnant, argument.Data());
157         iResult=-EINVAL;
158       }
159     } else {
160       HLTError("unknown argument %s", argument.Data());
161       iResult=-EINVAL;
162       break;
163     }
164   }
165   if (iResult>=0 && (rule.fSpecification!=kAliHLTVoidDataSpec || !MatchExactly(rule.fDataType,kAliHLTAnyDataType))) {
166     // add the pending rule
167     fFilterRules.push_back(rule);
168     FillBlockData(rule);
169   }
170   return iResult;
171 }
172
173 int AliHLTBlockFilterComponent::DoDeinit()
174 {
175   int iResult=0;
176   fFilterRules.clear();
177   return iResult;
178 }
179
180 int AliHLTBlockFilterComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/,
181                                          const AliHLTComponentBlockData* /*blocks*/, 
182                                          AliHLTComponentTriggerData& /*trigData*/,
183                                          AliHLTUInt8_t* /*outputPtr*/, 
184                                          AliHLTUInt32_t& size,
185                                          AliHLTComponentBlockDataList& /*outputBlocks*/ )
186 {
187   // see header file for class documentation
188   int iResult=0;
189   for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock();
190        pBlock!=NULL; 
191        pBlock=GetNextInputBlock()) {
192     if (IsSelected(*pBlock)) {
193       HLTDebug("block type %s %#x (ptr=%p offset=%d size=%d) selected by filter rules", 
194                DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, 
195                pBlock->fPtr, pBlock->fOffset, pBlock->fSize);
196       Forward();
197     } else {
198       HLTDebug("block type %s %#x discarded by filter rules", DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification);
199     }
200   }
201   size=0;
202   return iResult;
203 }
204
205 int AliHLTBlockFilterComponent::IsSelected(const AliHLTComponentBlockData& block)
206 {
207   // see header file for class documentation
208   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
209   //HLTDebug("check block: %s spec %#x", DataType2Text(block.fDataType, 1).c_str(), block.fSpecification);
210   if (desc==fFilterRules.end()) return 1; // no filter rules
211   do {
212     // match if
213     // 1. data types match or filter data type not set
214     // 2. data spec match or filter data wpec not set
215     // 3. either filter data type or spec is set
216     //HLTDebug("check rule : %s spec %#x", DataType2Text((*desc).fDataType, 2).c_str(), block.fSpecification);
217     if (((*desc).fDataType==block.fDataType) &&
218         ((*desc).fSpecification==block.fSpecification || (*desc).fSpecification==kAliHLTVoidDataSpec) &&
219         (!MatchExactly((*desc).fDataType,kAliHLTAnyDataType) || (*desc).fSpecification!=kAliHLTVoidDataSpec)) {
220       return 1;
221     }
222   } while (++desc!=fFilterRules.end());
223   
224   return 0;
225 }