1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 /// This is a class for reading raw data memory buffers.
22 ///////////////////////////////////////////////////////////////////////////////
24 #include "AliRawReaderMemory.h"
28 ClassImp(AliRawReaderMemory)
31 AliRawReaderMemory::AliRawReaderMemory() :
36 // create an object to read digits from
37 // the given memory location
40 AliRawReaderMemory::AliRawReaderMemory(UChar_t* memory, UInt_t size) :
45 // create an object to read digits from the given memory
46 fBuffers.push_back(AliRRMBuffer(memory, size, -1));
49 AliRawReaderMemory::~AliRawReaderMemory()
51 // close the input memory
54 void AliRawReaderMemory::RequireHeader(Bool_t required)
56 // Reading of raw data in case of missing
57 // raw data header is not implemented for
60 Fatal("AliRawReaderMemory","Reading of raw data without raw data header is not implemented !");
62 AliRawReader::RequireHeader(required);
65 Bool_t AliRawReaderMemory::ReadHeader()
67 // read a data header at the current buffer position
68 // returns kFALSE if the mini header could not be read
71 if (fCurrent>=fBuffers.size()) return kFALSE;
76 if (fBuffers[fCurrent].GetEquipmentId() == -1)
78 Warning("ReadHeader", "The equipment ID is not set for the DDL memory buffer.");
80 if (!fBuffers[fCurrent].GetBuffer()) break;
82 // Check if we would not read past the end of the buffer.
83 if ( fPosition+fCount >= fBuffers[fCurrent].GetBufferSize() ) break;
85 fHeader = reinterpret_cast<AliRawDataHeader*>(fBuffers[fCurrent].GetBuffer()+fPosition+fCount);
87 // Check that the header is sane, that is the size does not go past the buffer.
88 // Otherwise try again at the next word location.
90 if ( ( (fHeader->fSize == 0) ||
91 ((Int_t)fPosition + fCount + (Int_t)fHeader->fSize > (Int_t)fBuffers[fCurrent].GetBufferSize() ) )
92 && fHeader->fSize != 0xFFFFFFFF) {
94 if (fPosition + sizeof(UInt_t) <= fBuffers[fCurrent].GetBufferSize()) {
95 fPosition += sizeof(UInt_t);
98 Error("ReadHeader", "Could not find a valid DDL header!");
102 fPosition += fCount + sizeof(AliRawDataHeader);
107 if (fHeader->fSize != 0xFFFFFFFF) {
108 fCount = fHeader->fSize - sizeof(AliRawDataHeader);
110 fCount = fBuffers[fCurrent].GetBufferSize() - sizeof(AliRawDataHeader);
112 } while (!(result=IsSelected()) && OpenNextBuffer());
113 } while (!result && OpenNextBuffer());
118 Bool_t AliRawReaderMemory::OpenNextBuffer()
120 // increment to next buffer
123 if (fCurrent>=fBuffers.size()) return kFALSE;
124 if (++fCurrent>=fBuffers.size()) return kFALSE;
128 Bool_t AliRawReaderMemory::ReadNextData(UChar_t*& data)
130 // reads the next payload at the current buffer position
131 // returns kFALSE if the data could not be read
133 while (fCount == 0) {
134 if (!ReadHeader()) return kFALSE;
138 Error("ReadNextData","Cannot read data, payload is negative");
142 UInt_t currentPosition = fPosition;
146 if(fBuffers[fCurrent].GetBufferSize()<currentPosition){
147 Error("ReadNextData","Current position exceeds buffersize.");
150 data = fBuffers[fCurrent].GetBuffer()+currentPosition;
154 Bool_t AliRawReaderMemory::ReadNext(UChar_t* data, Int_t size)
156 // reads the next block of data at the current buffer position
157 // but does not shift to the next equipment. The next equipment
158 // must be activated by calling ReadHeader
159 // returns kFALSE if the data could not be read
162 if (fCurrent>=fBuffers.size()) return kFALSE;
163 if ( fBuffers[fCurrent].GetBufferSize()-fPosition < (UInt_t)size ) return kFALSE;
165 memcpy( data, fBuffers[fCurrent].GetBuffer()+fPosition, size );
172 Bool_t AliRawReaderMemory::Reset()
174 // reset the current position in the buffer to the beginning of the curevent
183 Bool_t AliRawReaderMemory::NextEvent()
185 // each memory buffer always contains only one event
186 if (fEventNumber < 0) {
194 Bool_t AliRawReaderMemory::RewindEvents()
196 // reset the event counter
202 Bool_t AliRawReaderMemory::SetMemory( UChar_t* memory, ULong_t size )
204 // SetMemory function kept for backward compatibility, only allowed
205 // if no blocks have been added so far
206 if (!memory || size<=0) return kFALSE;
207 if (fBuffers.size()>1 || (fBuffers.size()==1 && fPosition==0 && fCurrent==0)) {
208 Error("SetMemory","can not SetMemory for multiple buffers, use AddBuffer(...)");
211 if (fBuffers.size()==1) fBuffers.pop_back();
212 fBuffers.push_back(AliRRMBuffer(memory, size, -1));
220 void AliRawReaderMemory::SetEquipmentID(Int_t id)
222 // SetMemory function kept for backward compatibility, only allowed
223 // if no blocks have been added so far, set equipment id of the first
225 if (fBuffers.size()>1) {
226 Error("SetEquipmentID", "can not SetEquipmentID for multiple buffers, use AddBuffer(...)");
229 if (fBuffers.size()==0 || fCurrent>=fBuffers.size()) {
230 Error("SetEquipmentID", "no block available to set equipment id");
233 fBuffers[fCurrent].SetEquipmentId(id);
236 Int_t AliRawReaderMemory::GetEquipmentSize() const
238 // get the size of the equipment, that is payload + CDH
239 if (fCurrent>=fBuffers.size()) return 0;
240 return fBuffers[fCurrent].GetBufferSize();
243 Int_t AliRawReaderMemory::GetEquipmentId() const
245 // get the current equipment id
246 if (fCurrent>=fBuffers.size()) return -1;
247 return fBuffers[fCurrent].GetEquipmentId();
250 Bool_t AliRawReaderMemory::AddBuffer(UChar_t* memory, ULong_t size, Int_t equipmentId )
252 // Add a buffer to the list
253 if (!memory || size<=0 || equipmentId<0 ) return kFALSE;
254 fBuffers.push_back(AliRRMBuffer(memory, size, equipmentId));
258 void AliRawReaderMemory::ClearBuffers()
260 // Clear the buffer list
265 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer()
274 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(UChar_t* pBuffer, UInt_t bufferSize, Int_t equipmentId)
277 fBufferSize(bufferSize),
278 fEquipmentId(equipmentId)
283 AliRawReaderMemory::AliRRMBuffer::~AliRRMBuffer()
288 AliRawReaderMemory::AliRRMBuffer::AliRRMBuffer(const AliRRMBuffer& src)
290 fBuffer(src.fBuffer),
291 fBufferSize(src.fBufferSize),
292 fEquipmentId(src.fEquipmentId)
294 // copy ctor, there are no buffers allocated internally, pointers
298 AliRawReaderMemory::AliRRMBuffer& AliRawReaderMemory::AliRRMBuffer::operator=(const AliRRMBuffer& src)
302 fBufferSize=src.fBufferSize;
303 fEquipmentId=src.fEquipmentId;