DAs upgraded to AliZDCRawStream class
[u/mrichter/AliRoot.git] / RAW / AliRawReaderMemory.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 /// 
20 /// This is a class for reading raw data memory buffers.
21 ///
22 ///////////////////////////////////////////////////////////////////////////////
23
24 #include "AliRawReaderMemory.h"
25 #include <TSystem.h>
26
27
28 ClassImp(AliRawReaderMemory)
29
30
31 AliRawReaderMemory::AliRawReaderMemory() :
32   fPosition(0),
33   fBuffers(),
34   fCurrent(0)
35 {
36 // create an object to read digits from
37 // the given memory location
38 }
39
40 AliRawReaderMemory::AliRawReaderMemory(UChar_t* memory, UInt_t size) :
41   fPosition(0),
42   fBuffers(),
43   fCurrent(0)
44 {
45 // create an object to read digits from the given memory
46   fBuffers.push_back(AliRRMBuffer(memory, size, -1));
47 }
48
49 AliRawReaderMemory::~AliRawReaderMemory()
50 {
51 // close the input memory
52 }
53
54 void AliRawReaderMemory::RequireHeader(Bool_t required)
55 {
56   // Reading of raw data in case of missing
57   // raw data header is not implemented for
58   // this class
59   if (!required)
60     Fatal("AliRawReaderMemory","Reading of raw data without raw data header is not implemented !");
61
62   AliRawReader::RequireHeader(required);
63 }
64
65 Bool_t AliRawReaderMemory::ReadHeader()
66 {
67 // read a data header at the current buffer position
68 // returns kFALSE if the mini header could not be read
69
70   Bool_t result=kFALSE;
71   if (fCurrent>=fBuffers.size()) return kFALSE;
72
73   do {
74   result=kFALSE;
75   do {
76     if (fBuffers[fCurrent].GetEquipmentId() == -1)
77       {
78         Warning("ReadHeader", "The equipment ID is not set for the DDL memory buffer.");
79       }
80     if (!fBuffers[fCurrent].GetBuffer()) break;
81
82     // Check if we would not read past the end of the buffer.
83     if ( fPosition+fCount >= fBuffers[fCurrent].GetBufferSize() ) break;
84     
85     fHeader = reinterpret_cast<AliRawDataHeader*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount);
86     
87     // Check that the header is sane, that is the size does not go past the buffer.
88     // Otherwise try again at the next word location.
89     while (1) {
90     if ( ( (fHeader->fSize == 0) || 
91            ((Int_t)fPosition + fCount + (Int_t)fHeader->fSize > (Int_t)fBuffers[fCurrent].GetBufferSize() ) ) 
92          && fHeader->fSize != 0xFFFFFFFF) {
93
94       if (fPosition + sizeof(UInt_t) <= fBuffers[fCurrent].GetBufferSize()) {
95         fPosition += sizeof(UInt_t);
96         continue;
97       } else {
98         Error("ReadHeader", "Could not find a valid DDL header!");
99         return kFALSE;
100       }
101     } else {
102       fPosition += fCount + sizeof(AliRawDataHeader);
103     }
104     break;
105     }
106
107     if (fHeader->fSize != 0xFFFFFFFF) {
108       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
109     } else {
110       fCount = fBuffers[fCurrent].GetBufferSize() - sizeof(AliRawDataHeader);
111     }
112   } while (!(result=IsSelected()) && OpenNextBuffer());
113   } while (!result && OpenNextBuffer());
114
115   return result;
116 }
117
118 Bool_t AliRawReaderMemory::OpenNextBuffer()
119 {
120   // increment to next buffer
121   fPosition=0;
122   fCount=0;
123   if (fCurrent>=fBuffers.size()) return kFALSE;
124   if (++fCurrent>=fBuffers.size()) return kFALSE;
125   return kTRUE;
126 }
127
128 Bool_t AliRawReaderMemory::ReadNextData(UChar_t*& data)
129 {
130 // reads the next payload at the current buffer position
131 // returns kFALSE if the data could not be read
132
133   while (fCount == 0) {
134     if (!ReadHeader()) return kFALSE;
135   }
136   UInt_t currentPosition = fPosition;
137   fPosition += fCount;
138   fCount = 0;
139
140   data = fBuffers[fCurrent].GetBuffer()+currentPosition;
141   return kTRUE;
142 }
143
144 Bool_t AliRawReaderMemory::ReadNext(UChar_t* data, Int_t size)
145 {
146 // reads the next block of data at the current buffer position
147 // but does not shift to the next equipment. The next equipment
148 // must be activated by calling ReadHeader
149 // returns kFALSE if the data could not be read
150
151   
152   if (fCurrent>=fBuffers.size()) return kFALSE;
153   if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE;
154
155   memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size );
156   fCount -= size;
157   fPosition += size;
158   return kTRUE;
159 }
160
161
162 Bool_t AliRawReaderMemory::Reset()
163 {
164 // reset the current position in the buffer to the beginning of the curevent
165
166   fHeader = NULL;
167   fCount = 0;
168   fPosition = 0;
169   fCurrent=0;
170   return kTRUE;
171 }
172
173 Bool_t AliRawReaderMemory::NextEvent()
174 {
175 // each memory buffer always contains only one event
176   if (fEventNumber < 0) {
177     fEventNumber++;
178     return kTRUE;
179   }
180   else
181     return kFALSE; 
182 }
183
184 Bool_t AliRawReaderMemory::RewindEvents()
185 {
186 // reset the event counter
187   fEventNumber = -1;
188
189   return Reset();
190 }
191
192 Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size )
193 {
194   // SetMemory function kept for backward compatibility, only allowed
195   // if no blocks have been added so far 
196   if (!memory || size<=0) return kFALSE;
197   if (fBuffers.size()>1 || (fBuffers.size()==1 && fPosition==0 && fCurrent==0)) {
198     Error("SetMemory","can not SetMemory for multiple buffers, use AddBuffer(...)");
199     return kFALSE;
200   }
201   if (fBuffers.size()==1) fBuffers.pop_back();
202   fBuffers.push_back(AliRRMBuffer(memory, size, -1));
203   fCurrent=0;
204   fHeader = NULL;
205   fCount = 0;
206   fPosition = 0;
207   return kTRUE;
208 }
209
210 void  AliRawReaderMemory::SetEquipmentID(Int_t id)
211 {
212   // SetMemory function kept for backward compatibility, only allowed
213   // if no blocks have been added so far, set equipment id of the first
214   // buffer
215   if (fBuffers.size()>1) {
216     Error("SetEquipmentID", "can not SetEquipmentID for multiple buffers, use AddBuffer(...)");
217     return;
218   }
219   if (fBuffers.size()==0 || fCurrent>=fBuffers.size()) {
220     Error("SetEquipmentID", "no block available to set equipment id");
221     return;    
222   }
223   fBuffers[fCurrent].SetEquipmentId(id);
224 }
225
226 Int_t AliRawReaderMemory::GetEquipmentSize() const
227 {
228   // get the size of the equipment, that is payload + CDH
229   if (fCurrent>=fBuffers.size()) return 0;
230   return fBuffers[fCurrent].GetBufferSize();
231 }
232
233 Int_t AliRawReaderMemory::GetEquipmentId() const
234 {
235   // get the current equipment id
236   if (fCurrent>=fBuffers.size()) return -1;
237   return fBuffers[fCurrent].GetEquipmentId();
238 }
239
240 Bool_t AliRawReaderMemory::AddBuffer(UChar_t* memory, ULong_t size, Int_t equipmentId )
241 {
242   // Add a buffer to the list
243   if (!memory || size<=0 || equipmentId<0 ) return kFALSE;
244   fBuffers.push_back(AliRRMBuffer(memory, size, equipmentId));
245   return kTRUE;
246 }
247
248 void AliRawReaderMemory::ClearBuffers()
249 {
250   // Clear the buffer list
251   fBuffers.clear();
252   Reset();
253 }
254
255 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer()
256   :
257   fBuffer(NULL),
258   fBufferSize(0),
259   fEquipmentId(-1)
260 {
261   // ctor
262 }
263
264 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(UChar_t* pBuffer, UInt_t bufferSize, Int_t equipmentId)
265   :
266   fBuffer(pBuffer),
267   fBufferSize(bufferSize),
268   fEquipmentId(equipmentId)
269 {
270   // ctor
271 }
272
273 AliRawReaderMemory::AliRRMBuffer::~AliRRMBuffer()
274 {
275   // dtor
276 }
277
278 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(const AliRRMBuffer& src)
279   :
280   fBuffer(src.fBuffer),
281   fBufferSize(src.fBufferSize),
282   fEquipmentId(src.fEquipmentId)
283 {
284   // copy ctor, there are no buffers allocated internally, pointers
285   // are just copied
286 }
287
288 AliRawReaderMemory::AliRRMBuffer& AliRawReaderMemory::AliRRMBuffer::operator=(const AliRRMBuffer& src)
289 {
290   // assignment op
291   fBuffer=src.fBuffer;
292   fBufferSize=src.fBufferSize;
293   fEquipmentId=src.fEquipmentId;
294   return *this;
295 }