b11e4363818bc7e2f0f0ed863690df9e9b5b73f0
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTOUTHandlerEsdBranch.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   AliHLTOUTHandlerEsdBranch.cxx
20 /// @author Matthias Richter
21 /// @date   01.07.2010
22 /// @brief  HLTOUT handler of type kEsd to merge objects into the hltEsd.
23
24 #include "AliHLTOUTHandlerEsdBranch.h"
25 #include "AliHLTOUT.h"
26 #include "AliHLTMessage.h"
27 #include "AliHLTErrorGuard.h"
28 #include "AliESDEvent.h"
29 #include "TString.h"
30 #include "TObjString.h"
31 #include "TObjArray.h"
32 #include "TArrayC.h"
33 #include <cassert>
34
35 /** ROOT macro for the implementation of ROOT specific class methods */
36 ClassImp(AliHLTOUTHandlerEsdBranch)
37
38 AliHLTOUTHandlerEsdBranch::AliHLTOUTHandlerEsdBranch(const char* branchname)
39   : AliHLTOUTHandler() 
40   , fBranch(branchname)
41   , fESD(NULL)
42   , fpData(NULL)
43   , fSize(0)
44
45   // see header file for class documentation
46   // or
47   // refer to README to build package
48   // or
49   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
50 }
51
52 AliHLTOUTHandlerEsdBranch::~AliHLTOUTHandlerEsdBranch()
53 {
54   // see header file for class documentation
55 }
56
57 int AliHLTOUTHandlerEsdBranch::ProcessData(AliHLTOUT* pData)
58 {
59   // see header file for class documentation
60   if (!pData) return -EINVAL;
61   int iResult=0;
62
63   if (CheckStatus(kHandlerError)) {
64     HLTWarning("kEsd handler for ESD branch '%s' in error state, skipping processing of associated HLTOUT blocks", fBranch.Data());
65     return -EPERM;
66   }
67
68   if (!fESD) {
69     // create the ESD container, but without std content
70     fESD = new AliESDEvent;
71   }
72   if (!fpData) fpData=new TArrayC;
73   if (fESD && fpData) {
74     fESD->Reset();
75     iResult=ExtractAndAddObjects(pData);
76   }
77
78   AliHLTMessage* pMsg=AliHLTMessage::Stream(fESD);
79   if (pMsg) {
80     if (!pMsg->CompBuffer()) {
81       fSize=pMsg->Length();
82       fpData->Set(fSize, pMsg->Buffer());
83     } else {
84       fSize=pMsg->CompLength();
85       fpData->Set(fSize, pMsg->CompBuffer());
86     }
87     delete pMsg;
88     pMsg=NULL;
89   } else {
90     HLTError("streaming of object failed");
91   }
92
93   return iResult;
94 }
95
96 int AliHLTOUTHandlerEsdBranch::ExtractAndAddObjects(AliHLTOUT* pData)
97 {
98   // Default method
99   // Extract streamed object from the HLTOUT and add to ESD
100   // The default method works only for single blocks in the HLTOUT,
101   // A specific child class is required if multiple blocks should be
102   // treated.
103
104   int iResult=0;
105   iResult=pData->SelectFirstDataBlock(); 
106   if (iResult<0) return iResult;
107
108   TObject* pObject=pData->GetDataObject();
109   if (pObject) {
110     TString bname=fBranch;
111     if (bname.IsNull()) {
112       bname=pObject->GetName();
113       if (bname.CompareTo(pObject->ClassName())==0) {
114         ALIHLTERRORGUARD(5, "no branch name specified for unnamed object %s, not added to ESD", bname.Data());
115         bname="";
116       }
117     }
118     if (!bname.IsNull()) {
119       iResult=Add(pObject, bname.Data());
120     } else {
121       iResult=-EBADF;
122     }
123     pData->ReleaseDataObject(pObject);
124     pObject=NULL;
125   } else {
126     AliHLTComponentDataType dt=kAliHLTVoidDataType;
127     AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
128     pData->GetDataBlockDescription(dt, spec);
129     HLTError("Can not get TObject from HLTOUT buffer for block %s 0x%x", AliHLTComponent::DataType2Text(dt).c_str(), spec);
130     iResult=-ENODATA;
131   }
132
133   if (pData->SelectNextDataBlock()>=0) {
134     ALIHLTERRORGUARD(5, "the default function can only handle one single data block/object");
135   }
136
137   return iResult;
138 }
139
140 int AliHLTOUTHandlerEsdBranch::Add(TObject* object, const char* branchname)
141 {
142   // add object to the specified branch in the internal ESD
143   if (fESD && object) {
144     TObject* pESDObject=fESD->FindListObject(branchname);
145     if (pESDObject) {
146       // copy the content to the already existing object
147       object->Copy(*pESDObject);
148     } else {
149       // add a new object
150       fESD->AddObject(object->Clone());
151     }
152   }
153   return 0;
154 }
155
156 int AliHLTOUTHandlerEsdBranch::GetProcessedData(const AliHLTUInt8_t* &pData)
157 {
158   // see header file for class documentation
159   if (!fpData) {
160     pData=NULL;
161     return 0;
162   }
163
164   pData=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
165   return fSize;
166 }
167
168 int AliHLTOUTHandlerEsdBranch::ReleaseProcessedData(const AliHLTUInt8_t* pData, int size)
169 {
170   // see header file for class documentation
171   int iResult=0;
172   if (!fpData || size != fSize ||
173       const_cast<AliHLTUInt8_t*>(pData) != reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray())) {
174     HLTError("attempt to release to wrong data buffer %p size %d, expected %p size %d", pData, size, fpData?fpData->GetArray():NULL, fSize);
175   }
176   fSize=0;
177   return iResult;
178 }