+ f32DtaPtr=(UInt_t*)(f8DtaPtr-fSize+f8PayloadSize+fkN32HeaderWords*4);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Int_t AliAltroDecoder::CopyBackward(Byte_t* pBuffer, Int_t bufferSize)
+{
+ // Copy the original 10/40 bit encecoded data of the current channel.
+ // The funtions copies the data to the end of the provided buffer.
+ // @param pBuffer target buffer
+ // @param bufferSize size of target buffer
+ // @return number of copied bytes, neg. error code if failed
+ Int_t iCopy=0;
+
+ if(fIsDecoded != kTRUE) {
+ AliWarning("buffer has not been decoded, no channel data available");
+ return 0;
+ }
+
+ // This method does not need to be the fastest possible implementation
+ // For the sake of stability, there are a lot of consistency checks.
+
+ // the fOutBufferIndex always points to the next channel, since we are
+ // reading backwards, this is one byte before the start of the current
+ // channel.
+ Int_t currentIndex=fOutBufferIndex+1;
+ if (fNAltro10bitWords>0 && currentIndex < fN40AltroWords*4 ) {
+
+ // calculate the position in the encoded data, beginning right
+ // after the CDH. 10 -> 8 bit: needs 5/4 times the index
+ Int_t position=(currentIndex*5)/4;
+ if (position*4==currentIndex*5) {
+ // no of 10 bit words is without the fill words to fill complete 40 bit words
+ // in addition, align to complete 40 bit words (the '+3')
+ iCopy=((fNAltro10bitWords+3)/4)*5;
+
+ // calculate the source pointer in the encoded data
+ // f8DtaPtr was set to the end of the whole data buffer
+ // f32DtaPtr is behind the payload after decoding
+ Byte_t* pSrc=f8DtaPtr-fSize+(fkN32HeaderWords*4)+position;
+ if (pSrc+5<(Byte_t*)f32DtaPtr) {
+
+ // check the first byte of the source buffer, has to be consistent
+ // with the 8 LSBs of the decoded 10 bit word at the beginning of
+ // the current channel
+ //assert(*pSrc==fOutBuffer[currentIndex]&0xff);
+ if (*pSrc==(fOutBuffer[currentIndex]&0xff)) {
+
+ // try to verfify the length of the channel
+ UInt_t lenCheck=*(pSrc+iCopy+2)|(*(pSrc+iCopy+3)&0x3)<<8;
+ if (lenCheck==fNAltro10bitWords) {
+
+ // copy including the 40 bit altro trailer
+ iCopy+=5;
+ if (iCopy<=bufferSize) {
+
+ // copy to the end of the buffer
+ Byte_t* pTgt=pBuffer+bufferSize-iCopy;
+ memcpy(pTgt, pSrc, iCopy);
+ } else {
+ AliError(Form("target buffer too small: available %d, required %d", bufferSize, iCopy));
+ iCopy=-1;
+ }
+ } else {
+ AliWarning(Form("format error: can not reproduce channel length: expected %d, read %d", fNAltro10bitWords, lenCheck));
+ iCopy=-1;
+ }
+ } else {
+ AliError(Form("first byte of encoded data (%#x at %d) does not match decoded word (%#x at %d)", *pSrc, position, fOutBuffer[currentIndex]&0xff, currentIndex));
+ iCopy=-1;
+ }
+ } else {
+ AliError(Form("buffer size missmatch: payload ends at %p, but current channel pretends to end at %p", f32DtaPtr, pSrc+5));
+ iCopy=-1;
+ }
+ } else {
+ AliError(Form("current position does not match a byte: currentIndex=%d", currentIndex));
+ iCopy=-1;
+ }
+ }
+ return iCopy;
+}
+
+Bool_t AliAltroDecoder::GetRCUTrailerData(UChar_t*& data) const
+{
+ // Provide a pointer to RCU trailer.
+ // The type of the parameter might not be optimal, but the function has
+ // been chosen that way to be similar to the counterpart in
+ // AliAltroRawStream.
+ // @return kTRUE if trailer available;
+ if (!f8DtaPtr) return kFALSE;
+ data=f8DtaPtr-(fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
+ assert((UChar_t*)f32DtaPtr == data);
+ return kTRUE;
+}
+
+Int_t AliAltroDecoder::GetRCUTrailerSize() const
+{
+ // Provide size of RCU trailer.
+ if (!f8DtaPtr || !fIsDecoded || fSize==0) return 0;
+ assert(fSize>(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t)));
+ return fSize-(f8PayloadSize+fkN32HeaderWords*sizeof(UInt_t));