5e85a167e8f2fcd377e95dcaec2da0c699d158a8
[u/mrichter/AliRoot.git] / RAW / AliRawReaderFile.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 files.
21 ///
22 /// The files of one event are expected to be in one directory. The name 
23 /// of the directory is "raw" + the event number. Each file contains
24 /// the raw data (with data header) of one DDL. The convention for the
25 /// file names is "DET_#DDL.ddl". "DET" is the name of the detector and
26 /// "#DDL" is the unique equipment ID.
27 ///
28 /// The constructor of AliRawReaderFile takes the event number or the
29 /// directory name as argument.
30 /// 
31 ///////////////////////////////////////////////////////////////////////////////
32
33 #include <cstdlib>
34 #include "AliRawReaderFile.h"
35 #include <TSystem.h>
36
37
38 ClassImp(AliRawReaderFile)
39
40
41 AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
42   fEventIndex(eventNumber),
43   fDirName("."),
44   fDirectory(NULL),
45   fStream(NULL),
46   fEquipmentId(-1),
47   fBuffer(NULL),
48   fBufferSize(0),
49   fEquipmentSize(0)
50 {
51 // create an object to read digits from the given event
52 // in the current directory
53
54   fDirectory = OpenDirectory();
55   OpenNextFile();
56   fHeader = new AliRawDataHeader;
57 }
58
59 AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
60   fEventIndex(eventNumber),
61   fDirName(dirName),
62   fDirectory(NULL),
63   fStream(NULL),
64   fEquipmentId(-1),
65   fBuffer(NULL),
66   fBufferSize(0),
67   fEquipmentSize(0)
68 {
69 // create an object to read digits from the given directory
70
71   fDirectory = OpenDirectory();
72   OpenNextFile();
73   fHeader = new AliRawDataHeader;
74 }
75
76 AliRawReaderFile::~AliRawReaderFile()
77 {
78 // close the input file
79
80   if (fDirectory) gSystem->FreeDirectory(fDirectory);
81   if (fStream) {
82 #if defined(__HP_aCC) || defined(__DECCXX)
83     if (fStream->rdbuf()->is_open()) fStream->close();
84 #else
85     if (fStream->is_open()) fStream->close();
86 #endif
87     delete fStream;
88   }
89   if (fHeader) delete fHeader;
90   if (fBuffer) delete[] fBuffer;
91 }
92
93 void AliRawReaderFile::RequireHeader(Bool_t required)
94 {
95   // Reading of raw data in case of missing
96   // raw data header is not implemented for
97   // this class
98   if (!required) {
99     Warning("AliRawReaderFile","Reading of raw data without raw data header is not implemented !");
100     if (fHeader) delete fHeader;
101     fHeader = NULL;
102   }
103   else {
104     if (!fHeader) fHeader = new AliRawDataHeader;
105   }
106
107   AliRawReader::RequireHeader(required);
108 }
109
110 TString AliRawReaderFile::GetDirName() const
111 {
112 // return the current directory name
113
114   TString dirName(fDirName);
115   if (fEventIndex >= 0) {
116     dirName += "/raw";
117     dirName += fEventIndex;
118   }
119   return dirName;
120 }
121
122 void* AliRawReaderFile::OpenDirectory()
123 {
124 // open and return the directory
125
126   TString dirName = GetDirName();
127   void* directory = gSystem->OpenDirectory(dirName);
128   if (!directory) {
129     Error("OpenDirectory", "could not open directory %s", dirName.Data());
130   }
131   return directory;
132 }
133
134 Bool_t AliRawReaderFile::OpenNextFile()
135 {
136 // open the next file
137 // returns kFALSE if the current file is the last one
138
139   if (fStream) {
140 #if defined(__HP_aCC) || defined(__DECCXX)
141     if (fStream->rdbuf()->is_open()) fStream->close();
142 #else
143     if (fStream->is_open()) fStream->close();
144 #endif
145     delete fStream;
146     fStream = NULL;
147     fEquipmentId = -1;
148     fEquipmentSize = 0;
149   }
150
151   if (!fDirectory) return kFALSE;
152   TString entry;
153   while (entry = gSystem->GetDirEntry(fDirectory)) {
154     if (entry.IsNull()) return kFALSE;
155     if (!entry.EndsWith(".ddl")) continue;
156     char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
157 #ifndef __DECCXX 
158     fStream = new fstream(fileName, ios::binary|ios::in);
159 #else
160     fStream = new fstream(fileName, ios::in);
161 #endif
162     break;
163   }
164
165   if (!fStream) return kFALSE;
166   entry.Remove(0, entry.Last('_')+1);
167   entry.Remove(entry.Length()-4);
168   fEquipmentId = atoi(entry.Data());
169 #if defined(__HP_aCC) || defined(__DECCXX)
170   return (fStream->rdbuf()->is_open());
171 #else
172   return (fStream->is_open());
173 #endif
174 }
175
176
177 Bool_t AliRawReaderFile::ReadHeader()
178 {
179 // read a data header at the current stream position
180 // returns kFALSE if the mini header could not be read
181
182   if (!fStream) return kFALSE;
183   do {
184     if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
185     if (fHeader) {
186       while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
187         if (!OpenNextFile()) return kFALSE;
188       }
189     }
190     if (fHeader && fHeader->fSize != 0xFFFFFFFF) {
191       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
192     } else {
193       UInt_t currentPos = fStream->tellg();
194       fStream->seekg(0, ios::end);
195       fCount = UInt_t(fStream->tellg()) - currentPos;
196       fStream->seekg(currentPos);
197     }
198     fEquipmentSize = fCount;
199     if (fHeader) fEquipmentSize += sizeof(AliRawDataHeader);
200   } while (!IsSelected());
201   return kTRUE;
202 }
203
204 Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
205 {
206 // reads the next payload at the current stream position
207 // returns kFALSE if the data could not be read
208
209   while (fCount == 0) {
210     if (!ReadHeader()) return kFALSE;
211   }
212   if (fBufferSize < fCount) {
213     if (fBuffer) delete[] fBuffer;
214     fBufferSize = Int_t(fCount*1.2);
215     fBuffer = new UChar_t[fBufferSize];
216   }
217   if (!fStream->read((char*) fBuffer, fCount)) {
218     Error("ReadNext", "could not read data!");
219     return kFALSE;
220   }
221   fCount = 0;
222
223   data = fBuffer;
224   return kTRUE;
225 }
226
227 Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
228 {
229 // reads the next block of data at the current stream position
230 // returns kFALSE if the data could not be read
231
232   if (!fStream->read((char*) data, size)) {
233     Error("ReadNext", "could not read data!");
234     return kFALSE;
235   }
236   fCount -= size;
237   return kTRUE;
238 }
239
240
241 Bool_t AliRawReaderFile::Reset()
242 {
243 // reset the current stream position to the first DDL file of the curevent
244
245   void* directory = OpenDirectory();
246   if (!directory) return kFALSE;
247
248   if (fStream) {
249 #if defined(__HP_aCC) || defined(__DECCXX)
250     if (fStream->rdbuf()->is_open()) fStream->close();
251 #else
252     if (fStream->is_open()) fStream->close();
253 #endif
254     delete fStream;
255     fStream = NULL;
256   }
257
258   if (fDirectory) gSystem->FreeDirectory(fDirectory);
259   fDirectory = directory;
260
261   OpenNextFile();
262   fCount = 0;
263   return kTRUE;
264 }
265
266 Bool_t AliRawReaderFile::NextEvent()
267 {
268 // go to the next event directory
269
270   if (fEventIndex < -1) return kFALSE;
271
272   do {
273     TString dirName = fDirName + "/raw";
274     dirName += (fEventIndex + 1);
275     void* directory = gSystem->OpenDirectory(dirName);
276     if (!directory) return kFALSE;
277     gSystem->FreeDirectory(directory);
278
279     fEventIndex++;
280     Reset();
281   } while (!IsEventSelected());
282
283   fEventNumber++;
284
285   return kTRUE;
286 }
287
288 Bool_t AliRawReaderFile::RewindEvents()
289 {
290 // reset the event counter
291
292   if (fEventIndex >= 0)  fEventIndex = -1;
293   fEventNumber = -1;
294   return Reset();
295 }