Fix for coverity (AdC)
[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     fHeaderV3 = reinterpret_cast<AliRawDataHeaderV3*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount);
87
88     //Access to version and size is uniform for V2 and V3 
89     UChar_t version = fHeader->GetVersion();
90     UInt_t size = fHeader->fSize;
91     Int_t headerSize = 0;
92
93     if(version == 3) {
94       fHeader=NULL;
95       headerSize = sizeof(AliRawDataHeaderV3);
96     } else if(version == 2) {
97       fHeaderV3=NULL;
98       headerSize = sizeof(AliRawDataHeader);
99     } else {
100       Error("ReadHeader", "Wrong raw data header version: %d. Expected: 2 or 3.", version);
101       return kFALSE;
102     }
103     
104     // Check that the header is sane, that is the size does not go past the buffer.
105     // Otherwise try again at the next word location.
106     while (1) {
107       if ( ( (size == 0) ||
108            ((Int_t)fPosition + fCount + (Int_t)size > (Int_t)fBuffers[fCurrent].GetBufferSize() ) )
109           && size != 0xFFFFFFFF) {
110
111         if (fPosition + sizeof(UInt_t) <= fBuffers[fCurrent].GetBufferSize()) {
112           fPosition += sizeof(UInt_t);
113           continue;
114         } else {
115           Error("ReadHeader", "Could not find a valid DDL header!");
116           return kFALSE;
117         }
118       } else {
119         fPosition += fCount + headerSize;
120       }
121       break;
122     }
123
124     if (size != 0xFFFFFFFF) {
125       fCount = (Int_t)size - headerSize;
126     } else {
127       fCount = fBuffers[fCurrent].GetBufferSize() - headerSize;
128     }
129   } while (!(result=IsSelected()) && OpenNextBuffer());
130   } while (!result && OpenNextBuffer());
131
132   return result;
133 }
134
135 Bool_t AliRawReaderMemory::OpenNextBuffer()
136 {
137   // increment to next buffer
138   fPosition=0;
139   fCount=0;
140   if (fCurrent>=fBuffers.size()) return kFALSE;
141   if (++fCurrent>=fBuffers.size()) return kFALSE;
142   return kTRUE;
143 }
144
145 Bool_t AliRawReaderMemory::ReadNextData(UChar_t*& data)
146 {
147 // reads the next payload at the current buffer position
148 // returns kFALSE if the data could not be read
149
150   while (fCount == 0) {
151     if (!ReadHeader()) return kFALSE;
152   }
153
154   if(fCount < 0){
155     Error("ReadNextData","Cannot read data, payload is negative");
156     return kFALSE;
157   }
158
159   UInt_t currentPosition = fPosition;
160   fPosition += fCount;
161   fCount = 0;
162
163   if(fBuffers[fCurrent].GetBufferSize()<currentPosition){
164     Error("ReadNextData","Current position exceeds buffersize.");
165     return kFALSE;
166   }
167   data = fBuffers[fCurrent].GetBuffer()+currentPosition;
168   return kTRUE;
169 }
170
171 Bool_t AliRawReaderMemory::ReadNext(UChar_t* data, Int_t size)
172 {
173 // reads the next block of data at the current buffer position
174 // but does not shift to the next equipment. The next equipment
175 // must be activated by calling ReadHeader
176 // returns kFALSE if the data could not be read
177
178   
179   if (fCurrent>=fBuffers.size()) return kFALSE;
180   if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE;
181
182   memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size );
183   fCount -= size;
184   fPosition += size;
185   return kTRUE;
186 }
187
188
189 Bool_t AliRawReaderMemory::Reset()
190 {
191 // reset the current position in the buffer to the beginning of the curevent
192
193   fHeader = NULL;
194   fHeaderV3 = NULL;
195   fCount = 0;
196   fPosition = 0;
197   fCurrent=0;
198   return kTRUE;
199 }
200
201 Bool_t AliRawReaderMemory::NextEvent()
202 {
203 // each memory buffer always contains only one event
204   if (fEventNumber < 0) {
205     fEventNumber++;
206     return kTRUE;
207   }
208   else
209     return kFALSE; 
210 }
211
212 Bool_t AliRawReaderMemory::RewindEvents()
213 {
214 // reset the event counter
215   fEventNumber = -1;
216
217   return Reset();
218 }
219
220 Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size )
221 {
222   // SetMemory function kept for backward compatibility, only allowed
223   // if no blocks have been added so far 
224   if (!memory || size<=0) return kFALSE;
225   if (fBuffers.size()>1 || (fBuffers.size()==1 && fPosition==0 && fCurrent==0)) {
226     Error("SetMemory","can not SetMemory for multiple buffers, use AddBuffer(...)");
227     return kFALSE;
228   }
229   if (fBuffers.size()==1) fBuffers.pop_back();
230   fBuffers.push_back(AliRRMBuffer(memory, size, -1));
231   fCurrent=0;
232   fHeader = NULL;
233   fHeaderV3 = NULL;
234   fCount = 0;
235   fPosition = 0;
236   return kTRUE;
237 }
238
239 void  AliRawReaderMemory::SetEquipmentID(Int_t id)
240 {
241   // SetMemory function kept for backward compatibility, only allowed
242   // if no blocks have been added so far, set equipment id of the first
243   // buffer
244   if (fBuffers.size()>1) {
245     Error("SetEquipmentID", "can not SetEquipmentID for multiple buffers, use AddBuffer(...)");
246     return;
247   }
248   if (fBuffers.size()==0 || fCurrent>=fBuffers.size()) {
249     Error("SetEquipmentID", "no block available to set equipment id");
250     return;    
251   }
252   fBuffers[fCurrent].SetEquipmentId(id);
253 }
254
255 Int_t AliRawReaderMemory::GetEquipmentSize() const
256 {
257   // get the size of the equipment, that is payload + CDH
258   if (fCurrent>=fBuffers.size()) return 0;
259   return fBuffers[fCurrent].GetBufferSize();
260 }
261
262 Int_t AliRawReaderMemory::GetEquipmentId() const
263 {
264   // get the current equipment id
265   if (fCurrent>=fBuffers.size()) return -1;
266   return fBuffers[fCurrent].GetEquipmentId();
267 }
268
269 Bool_t AliRawReaderMemory::AddBuffer(UChar_t* memory, ULong_t size, Int_t equipmentId )
270 {
271   // Add a buffer to the list
272   if (!memory || size<=0 || equipmentId<0 ) return kFALSE;
273   fBuffers.push_back(AliRRMBuffer(memory, size, equipmentId));
274   return kTRUE;
275 }
276
277 void AliRawReaderMemory::ClearBuffers()
278 {
279   // Clear the buffer list
280   fBuffers.clear();
281   Reset();
282 }
283
284 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer()
285   :
286   fBuffer(NULL),
287   fBufferSize(0),
288   fEquipmentId(-1)
289 {
290   // ctor
291 }
292
293 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(UChar_t* pBuffer, UInt_t bufferSize, Int_t equipmentId)
294   :
295   fBuffer(pBuffer),
296   fBufferSize(bufferSize),
297   fEquipmentId(equipmentId)
298 {
299   // ctor
300 }
301
302 AliRawReaderMemory::AliRRMBuffer::~AliRRMBuffer()
303 {
304   // dtor
305 }
306
307 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(const AliRRMBuffer& src)
308   :
309   fBuffer(src.fBuffer),
310   fBufferSize(src.fBufferSize),
311   fEquipmentId(src.fEquipmentId)
312 {
313   // copy ctor, there are no buffers allocated internally, pointers
314   // are just copied
315 }
316
317 AliRawReaderMemory::AliRRMBuffer& AliRawReaderMemory::AliRRMBuffer::operator=(const AliRRMBuffer& src)
318 {
319   // assignment op
320   if(&src == this) return *this;
321   fBuffer=src.fBuffer;
322   fBufferSize=src.fBufferSize;
323   fEquipmentId=src.fEquipmentId;
324   return *this;
325 }