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