]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliAltroDecoder.cxx
DAs upgraded to AliZDCRawStream class
[u/mrichter/AliRoot.git] / RAW / AliAltroDecoder.cxx
index ee183be6f435fd11c4e866cf8e318984dcdb6e32..cc757e1baf4aa40ec15984c006d7b4ebe0c73499 100644 (file)
@@ -102,7 +102,12 @@ Bool_t AliAltroDecoder::Decode()
       //     printf("\n AliAltroDecoder::Decode(). Please check on the return value (-1 if fataly corrupted) of the SetMemory() function\n");    
       return kFALSE;
     }
-
+  else if (!f8DtaPtr || !f32DtaPtr ||
+          (UChar_t*)f32DtaPtr < f8DtaPtr-fSize ||
+          (UChar_t*)f32DtaPtr > f8DtaPtr)
+    {
+      return kFALSE;
+    }
   else
     {
       // see header file for class documentation
@@ -213,13 +218,13 @@ Bool_t AliAltroDecoder::NextChannel(AliAltroData *altroDataPtr)
            }
 
          
-         if(fOutBufferIndex > 0)
+         if(fOutBufferIndex >= 0)
            {
          
              //cout << " AliAltroDecoder::NextChannel fOutBufferIndex =" << fOutBufferIndex   << endl;
              //              printf( "AliAltroDecoder::NextChannel fOutBufferIndex = %d", fOutBufferIndex);
              altroDataPtr->SetData( &fOutBuffer[fOutBufferIndex] );
-             fOutBufferIndex --;
+             if(fOutBufferIndex > 0) fOutBufferIndex --;
              altroDataPtr->SetDataSize( fNAltro10bitWords );
              return kTRUE;
            }
@@ -311,13 +316,20 @@ int AliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size)
   if(dtaPtr == 0)
     {
       printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, dtaPtr = ZERO !!!!!!!!!!!!\n");
-      printf("\nThis is an user error, please check in your code that you don give a zero pointer to the decoder \n");
+      printf("Please check your code that you don't give a zero pointer to the decoder \n");
+      return -99;
+    }
+
+  if (size<fkN32HeaderWords+4)
+    {
+      printf("\nAliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size) FATAL ERROR, too little data (%d)\n", size);
+      printf("Data buffer must contain the CDH and at least one 32bit RCU trailer word\n");
       return -99;
     }
 
 
   int iRet = 0;
-  Int_t tmpTrailerSize;
+  UInt_t tmpTrailerSize;
   fIsDecoded = kFALSE; 
   f8DtaPtr =dtaPtr;
   fSize = size;
@@ -325,34 +337,53 @@ int AliAltroDecoder::SetMemory(UChar_t *dtaPtr, UInt_t size)
   f32DtaPtr = (UInt_t *)f8DtaPtr;
   tmpTrailerSize = *(f32DtaPtr - 1);
 
+  // format of the trailer has been fixed in the RCU FW2
+  // Bit 31 to 16: 0xaaaa         (16 bit)
+  // Bit 15 to  7: RCU address    ( 9 bit)
+  // Bit  6 to  0: Trailer length ( 7 bit)
+  //
+  // RCU FW1 has one trailer word containing the number of
+  // 10bit Altro words. According to some early documents,
+  // it should have at least 2 32bit words: trailer length and
+  // the number of 10bit Altro words. This is the format of
+  // the simulation at time of writing (June 2008)
+  bool haveFw2=false;
+  if ((tmpTrailerSize>>16)==0xaaaa) {
+      haveFw2=true;
+      tmpTrailerSize = tmpTrailerSize&0x7f; // 7 LSBs of the last word
+  } else
   if(tmpTrailerSize <=  MAX_TRAILER_WORDS)
     {
       tmpTrailerSize = tmpTrailerSize; //assume that the last word of the buffer gives the number of trailer words 
     }
-  else
+  // nof 10bit AltroWords * 5/4  + bytes in the CDH   + 4 bytes RCU trailer
+  else if (((*(f32DtaPtr-1)*5)/4 + fkN32HeaderWords*4 + 4)<=fSize)
     {
       tmpTrailerSize = 1; //assume that last word is ONE, and that the this word gives the number of 40 bit altro words
     }
+  else
+    {
+      tmpTrailerSize=0;
+      fIsFatalCorruptedTrailer = kTRUE;
+      iRet = -1;
+    }
 
-  f8PayloadSize = fSize - (fkN32HeaderWords + tmpTrailerSize)*4;
-  fN40AltroWords = f8PayloadSize/5; 
-  fNDDLBlocks =  fN40AltroWords/4;
-  f32LastDDLBlockSize =  ((f8PayloadSize%(4*DDL_32BLOCK_SIZE))+3)/4;
-
-  if(tmpTrailerSize > 0 && tmpTrailerSize < 5)
+  if(tmpTrailerSize > 0 && (fkN32HeaderWords + tmpTrailerSize)*4<=fSize)
     {
+      f8PayloadSize = fSize - (fkN32HeaderWords + tmpTrailerSize)*4;
+      fN40AltroWords = f8PayloadSize/5; 
+      fNDDLBlocks =  fN40AltroWords/4;
+      f32LastDDLBlockSize =  ((f8PayloadSize%(4*DDL_32BLOCK_SIZE))+3)/4;
+
       f32DtaPtr =  f32DtaPtr -  tmpTrailerSize;
       fN40RcuAltroWords =  *f32DtaPtr;
       f32DtaPtr = (UInt_t *)dtaPtr + fkN32HeaderWords;
       fIsFatalCorruptedTrailer = kFALSE; 
     }
-  else
-    {
-      //     printf("\n AliAltroDecoder::SetMemory, ERROR\n, trailer is corrupted");
-      fIsFatalCorruptedTrailer = kTRUE;
-      iRet = -1;
-    }
-  
+
+  // all subsequent consistency checks depend on the correct initialization
+  // of the pointer and size variables
+  assert(f8DtaPtr == dtaPtr + fSize);  
   return iRet;
 
 }