]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliAltroDecoder.cxx
checking existence of galice.root and require to delete the file
[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),
44443c72 64 fIsFatalCorruptedTrailer(kTRUE)
65 // fIsFirstChannelOfPayload(kTRUE)
31a920d3 66{
ac672c4c 67 // Default constructor
da42bffc 68 memset(fOutBuffer, 0, sizeof(fOutBuffer));
69 memset(fDDLBlockDummy, 0, sizeof(fDDLBlockDummy));
31a920d3 70}
71
72
73AliAltroDecoder::~AliAltroDecoder()
74{
ac672c4c 75 // Default destructor
31a920d3 76}
77
78
ac672c4c 79Bool_t AliAltroDecoder::CheckPayloadTrailer() const
31a920d3 80{
86525f0f 81 //Check consistency between the number of 40 bit altro words given by
ac672c4c 82 //the RCU payload and the number of 40 bit words calculated from the size of the RCU payload.
83
31a920d3 84 if(fN40AltroWords != fN40RcuAltroWords)
85 {
86 return kFALSE;
87 }
88 else
89 {
90 return kTRUE;
91 }
92}
93
94
95Bool_t AliAltroDecoder::Decode()
ebf7cafe 96{
be9a8bd4 97 // Decodes the RCU payload (all altro channels in one go) from the DDL/Altro
98 // format to PC readable format.
99 // The 10 bit words of the 40/10 bit Altro format are transformed to separated
100 // integers.
101
ebf7cafe 102 if( fIsFatalCorruptedTrailer == kTRUE)
31a920d3 103 {
987d6d62 104 // printf("\n AliAltroDecoder::Decode(), WARNING, attempt to decode badly corrupted data\n");
105 // printf("\n AliAltroDecoder::Decode(). Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");
ebf7cafe 106 return kFALSE;
107 }
817c796a 108 else if (!f8DtaPtr || !f32DtaPtr ||
109 (UChar_t*)f32DtaPtr < f8DtaPtr-fSize ||
110 (UChar_t*)f32DtaPtr > f8DtaPtr)
111 {
112 return kFALSE;
113 }
ebf7cafe 114 else
31a920d3 115 {
ebf7cafe 116 // see header file for class documentation
117 fComplete = 0;
118 fInComplete = 0;
119
ac672c4c 120 Int_t tmpcnt = CountAAApaddings();
31a920d3 121
ebf7cafe 122 if(tmpcnt == 3)
123 {
124 fN40AltroWords = fN40AltroWords -1;
125 }
126 else if(tmpcnt == 5)
127 {
128 fN40AltroWords = fN40AltroWords -2;
129 }
130 else if(tmpcnt == 8)
131 {
132 fN40AltroWords = fN40AltroWords -3;
133 }
31a920d3 134
ebf7cafe 135 if( ((CheckPayloadTrailer() == kTRUE) || fDecodeIfCorruptedTrailer == kTRUE ) && (fSize > 32) )
31a920d3 136 {
ebf7cafe 137 fOutBufferIndex = 0;
138
139 for(Int_t i = 0; i < fNDDLBlocks; i++)
140 {
141 DecodeDDLBlock();
142 }
31a920d3 143
ebf7cafe 144 DecodeLastDDLBlock();
145 fOutBufferIndex = fN40AltroWords*4 - 1;
ebf7cafe 146 fIsDecoded = kTRUE;
147 return kTRUE;
148 }
149
150 else
151 {
987d6d62 152// cout <<" ERROR: data integrity check failed, discarding data" << endl;
153// cout << "Size of datablock is " << fSize << endl;
154// cout << "fN40AltroWords = " << fN40AltroWords << endl;
155// cout << "fN40RcuAltroWords = " << fN40RcuAltroWords << endl;
ebf7cafe 156 return kFALSE;
157 }
49f90cc3 158
31a920d3 159 }
160}
161
162
44443c72 163
164
31a920d3 165Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
166{
be9a8bd4 167 // Reads the next altro channel in the RCU payload after the RCU payload
168 // has been decoded. The channels are read starting from the end (backlinked list)
169 // Returns kTRUE as long as ther are unread channels in the payload
170 // Returns kFALSE when all the channels have been read.
171
ebf7cafe 172 if(fIsFatalCorruptedTrailer == kTRUE)
31a920d3 173 {
ebf7cafe 174 return kFALSE;
175 }
176
177 else
31a920d3 178 {
31a920d3 179
ebf7cafe 180 if(fIsDecoded != kTRUE)
181 {
ebf7cafe 182 Decode();
183 }
31a920d3 184
be9a8bd4 185 // an altro block must constist of at least 2 40bit words:
186 // - 40bit Altro trailer
187 // - at least 3 10bit words (bunch length, time bin, signal) padded to 40 bit
188 // we are reading backwards, so the index is already 1 inside the block
86525f0f 189 if(fOutBufferIndex >= 7)
31a920d3 190 {
d3f2a99e 191 if(((fOutBuffer[fOutBufferIndex] << 4 ) | ((fOutBuffer[fOutBufferIndex-1] & 0x3c0) >> 6)) == 0x2aaa)
ebf7cafe 192 {
193 altroDataPtr->SetIsComplete(kTRUE);
194 fComplete ++;
195 }
196 else
197 {
198 altroDataPtr->SetIsComplete(kFALSE);
199 fInComplete ++;
200 }
201
202 fOutBufferIndex --;
203 fNAltro10bitWords = ( (fOutBuffer[fOutBufferIndex] & 0x3f) << 4 ) | ((fOutBuffer[fOutBufferIndex -1] & (0xF << 6)) >> 6) ;
204 fOutBufferIndex --;
44443c72 205 altroDataPtr->SetHadd( ((fOutBuffer[fOutBufferIndex] & 0x3)) << 10 | ( fOutBuffer[fOutBufferIndex-1] ), fOutBufferIndex);
ebf7cafe 206
207 fOutBufferIndex --;
208
209 if(fNAltro10bitWords%4 == 0)
210 {
211 fOutBufferIndex = fOutBufferIndex - fNAltro10bitWords;
212 }
213 else
214 {
215 fOutBufferIndex = fOutBufferIndex - fNAltro10bitWords -(4 - fNAltro10bitWords%4);
216 }
84111923 217
49f90cc3 218 if(fOutBufferIndex >= 0)
84111923 219 {
84111923 220 altroDataPtr->SetData( &fOutBuffer[fOutBufferIndex] );
be9a8bd4 221 fOutBufferIndex --;
84111923 222 altroDataPtr->SetDataSize( fNAltro10bitWords );
223 return kTRUE;
224 }
225 else
226 {
227 //TODO write a fatal log message when this happends
228 return kFALSE;
229 }
86525f0f 230
31a920d3 231 }
232 else
233 {
ebf7cafe 234 return kFALSE;
31a920d3 235 }
236
31a920d3 237 }
238}
239
31a920d3 240
ac672c4c 241Int_t AliAltroDecoder::CountAAApaddings() const
31a920d3 242{
ac672c4c 243 // Use for simulated data only.
244 // Patch for incorrectly simulated data. Counts the number of
245 // 2aaa word in the trailer of the payload and tries to figure out
246 // the correct number of 40 bit altro words in the RCU pauload
86525f0f 247 //
248 // The simulated raw data differs from the real data by a number
249 // of additional 0x2aa words between the Altro payload and the
250 // RCU trailer. This is most likely to bring the total number of
251 // bytes to a common multiple of 4 and 5.
ac672c4c 252
86525f0f 253 UShort_t *tailPtr= (UShort_t *)((UChar_t*)f32DtaPtr + f8PayloadSize);
31a920d3 254 Int_t cnt = 0;
255
256 tailPtr --;
257
258 while(*tailPtr == 0xaaaa)
259 {
260 cnt ++;
261 tailPtr --;
262 }
263
264 tailPtr = tailPtr + cnt +1;
265
266 return cnt;
267}
268
269
270Float_t AliAltroDecoder::GetFailureRate()
271{
ac672c4c 272 // Prints to stdout the percent of altroblocks that
273 // is missing the 2aaa trailer.
274
31a920d3 275 Float_t tmp = 0;
987d6d62 276 // cout << "Number of Complete channles = " << fComplete <<endl;
277 // cout << "Number of InComplete channles = " << fInComplete <<endl;
31a920d3 278 tmp = (100*(Float_t)fInComplete)/((Float_t)fComplete + (Float_t)fInComplete);
987d6d62 279 // cout <<"There are "<< tmp <<"% incomplete channels"<<endl;
31a920d3 280 return tmp;
281}
282
283
44443c72 284
31a920d3 285void AliAltroDecoder::PrintInfo(AliAltroData &altrodata, Int_t n, Int_t nPerLine)
286{
ac672c4c 287 // prints data and address information contained in altrodata
288 // to the standard output
289
987d6d62 290 // cout << "altrodata.fDataSize = " << altrodata.GetDataSize() << endl;
291 // cout << "altrodata.fHadd = " << altrodata.GetHadd() <<endl;
31a920d3 292 const UInt_t* data = altrodata.GetData();
293 for(Int_t i= 0; i< n; i++)
294 {
295 if( (i%nPerLine == 0) && (i != 0) )
296 {
297 printf("\n");
298 }
299 printf("%d\t", data[i]);
300 }
301 printf("\n");
302}
303
304
ebf7cafe 305int AliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size)
31a920d3 306{
ac672c4c 307 // Sets the pointer to the memory block that should be decoded
308 // Returns a negative value if an inconsistency in the data is detected
309
44443c72 310 // fIsFirstChannelOfPayload = kTRUE;
be9a8bd4 311 int iRet = 0;
312 fIsDecoded = kFALSE;
44443c72 313
84111923 314 if(dtaPtr == 0)
315 {
44443c72 316 // printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, dtaPtr = ZERO !!!!!!!!!!!!\n");
317 // printf("Please check your code that you don't give a zero pointer to the decoder \n");
84111923 318 return -99;
319 }
320
d3f2a99e 321 if ((Int_t)size<(fkN32HeaderWords+1)*4)
49f90cc3 322 {
44443c72 323 // printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, too little data (%d)\n", size);
324 // printf("Data buffer must contain the CDH and at least one 32bit RCU trailer word\n");
49f90cc3 325 return -99;
326 }
327
49f90cc3 328 UInt_t tmpTrailerSize;
31a920d3 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 }
817c796a 378
379 // all subsequent consistency checks depend on the correct initialization
380 // of the pointer and size variables
381 assert(f8DtaPtr == dtaPtr + fSize);
ebf7cafe 382 return iRet;
383
31a920d3 384}
385
386
387void AliAltroDecoder::DecodeDDLBlock()
388{
ac672c4c 389 //Decode one 160 bit DDL block into 16 x 16 bit integers (only least significant 10 bits are filled)
390
31a920d3 391 fOutBuffer[fOutBufferIndex] = *f32DtaPtr & 0x3ff; //s0
392 fOutBufferIndex ++;
393 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc00) >> 10; //s1
394 fOutBufferIndex ++;
395 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff00000) >> 20; //s2
396 fOutBufferIndex ++;
397 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xc0000000) >> 30; //s3_1
398 f32DtaPtr ++;
399 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0xff) << 2); //s3_2
400 fOutBufferIndex ++;
401 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff00) >> 8; //s4
402 fOutBufferIndex ++;
403 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc0000) >> 18; //s5
404 fOutBufferIndex ++;
405 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xf0000000) >> 28; //s6_1
406 f32DtaPtr ++;
407 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0x3f) << 4); //s6_2
408 fOutBufferIndex ++;
409 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc0) >> 6; //s7
410 fOutBufferIndex ++;
411 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff0000) >> 16; //s8
412 fOutBufferIndex ++;
413 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xFC000000) >> 26; //s9_1
414 f32DtaPtr ++;
415 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0xf) << 6); //s9_2
416 fOutBufferIndex ++;
417 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff0) >> 4; //s10
418 fOutBufferIndex ++;
419 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc000) >> 14; //s11
420 fOutBufferIndex ++;
421 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xff000000) >> 24; //s12_1
422 f32DtaPtr ++;
423 fOutBuffer[fOutBufferIndex] = fOutBuffer[fOutBufferIndex] | ((*f32DtaPtr & 0x3) << 8); //s12_2
424 fOutBufferIndex ++;
425 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc) >> 2; //s13
426 fOutBufferIndex ++;
427 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0x3ff000) >> 12; //s14
428 fOutBufferIndex ++;
429 fOutBuffer[fOutBufferIndex] = (*f32DtaPtr & 0xffc00000) >> 22; //s15
430 f32DtaPtr ++;
431 fOutBufferIndex ++;
432}
433
434
44443c72 435
436
437
438
439
440
31a920d3 441void AliAltroDecoder::DecodeLastDDLBlock()
442{
ac672c4c 443 // Decode one 160 bit DDL block into 16 integers.
444 // In order to use the same decoding function (DecodeDDLBlock())
445 // a copy of the the last DDL block is made and
44443c72 446 // if the last block does not align with 160 bits then it is padded with zeroes
ac672c4c 447
31a920d3 448 for(Int_t i=0; i < f32LastDDLBlockSize; i++)
449 {
450 fDDLBlockDummy[i] = *f32DtaPtr;
451 f32DtaPtr ++;
452 }
453
454 f32DtaPtr = fDDLBlockDummy;
31a920d3 455 DecodeDDLBlock();
86525f0f 456 f32DtaPtr=(UInt_t*)(f8DtaPtr-fSize+f8PayloadSize+fkN32HeaderWords*4);
457}
458
44443c72 459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
86525f0f 487Int_t AliAltroDecoder::CopyBackward(Byte_t* pBuffer, Int_t bufferSize)
488{
489 // Copy the original 10/40 bit encecoded data of the current channel.
490 // The funtions copies the data to the end of the provided buffer.
491 // @param pBuffer target buffer
492 // @param bufferSize size of target buffer
493 // @return number of copied bytes, neg. error code if failed
494 Int_t iCopy=0;
495
496 if(fIsDecoded != kTRUE) {
497 AliWarning("buffer has not been decoded, no channel data available");
498 return 0;
499 }
500
501 // This method does not need to be the fastest possible implementation
502 // For the sake of stability, there are a lot of consistency checks.
503
504 // the fOutBufferIndex always points to the next channel, since we are
505 // reading backwards, this is one byte before the start of the current
506 // channel.
507 Int_t currentIndex=fOutBufferIndex+1;
508 if (fNAltro10bitWords>0 && currentIndex < fN40AltroWords*4 ) {
509
510 // calculate the position in the encoded data, beginning right
511 // after the CDH. 10 -> 8 bit: needs 5/4 times the index
512 Int_t position=(currentIndex*5)/4;
513 if (position*4==currentIndex*5) {
514 // no of 10 bit words is without the fill words to fill complete 40 bit words
515 // in addition, align to complete 40 bit words (the '+3')
516 iCopy=((fNAltro10bitWords+3)/4)*5;
517
518 // calculate the source pointer in the encoded data
519 // f8DtaPtr was set to the end of the whole data buffer
520 // f32DtaPtr is behind the payload after decoding
521 Byte_t* pSrc=f8DtaPtr-fSize+(fkN32HeaderWords*4)+position;
522 if (pSrc+5<(Byte_t*)f32DtaPtr) {
523
524 // check the first byte of the source buffer, has to be consistent
525 // with the 8 LSBs of the decoded 10 bit word at the beginning of
526 // the current channel
527 //assert(*pSrc==fOutBuffer[currentIndex]&0xff);
be9a8bd4 528 if (*pSrc==(fOutBuffer[currentIndex]&0xff)) {
86525f0f 529
530 // try to verfify the length of the channel
ecc0795d 531 UInt_t lenCheck=*(pSrc+iCopy+2)|(*(pSrc+iCopy+3)&0x3)<<8;
86525f0f 532 if (lenCheck==fNAltro10bitWords) {
533
534 // copy including the 40 bit altro trailer
535 iCopy+=5;
536 if (iCopy<=bufferSize) {
537
538 // copy to the end of the buffer
539 Byte_t* pTgt=pBuffer+bufferSize-iCopy;
540 memcpy(pTgt, pSrc, iCopy);
541 } else {
542 AliError(Form("target buffer too small: available %d, required %d", bufferSize, iCopy));
543 iCopy=-1;
544 }
545 } else {
ecc0795d 546 AliWarning(Form("format error: can not reproduce channel length: expected %d, read %d", fNAltro10bitWords, lenCheck));
86525f0f 547 iCopy=-1;
548 }
549 } else {
550 AliError(Form("first byte of encoded data (%#x at %d) does not match decoded word (%#x at %d)", *pSrc, position, fOutBuffer[currentIndex]&0xff, currentIndex));
551 iCopy=-1;
552 }
553 } else {
554 AliError(Form("buffer size missmatch: payload ends at %p, but current channel pretends to end at %p", f32DtaPtr, pSrc+5));
555 iCopy=-1;
556 }
557 } else {
558 AliError(Form("current position does not match a byte: currentIndex=%d", currentIndex));
559 iCopy=-1;
560 }
561 }
562 return iCopy;
563}
564
565Bool_t AliAltroDecoder::GetRCUTrailerData(UChar_t*& data) const
566{
567 // Provide a pointer to RCU trailer.
568 // The type of the parameter might not be optimal, but the function has
569 // been chosen that way to be similar to the counterpart in
570 // AliAltroRawStream.
571 // @return kTRUE if trailer available;
572 if (!f8DtaPtr) return kFALSE;
573 data=f8DtaPtr-(fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
574 assert((UChar_t*)f32DtaPtr == data);
575 return kTRUE;
576}
577
578Int_t AliAltroDecoder::GetRCUTrailerSize() const
579{
580 // Provide size of RCU trailer.
be9a8bd4 581 if (!f8DtaPtr || !fIsDecoded || fSize==0) return 0;
86525f0f 582 assert(fSize>(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
583 return fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t));
31a920d3 584}