choose better name for recently added Swap functions -> ByteSwap
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTOUTRawReader.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   AliHLTOUTRawReader.cxx
20     @author Matthias Richter
21     @date   
22     @brief  HLTOUT data wrapper for AliRawReader.                         */
23
24 // see header file for class documentation
25 // or
26 // refer to README to build package
27 // or
28 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
29
30 #include "AliHLTOUTRawReader.h"
31 #include "AliHLTHOMERLibManager.h"
32 #include "AliRawReader.h"
33 #include "AliHLTHOMERReader.h"
34
35 /** ROOT macro for the implementation of ROOT specific class methods */
36 ClassImp(AliHLTOUTRawReader)
37
38 AliHLTOUTRawReader::AliHLTOUTRawReader(AliRawReader* pRawreader)
39   :
40   AliHLTOUTHomerBuffer(NULL, 0),
41   fpRawreader(pRawreader),
42   fpCurrent(NULL)
43 {
44   // see header file for class documentation
45   // or
46   // refer to README to build package
47   // or
48   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
49 }
50
51 const int AliHLTOUTRawReader::fgkIdShift=16;
52
53 AliHLTOUTRawReader::~AliHLTOUTRawReader()
54 {
55   // see header file for class documentation
56   if (fpManager) {
57     if (fpCurrent) fpManager->DeleteReader(fpCurrent);
58     fpCurrent=NULL;
59   }
60 }
61
62 int AliHLTOUTRawReader::GenerateIndex()
63 {
64   // see header file for class documentation
65   // step through all HLT ddls, create HOMER readers and
66   // scan data block
67   int iResult=0;
68   if (fpRawreader && fpManager) {
69     fpRawreader->Reset();
70     // there was a bug in AliDAQ returning the wrong equipment id
71     // for the HLT links. It has been fixed in the trunk on Feb 5th 2008
72     // and from v4-10-Release (Rev-02). For the moment we select directly
73     // to support older AliRoot versions
74     //fpRawreader->Select("HLT");
75     fpRawreader->SelectEquipment(0,7680, 7689);
76     UChar_t* pSrc=NULL;
77     while (fpRawreader->ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
78       AliHLTUInt32_t id=(fpRawreader->GetEquipmentId());
79       unsigned int size=fpRawreader->GetDataSize();
80
81       AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
82
83       // we use the equipment id to identify the different homer blocks 
84       id<<=fgkIdShift;
85       if (pReader) {
86         iResult=ScanReader(pReader, id);
87         fpManager->DeleteReader(pReader);
88       }
89     }
90   } else {
91     iResult=-ENODEV;
92   }
93   return iResult;
94 }
95
96 int AliHLTOUTRawReader::GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer, 
97                                       AliHLTUInt32_t& size)
98 {
99   // see header file for class documentation
100   int iResult=0;
101   pBuffer=NULL;
102   size=0;
103   if (fpManager) {
104     Int_t id = Int_t(index>>fgkIdShift);
105     AliHLTUInt32_t blockNo=index&((0x1<<fgkIdShift)-1);
106
107     // block from the same ddl requested?
108     if (fpCurrent && fpRawreader->GetEquipmentId()!=id) {
109       fpManager->DeleteReader(fpCurrent);
110       fpCurrent=NULL;
111     }
112
113     // open ddl for equipment id and create HOMER reader
114     if (!fpCurrent) {
115       fpRawreader->Reset();
116       fpRawreader->SelectEquipment(-1, id, id);
117       UChar_t* pSrc=NULL;
118       if (fpRawreader->ReadNextData(pSrc) && pSrc!=NULL) {
119         int srcSize=fpRawreader->GetDataSize();
120         fpCurrent=OpenReader(pSrc, srcSize);
121         if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
122           iResult=-ENODATA;
123         }
124       } else {
125         iResult=-ENOSYS;
126       }
127     }
128
129     // get data
130     if (fpCurrent) {
131       AliHLTMonitoringReader* pReader=fpCurrent;
132       if ((pBuffer=static_cast<const AliHLTUInt8_t*>(pReader->GetBlockData(blockNo)))!=NULL) {
133         size=pReader->GetBlockDataLength(blockNo);
134       } else {
135         iResult=-ENOENT;
136       }
137     }
138   } else {
139     iResult=-ENODEV;
140   }
141   return iResult;
142 }
143
144 AliHLTHOMERReader* AliHLTOUTRawReader::OpenReader(UChar_t* pSrc, unsigned int size)
145 {
146   // see header file for class documentation
147   unsigned int offset=sizeof(AliHLTOUTEventHeader);
148   const AliRawDataHeader* pCDH=fpRawreader->GetDataHeader();
149   AliHLTUInt32_t id=(fpRawreader->GetEquipmentId());
150   AliHLTUInt32_t statusFlags=pCDH->GetStatus();
151   AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
152
153   // consistency check for the block size
154   if (pHLTHeader->fLength!=size) {
155     HLTWarning("can not treat HLT data block %d: size missmatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
156     return NULL;
157   }
158
159   // determine the offset of the homer block
160   // the HLT header is mandatory, HLT decision and HLT
161   // payload are optional. HLT decision is always before HLT
162   // payload if existent.
163   if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
164     // the block contains HLT decision data, this is just
165     // skipped here
166     AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
167     if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
168       // the first 32bit word specifies the number of 32bit words in the
169       // decision block -> +1 for this length word
170       offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
171     } else {
172       HLTWarning("size missmatch: HLT decision block bigger than total block length, skipping ...");
173       return NULL;
174     }
175   }
176
177   // check if there is payload
178   if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
179
180   // continue if there is no data left in the buffer
181   if (offset>=size) {
182     HLTWarning("no HLT payload available, but bit is set, skipping ...");
183     return NULL;
184   }
185
186   // check for the HOME descriptor type id
187   AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
188   if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID && 
189       ByteSwap64(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
190     HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
191     return NULL;
192   }
193
194   return fpManager->OpenReaderBuffer(pSrc+offset, size-offset);
195 }