]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliAltroDecoder.cxx
added data origin kAliHLTDataOriginEMCAL {EMCL}
[u/mrichter/AliRoot.git] / RAW / AliAltroDecoder.cxx
CommitLineData
86525f0f 1// $Id$
2
31a920d3 3/**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * All rights reserved. *
6 * *
7 * Primary Authors: Per Thomas Hille <perthi@fys.uio.no> *
86525f0f 8 * Oystein Djuvsland <oystein.djuvsland@gmail.com> *
31a920d3 9 * *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
18
86525f0f 19/**
20 @file AliAltroDocoder.cxx
21 @author Per Thomas Hille, Oystein Djuvsland
22 @date
23 @brief High performance decoder class for the RCU/Altro data format
24*/
25
26#include <cassert>
31a920d3 27#include <Riostream.h>
28#include "AliAltroDecoder.h"
29#include "AliAltroData.h"
86525f0f 30#include "AliLog.h"
31a920d3 31
ac672c4c 32// Class for fast decoding of RCU/Altro raw data format (DDL format)
33// to PC readable form. The decoding is done in 3 steps.
86525f0f 34// 1) The RCU payload consist of a variable number of 160 bit words
35// denoted a DDL block. All the DDL blocks of an RCU payload are transformed
36// into 16 bit integers and stored into a buffer of integers big enought to contain the
ac672c4c 37// biggest number of samples possible
38// 2) The decoded buffer is then accesible for the NextChannel functions wich reads
39// the altro channel data (samples) contained in the payload. The first call to NextChannel gives the
86525f0f 40// last altro channel of the back linked list, the next call the second last channel ..etc until
41// all channels are read.
ac672c4c 42// 3) (optional) For each Altro channel one chan invoke the member function NextBunch which gives on first call
43// The last bunch (the bunch with the highest timestamp), on next call the second last bunch..etc
44// untill all bunches are read
45
46
31a920d3 47ClassImp(AliAltroDecoder)
48
49AliAltroDecoder::AliAltroDecoder() : f32DtaPtr(0),
ebf7cafe 50 f8DtaPtr(0),
ac672c4c 51 fkN32HeaderWords(8),
ebf7cafe 52 fN40AltroWords(0),
53 fN40RcuAltroWords(0),
54 fNDDLBlocks(0),
55 f32LastDDLBlockSize(5),
86525f0f 56 f8PayloadSize(0),
ebf7cafe 57 fOutBufferIndex(0),
58 fSize(0),
59 fNAltro10bitWords(0),
60 fComplete(0),
61 fInComplete(0),
62 fDecodeIfCorruptedTrailer(kTRUE),
63 fIsDecoded(kFALSE),
49f90cc3 64 fIsFatalCorruptedTrailer(kTRUE)
31a920d3 65{
ac672c4c 66 // Default constructor
31a920d3 67}
68
69
70AliAltroDecoder::~AliAltroDecoder()
71{
ac672c4c 72 // Default destructor
31a920d3 73}
74
75
ac672c4c 76Bool_t AliAltroDecoder::CheckPayloadTrailer() const
31a920d3 77{
86525f0f 78 //Check consistency between the number of 40 bit altro words given by
ac672c4c 79 //the RCU payload and the number of 40 bit words calculated from the size of the RCU payload.
80
31a920d3 81 if(fN40AltroWords != fN40RcuAltroWords)
82 {
83 return kFALSE;
84 }
85 else
86 {
87 return kTRUE;
88 }
89}
90
91
92Bool_t AliAltroDecoder::Decode()
ebf7cafe 93{
86525f0f 94 // Decodes the RCU payload (all altro channels in one go) from the DDL/Altro
95 // format to PC readable format.
96 // The 10 bit words of the 40/10 bit Altro format are transformed to separated
97 // integers.
ac672c4c 98
ebf7cafe 99 if( fIsFatalCorruptedTrailer == kTRUE)
31a920d3 100 {
987d6d62 101 // printf("\n AliAltroDecoder::Decode(), WARNING, attempt to decode badly corrupted data\n");
102 // printf("\n AliAltroDecoder::Decode(). Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");
ebf7cafe 103 return kFALSE;
104 }
105
106 else
31a920d3 107 {
ebf7cafe 108 // see header file for class documentation
109 fComplete = 0;
110 fInComplete = 0;
111
ac672c4c 112 Int_t tmpcnt = CountAAApaddings();
31a920d3 113
ebf7cafe 114 if(tmpcnt == 3)
115 {
116 fN40AltroWords = fN40AltroWords -1;
117 }
118 else if(tmpcnt == 5)
119 {
120 fN40AltroWords = fN40AltroWords -2;
121 }
122 else if(tmpcnt == 8)
123 {
124 fN40AltroWords = fN40AltroWords -3;
125 }
31a920d3 126
ebf7cafe 127 if( ((CheckPayloadTrailer() == kTRUE) || fDecodeIfCorruptedTrailer == kTRUE ) && (fSize > 32) )
31a920d3 128 {
ebf7cafe 129 // fDDLBlockCnt = 0;
130 fOutBufferIndex = 0;
131
132 for(Int_t i = 0; i < fNDDLBlocks; i++)
133 {
134 DecodeDDLBlock();
135 }
31a920d3 136
ebf7cafe 137 DecodeLastDDLBlock();
138 fOutBufferIndex = fN40AltroWords*4 - 1;
31a920d3 139
ebf7cafe 140 // DumpData(fOutBuffer, 400,4);
31a920d3 141
ebf7cafe 142 fIsDecoded = kTRUE;
143 return kTRUE;
144 }
145
146 else
147 {
987d6d62 148// cout <<" ERROR: data integrity check failed, discarding data" << endl;
149// cout << "Size of datablock is " << fSize << endl;
150// cout << "fN40AltroWords = " << fN40AltroWords << endl;
151// cout << "fN40RcuAltroWords = " << fN40RcuAltroWords << endl;
ebf7cafe 152 return kFALSE;
153 }
49f90cc3 154
31a920d3 155 }
156}
157
158
159Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
160{
ac672c4c 161 // Reads the next altro channel in the RCU payload after the RCU payload
86525f0f 162 // has been decoded. The channels are read starting from the end (backlinked list)
163 // Returns kTRUE as long as ther are unread channels in the payload
164 // Returns kFALSE when all the channels have been read.
ac672c4c 165
ebf7cafe 166 if(fIsFatalCorruptedTrailer == kTRUE)
31a920d3 167 {
987d6d62 168 // printf("\n AliAltroDecoder::NextChannel(), WARNING, attempt to decode badly corrupted data\n");
169 // printf("\n AliAltroDecoder::NextChannel(), Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");
ebf7cafe 170 return kFALSE;
171 }
172
173 else
31a920d3 174 {
31a920d3 175
ebf7cafe 176 if(fIsDecoded != kTRUE)
177 {
987d6d62 178 // cout <<"AliAltroDecoder::NextChanne, WARNING, buffer was not decoded, decoding now.. "<< endl;
ebf7cafe 179 Decode();
180 }
31a920d3 181
86525f0f 182 // an altro block must constist of at least 2 40bit words:
183 // - 40bit Altro trailer
184 // - at least 3 10bit words (bunch length, time bin, signal) padded to 40 bit
185 // we are reading backwards, so the index is already 1 inside the block
186 if(fOutBufferIndex >= 7)
31a920d3 187 {
ebf7cafe 188 if((fOutBuffer[fOutBufferIndex] << 4 ) | ((fOutBuffer[fOutBufferIndex-1] & 0x3c0) >> 6) == 0x2aaa)
189 {
190 altroDataPtr->SetIsComplete(kTRUE);
191 fComplete ++;
192 }
193 else
194 {
195 altroDataPtr->SetIsComplete(kFALSE);
196 fInComplete ++;
197 }
198
199 fOutBufferIndex --;
200 fNAltro10bitWords = ( (fOutBuffer[fOutBufferIndex] & 0x3f) << 4 ) | ((fOutBuffer[fOutBufferIndex -1] & (0xF << 6)) >> 6) ;
201 fOutBufferIndex --;
202 altroDataPtr->SetHadd( ((fOutBuffer[fOutBufferIndex] & 0x3)) << 10 | ( fOutBuffer[fOutBufferIndex-1] ) );
203
204 fOutBufferIndex --;
205
206 if(fNAltro10bitWords%4 == 0)
207 {
208 fOutBufferIndex = fOutBufferIndex - fNAltro10bitWords;
209 }
210 else
211 {
212 fOutBufferIndex = fOutBufferIndex - fNAltro10bitWords -(4 - fNAltro10bitWords%4);
213 }
214
84111923 215
49f90cc3 216 if(fOutBufferIndex >= 0)
84111923 217 {
218
219 //cout << " AliAltroDecoder::NextChannel fOutBufferIndex =" << fOutBufferIndex << endl;
220 // printf( "AliAltroDecoder::NextChannel fOutBufferIndex = %d", fOutBufferIndex);
221 altroDataPtr->SetData( &fOutBuffer[fOutBufferIndex] );
49f90cc3 222 if(fOutBufferIndex > 0) fOutBufferIndex --;
84111923 223 altroDataPtr->SetDataSize( fNAltro10bitWords );
224 return kTRUE;
225 }
226 else
227 {
228 //TODO write a fatal log message when this happends
229 return kFALSE;
230 }
86525f0f 231
ebf7cafe 232
31a920d3 233 }
234 else
235 {
ebf7cafe 236 return kFALSE;
31a920d3 237 }
238
31a920d3 239 }
240}
241
31a920d3 242
ac672c4c 243Int_t AliAltroDecoder::CountAAApaddings() const
31a920d3 244{
ac672c4c 245 // Use for simulated data only.
246 // Patch for incorrectly simulated data. Counts the number of
247 // 2aaa word in the trailer of the payload and tries to figure out
248 // the correct number of 40 bit altro words in the RCU pauload
86525f0f 249 //
250 // The simulated raw data differs from the real data by a number
251 // of additional 0x2aa words between the Altro payload and the
252 // RCU trailer. This is most likely to bring the total number of
253 // bytes to a common multiple of 4 and 5.
ac672c4c 254
86525f0f 255 UShort_t *tailPtr= (UShort_t *)((UChar_t*)f32DtaPtr + f8PayloadSize);
31a920d3 256 Int_t cnt = 0;
257
258 tailPtr --;
259
260 while(*tailPtr == 0xaaaa)
261 {
262 cnt ++;
263 tailPtr --;
264 }
265
266 tailPtr = tailPtr + cnt +1;
267
268 return cnt;
269}
270
271
272Float_t AliAltroDecoder::GetFailureRate()
273{
ac672c4c 274 // Prints to stdout the percent of altroblocks that
275 // is missing the 2aaa trailer.
276
31a920d3 277 Float_t tmp = 0;
987d6d62 278 // cout << "Number of Complete channles = " << fComplete <<endl;
279 // cout << "Number of InComplete channles = " << fInComplete <<endl;
31a920d3 280 tmp = (100*(Float_t)fInComplete)/((Float_t)fComplete + (Float_t)fInComplete);
987d6d62 281 // cout <<"There are "<< tmp <<"% incomplete channels"<<endl;
31a920d3 282 return tmp;
283}
284
285
286void AliAltroDecoder::PrintInfo(AliAltroData &altrodata, Int_t n, Int_t nPerLine)
287{
ac672c4c 288 // prints data and address information contained in altrodata
289 // to the standard output
290
987d6d62 291 // cout << "altrodata.fDataSize = " << altrodata.GetDataSize() << endl;
292 // cout << "altrodata.fHadd = " << altrodata.GetHadd() <<endl;
31a920d3 293 const UInt_t* data = altrodata.GetData();
294 for(Int_t i= 0; i< n; i++)
295 {
296 if( (i%nPerLine == 0) && (i != 0) )
297 {
298 printf("\n");
299 }
300 printf("%d\t", data[i]);
301 }
302 printf("\n");
303}
304
305
ebf7cafe 306int AliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size)
31a920d3 307{
ac672c4c 308 // Sets the pointer to the memory block that should be decoded
309 // Returns a negative value if an inconsistency in the data is detected
310
84111923 311 if(dtaPtr == 0)
312 {
313 printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, dtaPtr = ZERO !!!!!!!!!!!!\n");
49f90cc3 314 printf("Please check your code that you don't give a zero pointer to the decoder \n");
84111923 315 return -99;
316 }
317
49f90cc3 318 if (size<fkN32HeaderWords+4)
319 {
320 printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, too little data (%d)\n", size);
321 printf("Data buffer must contain the CDH and at least one 32bit RCU trailer word\n");
322 return -99;
323 }
324
325
ebf7cafe 326 int iRet = 0;
49f90cc3 327 UInt_t tmpTrailerSize;
31a920d3 328 fIsDecoded = kFALSE;
329 f8DtaPtr =dtaPtr;
330 fSize = size;
331 f8DtaPtr =f8DtaPtr + fSize;
332 f32DtaPtr = (UInt_t *)f8DtaPtr;
49f90cc3 333 tmpTrailerSize = *(f32DtaPtr - 1);
334
335 // format of the trailer has been fixed in the RCU FW2
336 // Bit 31 to 16: 0xaaaa (16 bit)
337 // Bit 15 to 7: RCU address ( 9 bit)
338 // Bit 6 to 0: Trailer length ( 7 bit)
339 //
340 // RCU FW1 has one trailer word containing the number of
341 // 10bit Altro words. According to some early documents,
342 // it should have at least 2 32bit words: trailer length and
343 // the number of 10bit Altro words. This is the format of
344 // the simulation at time of writing (June 2008)
345 bool haveFw2=false;
346 if ((tmpTrailerSize>>16)==0xaaaa) {
347 haveFw2=true;
348 tmpTrailerSize = tmpTrailerSize&0x7f; // 7 LSBs of the last word
349 } else
31a920d3 350 if(tmpTrailerSize <= MAX_TRAILER_WORDS)
351 {
352 tmpTrailerSize = tmpTrailerSize; //assume that the last word of the buffer gives the number of trailer words
353 }
49f90cc3 354 // nof 10bit AltroWords * 5/4 + bytes in the CDH + 4 bytes RCU trailer
355 else if (((*(f32DtaPtr-1)*5)/4 + fkN32HeaderWords*4 + 4)<=fSize)
31a920d3 356 {
357 tmpTrailerSize = 1; //assume that last word is ONE, and that the this word gives the number of 40 bit altro words
358 }
49f90cc3 359 else
360 {
361 tmpTrailerSize=0;
362 fIsFatalCorruptedTrailer = kTRUE;
363 iRet = -1;
364 }
31a920d3 365
49f90cc3 366 if(tmpTrailerSize > 0 && (fkN32HeaderWords + tmpTrailerSize)*4<=fSize)
ebf7cafe 367 {
49f90cc3 368 f8PayloadSize = fSize - (fkN32HeaderWords + tmpTrailerSize)*4;
369 fN40AltroWords = f8PayloadSize/5;
370 fNDDLBlocks = fN40AltroWords/4;
371 f32LastDDLBlockSize = ((f8PayloadSize%(4*DDL_32BLOCK_SIZE))+3)/4;
372
ebf7cafe 373 f32DtaPtr = f32DtaPtr - tmpTrailerSize;
374 fN40RcuAltroWords = *f32DtaPtr;
ac672c4c 375 f32DtaPtr = (UInt_t *)dtaPtr + fkN32HeaderWords;
ebf7cafe 376 fIsFatalCorruptedTrailer = kFALSE;
ebf7cafe 377 }
ebf7cafe 378
379 return iRet;
380
31a920d3 381}
382
383
384void AliAltroDecoder::DecodeDDLBlock()
385{
ac672c4c 386 //Decode one 160 bit DDL block into 16 x 16 bit integers (only least significant 10 bits are filled)
387
31a920d3 388 fOutBuffer[fOutBufferIndex] = *f32DtaPtr & 0x3ff; //s0
389 fOutBufferIndex ++;
390 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc00) >> 10; //s1
391 fOutBufferIndex ++;
392 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff00000) >> 20; //s2
393 fOutBufferIndex ++;
394 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xc0000000) >> 30; //s3_1
395 f32DtaPtr ++;
396 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0xff) << 2); //s3_2
397 fOutBufferIndex ++;
398 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff00) >> 8; //s4
399 fOutBufferIndex ++;
400 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc0000) >> 18; //s5
401 fOutBufferIndex ++;
402 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xf0000000) >> 28; //s6_1
403 f32DtaPtr ++;
404 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0x3f) << 4); //s6_2
405 fOutBufferIndex ++;
406 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc0) >> 6; //s7
407 fOutBufferIndex ++;
408 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff0000) >> 16; //s8
409 fOutBufferIndex ++;
410 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xFC000000) >> 26; //s9_1
411 f32DtaPtr ++;
412 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0xf) << 6); //s9_2
413 fOutBufferIndex ++;
414 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff0) >> 4; //s10
415 fOutBufferIndex ++;
416 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc000) >> 14; //s11
417 fOutBufferIndex ++;
418 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xff000000) >> 24; //s12_1
419 f32DtaPtr ++;
420 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0x3) << 8); //s12_2
421 fOutBufferIndex ++;
422 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc) >> 2; //s13
423 fOutBufferIndex ++;
424 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff000) >> 12; //s14
425 fOutBufferIndex ++;
426 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc00000) >> 22; //s15
427 f32DtaPtr ++;
428 fOutBufferIndex ++;
429}
430
431
432void AliAltroDecoder::DecodeLastDDLBlock()
433{
ac672c4c 434 // Decode one 160 bit DDL block into 16 integers.
435 // In order to use the same decoding function (DecodeDDLBlock())
436 // a copy of the the last DDL block is made and
437 // if the las block does not align with 160 bits then it is padded with zeroes
438
31a920d3 439 for(Int_t i=0; i < f32LastDDLBlockSize; i++)
440 {
441 fDDLBlockDummy[i] = *f32DtaPtr;
442 f32DtaPtr ++;
443 }
444
445 f32DtaPtr = fDDLBlockDummy;
31a920d3 446 DecodeDDLBlock();
86525f0f 447 f32DtaPtr=(UInt_t*)(f8DtaPtr-fSize+f8PayloadSize+fkN32HeaderWords*4);
448}
449
450Int_t AliAltroDecoder::CopyBackward(Byte_t* pBuffer, Int_t bufferSize)
451{
452 // Copy the original 10/40 bit encecoded data of the current channel.
453 // The funtions copies the data to the end of the provided buffer.
454 // @param pBuffer target buffer
455 // @param bufferSize size of target buffer
456 // @return number of copied bytes, neg. error code if failed
457 Int_t iCopy=0;
458
459 if(fIsDecoded != kTRUE) {
460 AliWarning("buffer has not been decoded, no channel data available");
461 return 0;
462 }
463
464 // This method does not need to be the fastest possible implementation
465 // For the sake of stability, there are a lot of consistency checks.
466
467 // the fOutBufferIndex always points to the next channel, since we are
468 // reading backwards, this is one byte before the start of the current
469 // channel.
470 Int_t currentIndex=fOutBufferIndex+1;
471 if (fNAltro10bitWords>0 && currentIndex < fN40AltroWords*4 ) {
472
473 // calculate the position in the encoded data, beginning right
474 // after the CDH. 10 -> 8 bit: needs 5/4 times the index
475 Int_t position=(currentIndex*5)/4;
476 if (position*4==currentIndex*5) {
477 // no of 10 bit words is without the fill words to fill complete 40 bit words
478 // in addition, align to complete 40 bit words (the '+3')
479 iCopy=((fNAltro10bitWords+3)/4)*5;
480
481 // calculate the source pointer in the encoded data
482 // f8DtaPtr was set to the end of the whole data buffer
483 // f32DtaPtr is behind the payload after decoding
484 Byte_t* pSrc=f8DtaPtr-fSize+(fkN32HeaderWords*4)+position;
485 if (pSrc+5<(Byte_t*)f32DtaPtr) {
486
487 // check the first byte of the source buffer, has to be consistent
488 // with the 8 LSBs of the decoded 10 bit word at the beginning of
489 // the current channel
490 //assert(*pSrc==fOutBuffer[currentIndex]&0xff);
491 if (*pSrc==fOutBuffer[currentIndex]&0xff) {
492
493 // try to verfify the length of the channel
ecc0795d 494 UInt_t lenCheck=*(pSrc+iCopy+2)|(*(pSrc+iCopy+3)&0x3)<<8;
86525f0f 495 if (lenCheck==fNAltro10bitWords) {
496
497 // copy including the 40 bit altro trailer
498 iCopy+=5;
499 if (iCopy<=bufferSize) {
500
501 // copy to the end of the buffer
502 Byte_t* pTgt=pBuffer+bufferSize-iCopy;
503 memcpy(pTgt, pSrc, iCopy);
504 } else {
505 AliError(Form("target buffer too small: available %d, required %d", bufferSize, iCopy));
506 iCopy=-1;
507 }
508 } else {
ecc0795d 509 AliWarning(Form("format error: can not reproduce channel length: expected %d, read %d", fNAltro10bitWords, lenCheck));
86525f0f 510 iCopy=-1;
511 }
512 } else {
513 AliError(Form("first byte of encoded data (%#x at %d) does not match decoded word (%#x at %d)", *pSrc, position, fOutBuffer[currentIndex]&0xff, currentIndex));
514 iCopy=-1;
515 }
516 } else {
517 AliError(Form("buffer size missmatch: payload ends at %p, but current channel pretends to end at %p", f32DtaPtr, pSrc+5));
518 iCopy=-1;
519 }
520 } else {
521 AliError(Form("current position does not match a byte: currentIndex=%d", currentIndex));
522 iCopy=-1;
523 }
524 }
525 return iCopy;
526}
527
528Bool_t AliAltroDecoder::GetRCUTrailerData(UChar_t*& data) const
529{
530 // Provide a pointer to RCU trailer.
531 // The type of the parameter might not be optimal, but the function has
532 // been chosen that way to be similar to the counterpart in
533 // AliAltroRawStream.
534 // @return kTRUE if trailer available;
535 if (!f8DtaPtr) return kFALSE;
536 data=f8DtaPtr-(fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
537 assert((UChar_t*)f32DtaPtr == data);
538 return kTRUE;
539}
540
541Int_t AliAltroDecoder::GetRCUTrailerSize() const
542{
543 // Provide size of RCU trailer.
544 if (!f8DtaPtr) return 0;
545 assert(fSize>(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
546 return fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t));
31a920d3 547}