]>
Commit | Line | Data |
---|---|---|
7ab595b2 | 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() : | |
f3c1e83c | 32 | fPosition(0), |
e8692df9 | 33 | fBuffers(), |
34 | fCurrent(0) | |
7ab595b2 | 35 | { |
36 | // create an object to read digits from | |
37 | // the given memory location | |
7ab595b2 | 38 | } |
39 | ||
40 | AliRawReaderMemory::AliRawReaderMemory(UChar_t* memory, UInt_t size) : | |
f3c1e83c | 41 | fPosition(0), |
e8692df9 | 42 | fBuffers(), |
43 | fCurrent(0) | |
7ab595b2 | 44 | { |
45 | // create an object to read digits from the given memory | |
e8692df9 | 46 | fBuffers.push_back(AliRRMBuffer(memory, size, -1)); |
7ab595b2 | 47 | } |
48 | ||
49 | AliRawReaderMemory::~AliRawReaderMemory() | |
50 | { | |
51 | // close the input memory | |
7ab595b2 | 52 | } |
53 | ||
299738b9 | 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 | ||
7ab595b2 | 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 | ||
e8692df9 | 70 | Bool_t result=kFALSE; |
71 | if (fCurrent>=fBuffers.size()) return kFALSE; | |
b6ae8ba1 | 72 | |
7ab595b2 | 73 | do { |
e8692df9 | 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 | ||
b6ae8ba1 | 82 | // Check if we would not read past the end of the buffer. |
e8692df9 | 83 | if ( fPosition+fCount >= fBuffers[fCurrent].GetBufferSize() ) break; |
b3c6961a | 84 | |
e8692df9 | 85 | fHeader = reinterpret_cast<AliRawDataHeader*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount); |
b3c6961a | 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 | } | |
b6ae8ba1 | 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. | |
e8692df9 | 106 | while (1) { |
b3c6961a | 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 | } | |
b6ae8ba1 | 118 | } else { |
b3c6961a | 119 | fPosition += fCount + headerSize; |
299738b9 | 120 | } |
b3c6961a | 121 | break; |
e8692df9 | 122 | } |
7ab595b2 | 123 | |
b3c6961a | 124 | if (size != 0xFFFFFFFF) { |
125 | fCount = (Int_t)size - headerSize; | |
7ab595b2 | 126 | } else { |
b3c6961a | 127 | fCount = fBuffers[fCurrent].GetBufferSize() - headerSize; |
7ab595b2 | 128 | } |
e8692df9 | 129 | } while (!(result=IsSelected()) && OpenNextBuffer()); |
130 | } while (!result && OpenNextBuffer()); | |
131 | ||
132 | return result; | |
133 | } | |
b6ae8ba1 | 134 | |
e8692df9 | 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; | |
7ab595b2 | 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 | } | |
17d72161 | 153 | |
154 | if(fCount < 0){ | |
155 | Error("ReadNextData","Cannot read data, payload is negative"); | |
156 | return kFALSE; | |
157 | } | |
158 | ||
7ab595b2 | 159 | UInt_t currentPosition = fPosition; |
160 | fPosition += fCount; | |
161 | fCount = 0; | |
162 | ||
6bfa7f1f | 163 | if(fBuffers[fCurrent].GetBufferSize()<currentPosition){ |
17d72161 | 164 | Error("ReadNextData","Current position exceeds buffersize."); |
165 | return kFALSE; | |
166 | } | |
e8692df9 | 167 | data = fBuffers[fCurrent].GetBuffer()+currentPosition; |
7ab595b2 | 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 | |
e8692df9 | 174 | // but does not shift to the next equipment. The next equipment |
175 | // must be activated by calling ReadHeader | |
7ab595b2 | 176 | // returns kFALSE if the data could not be read |
177 | ||
e8692df9 | 178 | |
179 | if (fCurrent>=fBuffers.size()) return kFALSE; | |
180 | if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE; | |
7ab595b2 | 181 | |
e8692df9 | 182 | memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size ); |
7ab595b2 | 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 | ||
b6ae8ba1 | 193 | fHeader = NULL; |
b3c6961a | 194 | fHeaderV3 = NULL; |
7ab595b2 | 195 | fCount = 0; |
196 | fPosition = 0; | |
e8692df9 | 197 | fCurrent=0; |
7ab595b2 | 198 | return kTRUE; |
199 | } | |
200 | ||
201 | Bool_t AliRawReaderMemory::NextEvent() | |
202 | { | |
203 | // each memory buffer always contains only one event | |
59a76075 | 204 | if (fEventNumber < 0) { |
205 | fEventNumber++; | |
206 | return kTRUE; | |
207 | } | |
208 | else | |
209 | return kFALSE; | |
7ab595b2 | 210 | } |
211 | ||
212 | Bool_t AliRawReaderMemory::RewindEvents() | |
213 | { | |
214 | // reset the event counter | |
59a76075 | 215 | fEventNumber = -1; |
7ab595b2 | 216 | |
217 | return Reset(); | |
218 | } | |
219 | ||
220 | Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size ) | |
221 | { | |
e8692df9 | 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; | |
b6ae8ba1 | 232 | fHeader = NULL; |
b3c6961a | 233 | fHeaderV3 = NULL; |
7ab595b2 | 234 | fCount = 0; |
235 | fPosition = 0; | |
e8692df9 | 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(); | |
7ab595b2 | 267 | } |
268 | ||
e8692df9 | 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 | |
2a4ff083 | 320 | if(&src == this) return *this; |
e8692df9 | 321 | fBuffer=src.fBuffer; |
322 | fBufferSize=src.fBufferSize; | |
323 | fEquipmentId=src.fEquipmentId; | |
324 | return *this; | |
325 | } |