#ifndef TDemo2Bank_hxx_seen
#define TDemo2Bank_hxx_seen
// $Id: IDemo2Bank.hxx,v 1.6 2009/09/25 06:02:32 nickwest Exp $
#include "ICOMETLog.hxx"
#include "IMidasBank.hxx"
#include "IMidasObj.hxx"
#include "IMidasItr.hxx"
#define TDEMO2_BANK_TITLE "Raw Demo2 Bank"
namespace COMET {
class IDemo2Bank;
class IMidasDemo2BlockItr;
class IMidasDemo2Block;
};
/// This class, and its companion IDemo1Bank, demonstrate how all the
/// raw DAQ data is made accessible via a set of TXxxBank classes,
/// see IDemo1Bank for an introduction.
///
/// This example has some more interesting getters and demonstrates:-
///
///- A bank with internal (RawDemo2Block) sub-block structure with iteration.
///
///
- Access as if the data were 32-bit array rather than the underlying
/// 64-bit.
///
/// The Demo2Bank consists of a series of 32-bit RawDemo2Block with the
/// structure:-
///
/// + 0 No of 32-bit words following (at least 1)
/// + 1 sub-block ID
/// + 2 First data word
///
/// The class provide 2 getters:-
///\code
/// Int_t GetNumSubBlocks() const;
/// IMidasDemo2BlockItr GetMidasDemo2BlockItr() const;
///\endcode
/// The IMidasDemo2BlockItr is a simple iterator object with the following methods:-
///
/// Positioning:-
///\code
/// void Rewind()
///\endcode
/// Testing:-
///\code
/// Bool_t EOD()const
/// UInt_t Size()const
///\endcode
/// Sub-block access
///\code
/// IMidasDemo2Block Get() const
///\endcode
/// IMidasDemo2Block has the following methods:-
///\code
/// Int_t GetID() const
/// UInt_t GetSize() const
/// const UInt_t* GetData() const
///
///\endcode
/// The following is a and a trivial example of its use:-
///\code
/// void Demo(COMET::ICOMETRawEvent& revt) {
///
/// // Get a IDemo2Bank object
/// COMET::IHandle h = revt.GetMidasBank("");
/// if ( ! h ) return;
///
/// COMET::IMidasDemo2BlockItr itr = h->GetMidasDemo2BlockItr();
/// std::cout << "Bank " << h->GetName()
/// << " contains the following " << itr->Size();
/// << " sub-blocks:-" << std::endl;
/// while ( COMET::IMidasDemo2Block sb = itr.Get() )
/// std::cout << "sub-block ID " << sb.GetID()
/// << " length " << sb.GetSize()
/// << " first data word " << *(sb.GetData())
/// << std::endl;
/// }
///\endcode
//_____________________________________________________________________________
class COMET::IMidasDemo2Block : public COMET::IMidasObj {
private:
Int_t fId;
UInt_t fSize;
const UInt_t* fDdata;
public:
IMidasDemo2Block(UShort_t invalid_code, Int_t id, UInt_t size, const UInt_t* data) :
IMidasObj(0,invalid_code),fId(id),fSize(size),fDdata(data) {}
~IMidasDemo2Block() {}
Int_t GetID() const { return fId; }
UInt_t GetSize() const { return fSize; }
const UInt_t* GetData() const { return fDdata; }
virtual void Print(const Option_t* opt = "") const {
UInt_t fdw = this->GetSize() ? *(this->GetData()) : 0;
COMETLog(" sub-block ID " << this->GetID()
<< " length " << this->GetSize()
<< " first data word " << fdw);
}
};
//_____________________________________________________________________________
class COMET::IMidasDemo2BlockItr: public COMET::IMidasItr {
private:
/// Pointers to first, next and last RawDemo2Block sub-blocks.
/// If there are no sub-blocks all pointers are set to zero
const UInt_t* fFirst;
const UInt_t* fNext; // if > fLast then EOD (End of Data)
const UInt_t* fLast;
public:
IMidasDemo2BlockItr(const COMET::IMidasBank* parent=0, const UInt_t* first=0, const UInt_t* last=0) :
IMidasItr(0,0,parent),
fFirst(first),fNext(first),fLast(last) {}
~IMidasDemo2BlockItr() {}
protected:
/// Implement methods mandated by IMidasItr.
virtual Bool_t EODImp() const { return ! fFirst || fNext > fLast ; }
virtual IMidasDemo2Block GetImp() {
if ( this->EODImp() ) return IMidasDemo2Block(IMidasObj::IteratorOutOfRange,0,0,0);
UInt_t size = *fNext;
Int_t id = *(fNext+1);
const UInt_t* data = fNext+2;
fNext += size + 1;
return IMidasDemo2Block(0,id,size,data);
}
virtual void RewindImp() { fNext = fFirst; };
};
//_____________________________________________________________________________
class COMET::IDemo2Bank : public COMET::IMidasBank {
public:
IDemo2Bank();
explicit IDemo2Bank(const ULong64_t *bank,
const char* title = TDEMO2_BANK_TITLE);
virtual ~IDemo2Bank();
/// Return the number of RawDemo2Block sub-blocks
UInt_t GetNumSubBlocks() const { return fNumSubBlocks;}
/// Return an iterator to access the IMidasDemo2Block sub-blocks
COMET::IMidasDemo2BlockItr GetMidasDemo2BlockItr() const { return IMidasDemo2BlockItr(this,fFirst,fLast); }
/// Print contents to COMETLog
void Print(const Option_t* opt = "") const;
private:
void Init();
/// Number of sub-blocks
UInt_t fNumSubBlocks;
/// Pointers to first and last sub-block.
/// If there are no sub-blocks both pointers are set to zero
const UInt_t* fFirst;
const UInt_t* fLast;
};
#endif