renamed Cosmics folder to Cosmic
[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
137   if(fCount < 0){
138     Error("ReadNextData","Cannot read data, payload is negative");
139     return kFALSE;
140   }
141
142   UInt_t currentPosition = fPosition;
143   fPosition += fCount;
144   fCount = 0;
145
146   if(fBuffers[fCurrent].GetBufferSize()<currentPosition){
147     Error("ReadNextData","Current position exceeds buffersize.");
148     return kFALSE;
149   }
150   data = fBuffers[fCurrent].GetBuffer()+currentPosition;
151   return kTRUE;
152 }
153
154 Bool_t AliRawReaderMemory::ReadNext(UChar_t* data, Int_t size)
155 {
156 // reads the next block of data at the current buffer position
157 // but does not shift to the next equipment. The next equipment
158 // must be activated by calling ReadHeader
159 // returns kFALSE if the data could not be read
160
161   
162   if (fCurrent>=fBuffers.size()) return kFALSE;
163   if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE;
164
165   memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size );
166   fCount -= size;
167   fPosition += size;
168   return kTRUE;
169 }
170
171
172 Bool_t AliRawReaderMemory::Reset()
173 {
174 // reset the current position in the buffer to the beginning of the curevent
175
176   fHeader = NULL;
177   fCount = 0;
178   fPosition = 0;
179   fCurrent=0;
180   return kTRUE;
181 }
182
183 Bool_t AliRawReaderMemory::NextEvent()
184 {
185 // each memory buffer always contains only one event
186   if (fEventNumber < 0) {
187     fEventNumber++;
188     return kTRUE;
189   }
190   else
191     return kFALSE; 
192 }
193
194 Bool_t AliRawReaderMemory::RewindEvents()
195 {
196 // reset the event counter
197   fEventNumber = -1;
198
199   return Reset();
200 }
201
202 Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size )
203 {
204   // SetMemory function kept for backward compatibility, only allowed
205   // if no blocks have been added so far 
206   if (!memory || size<=0) return kFALSE;
207   if (fBuffers.size()>1 || (fBuffers.size()==1 && fPosition==0 && fCurrent==0)) {
208     Error("SetMemory","can not SetMemory for multiple buffers, use AddBuffer(...)");
209     return kFALSE;
210   }
211   if (fBuffers.size()==1) fBuffers.pop_back();
212   fBuffers.push_back(AliRRMBuffer(memory, size, -1));
213   fCurrent=0;
214   fHeader = NULL;
215   fCount = 0;
216   fPosition = 0;
217   return kTRUE;
218 }
219
220 void  AliRawReaderMemory::SetEquipmentID(Int_t id)
221 {
222   // SetMemory function kept for backward compatibility, only allowed
223   // if no blocks have been added so far, set equipment id of the first
224   // buffer
225   if (fBuffers.size()>1) {
226     Error("SetEquipmentID", "can not SetEquipmentID for multiple buffers, use AddBuffer(...)");
227     return;
228   }
229   if (fBuffers.size()==0 || fCurrent>=fBuffers.size()) {
230     Error("SetEquipmentID", "no block available to set equipment id");
231     return;    
232   }
233   fBuffers[fCurrent].SetEquipmentId(id);
234 }
235
236 Int_t AliRawReaderMemory::GetEquipmentSize() const
237 {
238   // get the size of the equipment, that is payload + CDH
239   if (fCurrent>=fBuffers.size()) return 0;
240   return fBuffers[fCurrent].GetBufferSize();
241 }
242
243 Int_t AliRawReaderMemory::GetEquipmentId() const
244 {
245   // get the current equipment id
246   if (fCurrent>=fBuffers.size()) return -1;
247   return fBuffers[fCurrent].GetEquipmentId();
248 }
249
250 Bool_t AliRawReaderMemory::AddBuffer(UChar_t* memory, ULong_t size, Int_t equipmentId )
251 {
252   // Add a buffer to the list
253   if (!memory || size<=0 || equipmentId<0 ) return kFALSE;
254   fBuffers.push_back(AliRRMBuffer(memory, size, equipmentId));
255   return kTRUE;
256 }
257
258 void AliRawReaderMemory::ClearBuffers()
259 {
260   // Clear the buffer list
261   fBuffers.clear();
262   Reset();
263 }
264
265 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer()
266   :
267   fBuffer(NULL),
268   fBufferSize(0),
269   fEquipmentId(-1)
270 {
271   // ctor
272 }
273
274 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(UChar_t* pBuffer, UInt_t bufferSize, Int_t equipmentId)
275   :
276   fBuffer(pBuffer),
277   fBufferSize(bufferSize),
278   fEquipmentId(equipmentId)
279 {
280   // ctor
281 }
282
283 AliRawReaderMemory::AliRRMBuffer::~AliRRMBuffer()
284 {
285   // dtor
286 }
287
288 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(const AliRRMBuffer& src)
289   :
290   fBuffer(src.fBuffer),
291   fBufferSize(src.fBufferSize),
292   fEquipmentId(src.fEquipmentId)
293 {
294   // copy ctor, there are no buffers allocated internally, pointers
295   // are just copied
296 }
297
298 AliRawReaderMemory::AliRRMBuffer& AliRawReaderMemory::AliRRMBuffer::operator=(const AliRRMBuffer& src)
299 {
300   // assignment op
301   fBuffer=src.fBuffer;
302   fBufferSize=src.fBufferSize;
303   fEquipmentId=src.fEquipmentId;
304   return *this;
305 }