doing backward compatibility correctly
[u/mrichter/AliRoot.git] / HLT / rec / AliRawReaderHLT.cxx
index 4bcf4be9a5b62194ccc00159f480f1110e908b8f..bd11a1ebcfe0e0e7f0789f5f78c6c88b91e68bc2 100644 (file)
@@ -52,10 +52,12 @@ AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
   fpData(NULL),
   fDataSize(0),
   fOffset(0),
+  fPosition(0),
   fEquipmentId(-1),
   fbHaveHLTData(false),
   fDetectors(),
   fpHLTOUT(NULL),
+  fbReadFirst(true),
   fpDataHandler(NULL)
 {
   // see header file for class documentation
@@ -70,13 +72,7 @@ AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
 AliRawReaderHLT::~AliRawReaderHLT()
 {
   // see header file for class documentation
-  if (fpHLTOUT) {
-    if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
-    else fpHLTOUT->ReleaseDataBuffer(fpData);
-    fpDataHandler=NULL;
-    delete fpHLTOUT;
-    fpHLTOUT=NULL;
-  }
+  ReleaseHLTData();
 }
 
 UInt_t AliRawReaderHLT::GetType() const
@@ -193,18 +189,33 @@ Bool_t   AliRawReaderHLT::ReadHeader()
 {
   // see header file for class documentation
   Bool_t result=kFALSE;
-  while (fbHaveHLTData&=ReadNextHLTData()) {
+  Bool_t firstParentCycle=fbHaveHLTData;
+  while (fbHaveHLTData=(fbHaveHLTData && ReadNextHLTData())) {
     // all internal data variables set
     assert(fpData!=NULL);
     fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
+    fOffset=sizeof(AliRawDataHeader);
+    fPosition=fOffset;
     if (result=IsSelected()) break;
   }
-  if (!result) {
-    // first set the selection back to the original one
-    fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
+  firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
+  while (!result) {
+    if (firstParentCycle) {
+      firstParentCycle=kFALSE;
+      // reset and set the selection back to the original one
+      fpParentReader->Reset();
+      fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
+    }
 
-    result=fpParentReader->ReadHeader();
+    if (!(result=fpParentReader->ReadHeader())) {
+      fHeader=NULL;
+      break;
+    }
     fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
+
+    // filter out all equipment ids which should be taken from the HLT stream
+    int id=fpParentReader->GetEquipmentId();
+    if (result=!IsHLTInput(id)) break;
   }
   return result;
 }
@@ -216,36 +227,32 @@ Bool_t   AliRawReaderHLT::ReadNextData(UChar_t*& data)
   // this function is the backbone of the ReadNext functions, it gets the
   // whole data block either from the HLT stream or the parent raw reader.
   // Each call of ReadNextData directly jumps to the next data set.
-  Bool_t result=kFALSE;
-  if (ReadHeader() && fpData!=NULL) {
-    // all internal data variables set
-    result=kTRUE;
-    data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
-  }
-  if (kFALSE) { // this needs more thinking
-    // no data in the HLT stream, read real data
-    //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
-
-    // read data
-    while (result=fpParentReader->ReadNextData(data)) {
-      // continue if the Equipment Id is supposed to be replaced by the HLT stream
-      // in that case we do not want to read it from the parent raw reader
-      if (!IsHLTInput(fpParentReader->GetEquipmentId())) break;
-    }
-
-    // set the header of this reader from the parent reader.
-    // This is necessary because of a few base class methods working directly
-    // on the header
-    fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
-    if (result) {
-      fpData=data;
-      fDataSize=fpParentReader->GetDataSize();
+  Bool_t result=kTRUE;
+
+  // read new header if data already read
+  if (fPosition<fDataSize || (result=ReadHeader())) {
+    if (fbHaveHLTData && fpHLTOUT!=NULL) {
+      // all internal data variables set
+      result=kTRUE;
+      data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
     } else {
-      fpData=NULL;
-      fDataSize=0;
+      // no data in the HLT stream, read real data
+      //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
+
+      // read data
+      result=fpParentReader->ReadNextData(data);
+      if (result) {
+       fpData=data;
+       fDataSize=fpParentReader->GetDataSize();
+      } else {
+       fpData=NULL;
+       fDataSize=0;
+      }
+
+      fEquipmentId=-1;
     }
-    fOffset=0;
-    fEquipmentId=-1;
+    fOffset=sizeof(AliRawDataHeader);
+    fPosition=fDataSize;
   }
   return result;
 }
@@ -315,31 +322,15 @@ Bool_t   AliRawReaderHLT::ReadNext(UChar_t* data, Int_t size)
 Bool_t   AliRawReaderHLT::Reset()
 {
   // see header file for class documentation
+  ReleaseHLTData(false/* keep HLTOUT instance */);
   Bool_t result=fpParentReader->Reset();
-  fpData=NULL;
-  fDataSize=0;
-  fOffset=0;
   fEquipmentId=-1;
-  if (fbHaveHLTData=(fDetectors.size()>0)) {
-    vector<int>::iterator detector=fDetectors.begin();
-    for (; detector!=fDetectors.end(); detector++) {
-      int ddlOffset=AliDAQ::DdlIDOffset(*detector);
-      int nofDDLs=AliDAQ::NumberOfDdls(*detector);
-      if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) ||
-         (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset))
-       continue;
-      break;
-    }
-    fbHaveHLTData=detector!=fDetectors.end();
-  }
 
-  if (fpHLTOUT) {
-    if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
-    else fpHLTOUT->ReleaseDataBuffer(fpData);
-    fpDataHandler=NULL;
-    delete fpHLTOUT;
-    fpHLTOUT=NULL;
-  }
+  // check if redirection is enabled for at least one detector in the selected range
+  fbHaveHLTData=EvaluateSelection();
+
+  // start reading HLTOUT data blocks from the beginning
+  fbReadFirst=true;
 
   return result;
 }
@@ -347,6 +338,9 @@ Bool_t   AliRawReaderHLT::Reset()
 Bool_t   AliRawReaderHLT::NextEvent()
 {
   // see header file for class documentation
+
+  ReleaseHLTData();
+
   Bool_t result=fpParentReader->NextEvent();
   if (result) {
     fEventNumber++;
@@ -368,6 +362,7 @@ void AliRawReaderHLT::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
   // see header file for class documentation
   AliRawReader::Select(detectorID, minDDLID, maxDDLID);
   fpParentReader->Select(detectorID, minDDLID, maxDDLID);
+  fbHaveHLTData=EvaluateSelection();
 }
 
 // most likely we do not need this method since the base class directly forwards
@@ -384,8 +379,9 @@ void AliRawReaderHLT::SelectEquipment(Int_t equipmentType, Int_t minEquipmentId,
   // see header file for class documentation
 
   //AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
-  AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId);
-  fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId);
+  AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
+  fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
+  fbHaveHLTData=EvaluateSelection();
 }
 
 void AliRawReaderHLT::SkipInvalid(Bool_t skip)
@@ -439,7 +435,8 @@ Bool_t   AliRawReaderHLT::ReadNextHLTData()
 {
   // see header file for class documentation
   bool result=kTRUE;
-  if (!fpHLTOUT) {
+  if (fbReadFirst || !fpHLTOUT) {
+    if (!fpHLTOUT) {
     fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
     if (result=(fpHLTOUT!=NULL)) {
       AliHLTSystem* pSystem=GetInstance();
@@ -447,20 +444,18 @@ Bool_t   AliRawReaderHLT::ReadNextHLTData()
        pSystem->ScanOptions(fSystemOptions.Data());
       }
       if (result=(fpHLTOUT->Init()>=0)) {
-       result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
-                                             AliHLTModuleAgent::kRawReader)>=0;
       }
     }
+    }
+    if (result) {
+      result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
+                                           AliHLTModuleAgent::kRawReader)>=0;
+    }
+    fbReadFirst=false;
   } else {
     // first release the data buffer
-    if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
-    else fpHLTOUT->ReleaseDataBuffer(fpData);
-    fpDataHandler=NULL;
-    fpData=NULL;
-    if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) {
-      delete fpHLTOUT;
-      fpHLTOUT=NULL;
-    }
+    ReleaseHLTData(false /* keep HLTOUT instance */);
+    result=fpHLTOUT->SelectNextDataBlock()>=0;
   }
   if (result) {
     AliHLTComponentDataType dt=kAliHLTVoidDataType;
@@ -476,6 +471,7 @@ Bool_t   AliRawReaderHLT::ReadNextHLTData()
        fDataSize=pHandler->GetProcessedData(fpData);
        if (!fpData) {
          result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
+         fpDataHandler=NULL;
          AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
          fDataSize=(int)size;
        } else {
@@ -493,10 +489,7 @@ Bool_t   AliRawReaderHLT::ReadNextHLTData()
                      fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
     }
   } else {
-    fpData=NULL;
-    fDataSize=0;
-    fOffset=0;
-    fEquipmentId=-1;
+    ReleaseHLTData(false /* keep HLTOUT instance */);
   }
   return kFALSE;
 }
