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