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