Removing meaningless type qualifier on return type (icc warning 858)
[u/mrichter/AliRoot.git] / RAW / AliRawReaderDateV3.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 from a date file or event (version 3).
21 ///
22 /// The AliRawReaderDateV3 is constructed either with a pointer to a
23 /// date event or with a file name and an event number.
24 ///
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #include "AliRawReaderDateV3.h"
28
29 struct eventHeaderStruct { 
30   Int_t  size;          /* size of event in Bytes  */
31   UInt_t magic;         /* magic number used for consistency check */
32   UInt_t type;          /* event type */
33   UInt_t headLen;       /* size of header in bytes */
34   UInt_t runNb;         /* run number */
35   UInt_t burstNb;       /* burst number */
36   UInt_t nbInRun;       /* event number in run */
37   UInt_t nbInBurst;     /* event number in burst */
38   UInt_t triggerNb;     /* trigger number for this detector */
39   UInt_t fileSeqNb;     /* file sequence number for multifiles run */
40   UInt_t detectorId[3]; /* detector identification */
41   UInt_t time;          /* time in seconds since 0.00 GMT 1.1.1970 */
42   UInt_t usec;          /* microseconds */
43   UInt_t errorCode;
44   UInt_t deadTime;
45   UInt_t deadTimeusec;
46   UInt_t typeAttribute[2]; /* event type id mask */
47 };
48
49 #define EVENT_MAGIC_NUMBER         ((UInt_t)0xDA1E5AFE)
50
51
52 ClassImp(AliRawReaderDateV3)
53
54
55 AliRawReaderDateV3::AliRawReaderDateV3(void* event) :
56   fRequireHeader(kTRUE),
57   fFile(NULL),
58   fEvent(NULL),
59   fSubEvent(NULL),
60   fPosition(NULL),
61   fEnd(NULL)
62 {
63 // create an object to read digits from the given date event
64
65   fEvent = (eventHeaderStruct*) event;
66 }
67
68 AliRawReaderDateV3::AliRawReaderDateV3(const char* fileName, 
69                                        Int_t eventNumber) :
70   fRequireHeader(kTRUE),
71   fFile(NULL),
72   fEvent(NULL),
73   fSubEvent(NULL),
74   fPosition(NULL),
75   fEnd(NULL)
76 {
77 // create an object to read digits from the given date event
78
79   fFile = fopen(fileName, "rb");
80   if (!fFile) {
81     Error("AliRawReaderDateV3", "could not open file %s", fileName);
82     return;
83   }
84   if (eventNumber < 0) return;
85
86   eventHeaderStruct header;
87   UInt_t headerSize = sizeof(eventHeaderStruct);
88   while (fread(&header, 1, headerSize, fFile) == headerSize) {
89     if (eventNumber == 0) {
90       UChar_t* buffer = new UChar_t[header.size];
91       fseek(fFile, -headerSize, SEEK_CUR);
92       if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) break;
93       fEvent = (eventHeaderStruct*) buffer;
94       break;
95     }
96     fseek(fFile, header.size-headerSize, SEEK_CUR);
97     eventNumber--;
98   }
99 }
100
101 AliRawReaderDateV3::AliRawReaderDateV3(const AliRawReaderDateV3& rawReader) :
102   AliRawReader(rawReader),
103   fRequireHeader(rawReader.fRequireHeader),
104   fFile(rawReader.fFile),
105   fEvent(rawReader.fEvent),
106   fSubEvent(rawReader.fSubEvent),
107   fPosition(rawReader.fPosition),
108   fEnd(rawReader.fEnd)
109
110 {
111 // copy constructor
112
113   Fatal("AliRawReaderDateV3", "copy constructor not implemented");
114 }
115
116 AliRawReaderDateV3& AliRawReaderDateV3::operator = (const AliRawReaderDateV3& 
117                                                 /*rawReader*/)
118 {
119 // assignment operator
120
121   Fatal("operator =", "assignment operator not implemented");
122   return *this;
123 }
124
125 AliRawReaderDateV3::~AliRawReaderDateV3()
126 {
127 // destructor
128
129   if (fFile) {
130     delete[] fEvent;
131     fclose(fFile);
132   }
133 }
134
135
136 UInt_t AliRawReaderDateV3::GetType() const
137 {
138 // get the type from the event header
139
140   if (!fEvent) return 0;
141   return fEvent->type;
142 }
143
144 UInt_t AliRawReaderDateV3::GetRunNumber() const
145 {
146 // get the run number from the event header
147
148   if (!fEvent) return 0;
149   return fEvent->runNb;
150 }
151
152 const UInt_t* AliRawReaderDateV3::GetEventId() const
153 {
154 // get the event id from the event header
155
156   if (!fEvent) return NULL;
157   return &(fEvent->nbInRun);
158 }
159
160 const UInt_t* AliRawReaderDateV3::GetTriggerPattern() const
161 {
162 // get the trigger pattern from the event header
163
164   return NULL;
165 }
166
167 const UInt_t* AliRawReaderDateV3::GetDetectorPattern() const
168 {
169 // get the detector pattern from the event header
170
171   if (!fEvent) return NULL;
172   return fEvent->detectorId;
173 }
174
175 const UInt_t* AliRawReaderDateV3::GetAttributes() const
176 {
177 // get the type attributes from the event header
178
179   if (!fEvent) return NULL;
180   return fEvent->typeAttribute;
181 }
182
183 const UInt_t* AliRawReaderDateV3::GetSubEventAttributes() const
184 {
185 // get the type attributes from the sub event header
186
187   if (!fSubEvent) return NULL;
188   return fSubEvent->typeAttribute;
189 }
190
191 UInt_t AliRawReaderDateV3::GetLDCId() const
192 {
193 // get the LDC Id from the event header
194
195   return UInt_t(-1);
196 }
197
198 UInt_t AliRawReaderDateV3::GetGDCId() const
199 {
200 // get the GDC Id from the event header
201
202   return UInt_t(-1);
203 }
204
205
206 Int_t AliRawReaderDateV3::GetEquipmentSize() const
207 {
208 // get the size of the equipment
209
210   if (!fSubEvent) return 0;
211   return fSubEvent->size;
212 }
213
214 Int_t AliRawReaderDateV3::GetEquipmentType() const
215 {
216 // get the type from the equipment header
217
218   return 0;
219 }
220
221 Int_t AliRawReaderDateV3::GetEquipmentId() const
222 {
223 // get the ID from the equipment header
224
225   return 0;
226 }
227
228 const UInt_t* AliRawReaderDateV3::GetEquipmentAttributes() const
229 {
230 // get the attributes from the equipment header
231
232   return 0;
233 }
234
235 Int_t AliRawReaderDateV3::GetEquipmentElementSize() const
236 {
237 // get the basic element size from the equipment header
238
239   return 0;
240 }
241
242
243 Bool_t AliRawReaderDateV3::ReadHeader()
244 {
245 // read a data header at the current position
246 // returns kFALSE if the data header could not be read
247
248   fErrorCode = 0;
249
250   fHeader = NULL;
251   if (!fEvent) return kFALSE;
252   // check whether there are sub events
253   if (fEvent->size <= Int_t(fEvent->headLen)) return kFALSE;
254
255   do {
256     // skip payload (if event was not selected)
257     if (fCount > 0) fPosition += fCount;
258
259     // check for end of event data
260     if (fPosition >= ((UChar_t*)fEvent)+fEvent->size) return kFALSE;
261     if ((fEvent->detectorId[2] && 0x8000) != 0x8000) {
262       fSubEvent = fEvent;   // no super event
263     } else if (fSubEvent) {
264       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + 
265                                         fSubEvent->size);
266     } else {
267       fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
268                                         fEvent->headLen);
269     }
270
271     // check the magic word of the sub event
272     if (fSubEvent->magic != EVENT_MAGIC_NUMBER) {
273       Error("ReadHeader", "wrong magic number in sub event!\n"
274             " run: %d  event: %d\n", 
275             fSubEvent->runNb, fSubEvent->nbInRun);
276       fErrorCode = kErrMagic;
277       return kFALSE;
278     }
279
280     // continue if no data in the subevent
281     if (fSubEvent->size == Int_t(fSubEvent->headLen)) {
282       fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
283       fCount = 0;
284       continue;
285     }
286
287     fCount = 0;
288     fPosition = ((UChar_t*)fSubEvent) + sizeof(eventHeaderStruct);
289     fEnd = ((UChar_t*)fSubEvent) + fSubEvent->size;
290
291     // continue with the next sub event if no data left in the payload
292     if (fPosition >= fEnd) continue;
293
294     if (fRequireHeader) {
295       // check that there are enough bytes left for the data header
296       if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
297         Error("ReadHeader", "could not read data header data!");
298         Warning("ReadHeader", "skipping %d bytes\n"
299                 " run: %d  event: %d\n", 
300                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
301         fCount = 0;
302         fPosition = fEnd;
303         fErrorCode = kErrNoDataHeader;
304         continue;
305       }
306
307       // "read" the data header
308       fHeader = (AliRawDataHeader*) fPosition;
309       fPosition += sizeof(AliRawDataHeader);
310     }
311
312     if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
313       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
314
315       // check consistency of data size in the header and in the sub event
316       if (fPosition + fCount > fEnd) {
317         Error("ReadHeader", "size in data header exceeds event size!");
318         Warning("ReadHeader", "skipping %d bytes\n"
319                 " run: %d  event: %d\n", 
320                 fEnd - fPosition, fSubEvent->runNb, fSubEvent->nbInRun);
321         fCount = 0;
322         fPosition = fEnd;
323         fErrorCode = kErrSize;
324         continue;
325       }
326
327     } else {
328       fCount = fEnd - fPosition;
329     }
330
331   } while (!IsSelected());
332
333   return kTRUE;
334 }
335
336 Bool_t AliRawReaderDateV3::ReadNextData(UChar_t*& data)
337 {
338 // reads the next payload at the current position
339 // returns kFALSE if the data could not be read
340
341   fErrorCode = 0;
342   while (fCount == 0) {
343     if (!ReadHeader()) return kFALSE;
344   }
345   data = fPosition;
346   fPosition += fCount;  
347   fCount = 0;
348   return kTRUE;
349 }
350
351 Bool_t AliRawReaderDateV3::ReadNext(UChar_t* data, Int_t size)
352 {
353 // reads the next block of data at the current position
354 // returns kFALSE if the data could not be read
355
356   fErrorCode = 0;
357   if (fPosition + size > fEnd) {
358     Error("ReadNext", "could not read data!");
359     fErrorCode = kErrOutOfBounds;
360     return kFALSE;
361   }
362   memcpy(data, fPosition, size);
363   fPosition += size;
364   fCount -= size;
365   return kTRUE;
366 }
367
368
369 Bool_t AliRawReaderDateV3::Reset()
370 {
371 // reset the current position to the beginning of the event
372
373   fSubEvent = NULL;
374   fCount = 0;
375   fPosition = fEnd = NULL;
376   return kTRUE;
377 }
378
379
380 Bool_t AliRawReaderDateV3::NextEvent()
381 {
382 // go to the next event in the date file
383
384   if (!fFile) return kFALSE;
385
386   Reset();
387   eventHeaderStruct header;
388   UInt_t headerSize = sizeof(eventHeaderStruct);
389   if (fEvent) delete[] fEvent;
390   fEvent = &header;
391
392   while (fread(&header, 1, headerSize, fFile) == headerSize) {
393     if (!IsEventSelected()) {
394       fseek(fFile, header.size-headerSize, SEEK_CUR);
395       continue;
396     }
397     UChar_t* buffer = new UChar_t[header.size];
398     fseek(fFile, -headerSize, SEEK_CUR);
399     if (Int_t(fread(buffer, 1, header.size, fFile)) != header.size) {
400       Error("NextEvent", "could not read event from file");
401       delete[] buffer;
402       break;
403     }
404     fEvent = (eventHeaderStruct*) buffer;
405     return kTRUE;
406   };
407
408   fEvent = NULL;
409   return kFALSE;
410 }
411
412 Bool_t AliRawReaderDateV3::RewindEvents()
413 {
414 // go back to the beginning of the date file
415
416   if (!fFile) return kFALSE;
417
418   fseek(fFile, 0, SEEK_SET);
419   return Reset();
420 }
421
422
423 Int_t AliRawReaderDateV3::CheckData() const
424 {
425 // check the consistency of the data
426
427   if (!fEvent) return 0;
428   // check whether there are sub events
429   if (fEvent->size <= Int_t(fEvent->headLen)) return 0;
430
431   eventHeaderStruct* subEvent = NULL;
432   UChar_t* position = 0;
433   UChar_t* end = 0;
434   Int_t result = 0;
435
436   while (kTRUE) {
437     // check for end of event data
438     if (position >= ((UChar_t*)fEvent)+fEvent->size) return result;
439     if ((fEvent->detectorId[2] && 0x8000) != 0x8000) {
440       subEvent = fEvent;   // no super event
441     } else if (subEvent) {
442       subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + 
443                                        subEvent->size);
444     } else {
445       subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + 
446                                        fEvent->headLen);
447     }
448
449     // check the magic word of the sub event
450     if (subEvent->magic != EVENT_MAGIC_NUMBER) {
451       result |= kErrMagic;
452       return result;
453     }
454
455     position = ((UChar_t*)subEvent) + subEvent->headLen;
456     end = ((UChar_t*)subEvent) + subEvent->size;
457
458     // continue with the next sub event if no data left in the payload
459     if (position >= end) continue;
460
461     if (fRequireHeader) {
462       // check that there are enough bytes left for the data header
463       if (position + sizeof(AliRawDataHeader) > end) {
464         result |= kErrNoDataHeader;
465         position = end;
466         continue;
467       }
468
469       // check consistency of data size in the data header and in the sub event
470       AliRawDataHeader* header = (AliRawDataHeader*) position;
471       if (header->fSize != 0xFFFFFFFF) {
472         if (position + header->fSize > end) result |= kErrSize;
473       }
474     }
475     position = end;
476   };
477
478   return 0;
479 }