@@ -514,6 +507,46 @@ Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
   return kFALSE;
 }
 
+int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
+{
+  // see header file for class documentation
+  if (fpHLTOUT) {
+    if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
+    else fpHLTOUT->ReleaseDataBuffer(fpData);
+    fpDataHandler=NULL;
+    if (bReleaseHLTOUT) {
+      delete fpHLTOUT;
+      fpHLTOUT=NULL;
+    }
+  }
+
+  fpData=NULL;
+  fDataSize=0;
+  fOffset=0;
+  fPosition=0;
+  fEquipmentId=-1;
+
+  return 0;
+}
+
+Bool_t AliRawReaderHLT::EvaluateSelection()
+{
+  // see header file for class documentation
+  Bool_t bHaveHLTData=kFALSE;
+  if (bHaveHLTData=(fDetectors.size()>0)) {
+    vector<int>::iterator detector=fDetectors.begin();
+    for (; detector!=fDetectors.end(); detector++) {
+      int ddlOffset=AliDAQ::DdlIDOffset(*detector);
+      int nofDDLs=AliDAQ::NumberOfDdls(*detector);
+      if ((fSelectMinEquipmentId<0 || fSelectMinEquipmentId<ddlOffset+nofDDLs) &&
+         (fSelectMaxEquipmentId<0 || fSelectMaxEquipmentId>=ddlOffset))
+       break;
+    }
+    bHaveHLTData=detector!=fDetectors.end();
+  }
+  return bHaveHLTData;
+}
+
 AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
 {
   // see header file for class documentation