#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:- /// /// 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