Line data Source code
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 128 : ClassImp(AliRawReaderMemory)
29 :
30 :
31 0 : AliRawReaderMemory::AliRawReaderMemory() :
32 0 : fPosition(0),
33 0 : fBuffers(),
34 0 : fCurrent(0)
35 0 : {
36 : // create an object to read digits from
37 : // the given memory location
38 0 : }
39 :
40 0 : AliRawReaderMemory::AliRawReaderMemory(UChar_t* memory, UInt_t size) :
41 0 : fPosition(0),
42 0 : fBuffers(),
43 0 : fCurrent(0)
44 0 : {
45 : // create an object to read digits from the given memory
46 0 : fBuffers.push_back(AliRRMBuffer(memory, size, -1));
47 0 : }
48 :
49 : AliRawReaderMemory::~AliRawReaderMemory()
50 0 : {
51 : // close the input memory
52 0 : }
53 :
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 0 : if (!required)
60 0 : Fatal("AliRawReaderMemory","Reading of raw data without raw data header is not implemented !");
61 :
62 0 : AliRawReader::RequireHeader(required);
63 0 : }
64 :
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 :
70 : Bool_t result=kFALSE;
71 0 : if (fCurrent>=fBuffers.size()) return kFALSE;
72 :
73 : do {
74 : result=kFALSE;
75 0 : do {
76 0 : if (fBuffers[fCurrent].GetEquipmentId() == -1)
77 : {
78 0 : Warning("ReadHeader", "The equipment ID is not set for the DDL memory buffer.");
79 0 : }
80 0 : if (!fBuffers[fCurrent].GetBuffer()) break;
81 :
82 : // Check if we would not read past the end of the buffer.
83 0 : if ( fPosition+fCount >= fBuffers[fCurrent].GetBufferSize() ) break;
84 :
85 0 : fHeader = reinterpret_cast<AliRawDataHeader*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount);
86 0 : fHeaderV3 = reinterpret_cast<AliRawDataHeaderV3*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount);
87 :
88 : //Access to version and size is uniform for V2 and V3
89 0 : UChar_t version = fHeader->GetVersion();
90 0 : UInt_t size = fHeader->fSize;
91 : Int_t headerSize = 0;
92 :
93 0 : if(version == 3) {
94 0 : fHeader=NULL;
95 : headerSize = sizeof(AliRawDataHeaderV3);
96 0 : } else if(version == 2) {
97 0 : fHeaderV3=NULL;
98 : headerSize = sizeof(AliRawDataHeader);
99 : } else {
100 0 : Error("ReadHeader", "Wrong raw data header version: %d. Expected: 2 or 3.", version);
101 0 : return kFALSE;
102 : }
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.
106 : while (1) {
107 0 : if ( ( (size == 0) ||
108 0 : ((Int_t)fPosition + fCount + (Int_t)size > (Int_t)fBuffers[fCurrent].GetBufferSize() ) )
109 0 : && size != 0xFFFFFFFF) {
110 :
111 0 : if (fPosition + sizeof(UInt_t) <= fBuffers[fCurrent].GetBufferSize()) {
112 0 : fPosition += sizeof(UInt_t);
113 0 : continue;
114 : } else {
115 0 : Error("ReadHeader", "Could not find a valid DDL header!");
116 0 : return kFALSE;
117 : }
118 : } else {
119 0 : fPosition += fCount + headerSize;
120 : }
121 : break;
122 : }
123 :
124 0 : if (size != 0xFFFFFFFF) {
125 0 : fCount = (Int_t)size - headerSize;
126 0 : } else {
127 0 : fCount = fBuffers[fCurrent].GetBufferSize() - headerSize;
128 : }
129 0 : } while (!(result=IsSelected()) && OpenNextBuffer());
130 0 : } while (!result && OpenNextBuffer());
131 :
132 0 : return result;
133 0 : }
134 :
135 : Bool_t AliRawReaderMemory::OpenNextBuffer()
136 : {
137 : // increment to next buffer
138 0 : fPosition=0;
139 0 : fCount=0;
140 0 : if (fCurrent>=fBuffers.size()) return kFALSE;
141 0 : if (++fCurrent>=fBuffers.size()) return kFALSE;
142 0 : return kTRUE;
143 0 : }
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 0 : while (fCount == 0) {
151 0 : if (!ReadHeader()) return kFALSE;
152 : }
153 :
154 0 : if(fCount < 0){
155 0 : Error("ReadNextData","Cannot read data, payload is negative");
156 0 : return kFALSE;
157 : }
158 :
159 0 : UInt_t currentPosition = fPosition;
160 0 : fPosition += fCount;
161 0 : fCount = 0;
162 :
163 0 : if(fBuffers[fCurrent].GetBufferSize()<currentPosition){
164 0 : Error("ReadNextData","Current position exceeds buffersize.");
165 0 : return kFALSE;
166 : }
167 0 : data = fBuffers[fCurrent].GetBuffer()+currentPosition;
168 0 : return kTRUE;
169 0 : }
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
174 : // but does not shift to the next equipment. The next equipment
175 : // must be activated by calling ReadHeader
176 : // returns kFALSE if the data could not be read
177 :
178 :
179 0 : if (fCurrent>=fBuffers.size()) return kFALSE;
180 0 : if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE;
181 :
182 0 : memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size );
183 0 : fCount -= size;
184 0 : fPosition += size;
185 0 : return kTRUE;
186 0 : }
187 :
188 :
189 : Bool_t AliRawReaderMemory::Reset()
190 : {
191 : // reset the current position in the buffer to the beginning of the curevent
192 :
193 0 : fHeader = NULL;
194 0 : fHeaderV3 = NULL;
195 0 : fCount = 0;
196 0 : fPosition = 0;
197 0 : fCurrent=0;
198 0 : return kTRUE;
199 : }
200 :
201 : Bool_t AliRawReaderMemory::NextEvent()
202 : {
203 : // each memory buffer always contains only one event
204 0 : if (fEventNumber < 0) {
205 0 : fEventNumber++;
206 0 : return kTRUE;
207 : }
208 : else
209 0 : return kFALSE;
210 0 : }
211 :
212 : Bool_t AliRawReaderMemory::RewindEvents()
213 : {
214 : // reset the event counter
215 0 : fEventNumber = -1;
216 :
217 0 : return Reset();
218 : }
219 :
220 : Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size )
221 : {
222 : // SetMemory function kept for backward compatibility, only allowed
223 : // if no blocks have been added so far
224 0 : if (!memory || size<=0) return kFALSE;
225 0 : if (fBuffers.size()>1 || (fBuffers.size()==1 && fPosition==0 && fCurrent==0)) {
226 0 : Error("SetMemory","can not SetMemory for multiple buffers, use AddBuffer(...)");
227 0 : return kFALSE;
228 : }
229 0 : if (fBuffers.size()==1) fBuffers.pop_back();
230 0 : fBuffers.push_back(AliRRMBuffer(memory, size, -1));
231 0 : fCurrent=0;
232 0 : fHeader = NULL;
233 0 : fHeaderV3 = NULL;
234 0 : fCount = 0;
235 0 : fPosition = 0;
236 0 : return kTRUE;
237 0 : }
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 0 : if (fBuffers.size()>1) {
245 0 : Error("SetEquipmentID", "can not SetEquipmentID for multiple buffers, use AddBuffer(...)");
246 0 : return;
247 : }
248 0 : if (fBuffers.size()==0 || fCurrent>=fBuffers.size()) {
249 0 : Error("SetEquipmentID", "no block available to set equipment id");
250 0 : return;
251 : }
252 0 : fBuffers[fCurrent].SetEquipmentId(id);
253 0 : }
254 :
255 : Int_t AliRawReaderMemory::GetEquipmentSize() const
256 : {
257 : // get the size of the equipment, that is payload + CDH
258 0 : if (fCurrent>=fBuffers.size()) return 0;
259 0 : return fBuffers[fCurrent].GetBufferSize();
260 0 : }
261 :
262 : Int_t AliRawReaderMemory::GetEquipmentId() const
263 : {
264 : // get the current equipment id
265 0 : if (fCurrent>=fBuffers.size()) return -1;
266 0 : return fBuffers[fCurrent].GetEquipmentId();
267 0 : }
268 :
269 : Bool_t AliRawReaderMemory::AddBuffer(UChar_t* memory, ULong_t size, Int_t equipmentId )
270 : {
271 : // Add a buffer to the list
272 0 : if (!memory || size<=0 || equipmentId<0 ) return kFALSE;
273 0 : fBuffers.push_back(AliRRMBuffer(memory, size, equipmentId));
274 0 : return kTRUE;
275 0 : }
276 :
277 : void AliRawReaderMemory::ClearBuffers()
278 : {
279 : // Clear the buffer list
280 0 : fBuffers.clear();
281 0 : Reset();
282 0 : }
283 :
284 : AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer()
285 : :
286 0 : fBuffer(NULL),
287 0 : fBufferSize(0),
288 0 : fEquipmentId(-1)
289 0 : {
290 : // ctor
291 0 : }
292 :
293 : AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(UChar_t* pBuffer, UInt_t bufferSize, Int_t equipmentId)
294 : :
295 0 : fBuffer(pBuffer),
296 0 : fBufferSize(bufferSize),
297 0 : fEquipmentId(equipmentId)
298 0 : {
299 : // ctor
300 0 : }
301 :
302 : AliRawReaderMemory::AliRRMBuffer::~AliRRMBuffer()
303 0 : {
304 : // dtor
305 0 : }
306 :
307 : AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(const AliRRMBuffer& src)
308 : :
309 0 : fBuffer(src.fBuffer),
310 0 : fBufferSize(src.fBufferSize),
311 0 : fEquipmentId(src.fEquipmentId)
312 0 : {
313 : // copy ctor, there are no buffers allocated internally, pointers
314 : // are just copied
315 0 : }
316 :
317 : AliRawReaderMemory::AliRRMBuffer& AliRawReaderMemory::AliRRMBuffer::operator=(const AliRRMBuffer& src)
318 : {
319 : // assignment op
320 0 : if(&src == this) return *this;
321 0 : fBuffer=src.fBuffer;
322 0 : fBufferSize=src.fBufferSize;
323 0 : fEquipmentId=src.fEquipmentId;
324 0 : return *this;
325 0 : }
|