#include "TString.h" #include "IMidasBank.hxx" #include "IMidasItr.hxx" #include "ICOMETLog.hxx" //_____________________________________________________________________________ template COMET::IMidasItr::IMidasItr(UShort_t rawDataVer /* = 0 */, UShort_t invalid_code /* = 0 */, const IMidasBank* parent /*= 0*/, Int_t size /* = -1 */) : IMidasObj(rawDataVer,invalid_code,parent), fIndex(0), fSize(size), fChannelInfo(0) { if ( parent ) fChannelInfo = parent->GetChannelInfo(); } //_____________________________________________________________________________ template COMET::IMidasItr::~IMidasItr() {} //_____________________________________________________________________________ template T COMET::IMidasItr::Get() { // Get next element of list. Return invalid element if list already exhausted or iterator invalid. T elem = this->GetImp(); if ( this->NotValid("Get") ) elem.SetInvalidCode(this->GetInvalidCode()); if ( elem.IsValid() ) ++fIndex; return elem; } //_____________________________________________________________________________ template void COMET::IMidasItr::GetSet(std::vector& vec) const { // Return the complete set as a vector for random access. // Caller must pass in the vector which is cleared before use. // Caution: involves iteration and resulting list may be heavyweight if ( this->NotValid("GetSet") ) return; // See e.g. Print() for this naughty casting away of const. IMidasItr* nc_this = const_cast*>(this); UInt_t old_index = nc_this->GetIndex(); vec.clear(); nc_this->Rewind(); while ( ! nc_this->EOD() ) { T elem = nc_this->Get(); if ( elem.IsValid() ) vec.push_back(elem); else break; } nc_this->SetPosition(old_index); } //_____________________________________________________________________________ template void COMET::IMidasItr::Print(const Option_t* opt /* = "" */) const { /// This is naturally a const method but is implement by rewinding, /// iterating and finally restoring current position so has to cast /// away constness. if ( this->NotValid("Print") ) return; IMidasItr* nc_this = const_cast*>(this); UInt_t old_index = nc_this->GetIndex(); // Use option to decide how many elements to print. TString option = opt; option.ToLower(); UInt_t num_elem = this->Size(); UInt_t num_half_print = 0; if ( option.Contains("i") ) num_half_print = 2; if ( option.Contains("v") ) num_half_print = 99; if ( option.Contains("vv") ) num_half_print = 999999999; if ( num_half_print == 0 ) return; UInt_t startSkipIndex = num_half_print; UInt_t endSkipIndex = num_elem -1 - num_half_print; if ( 2*num_half_print > num_elem ) endSkipIndex = startSkipIndex -1; // Print elements skipping any whose index is in range startSkipIndex .. endSkipIndex nc_this->Rewind(); while ( ! nc_this->EOD() ) { UInt_t index = fIndex; // Record current index before Get bumps it on. T elem = nc_this->Get(); if ( index < startSkipIndex || index > endSkipIndex ) elem.Print(opt); if ( index == startSkipIndex ) COMETLog(" ......"); } nc_this->SetPosition(old_index); } //_____________________________________________________________________________ template void COMET::IMidasItr::Rewind() { this->RewindImp(); fIndex = 0; } //_____________________________________________________________________________ template Bool_t COMET::IMidasItr::SetPosition(UInt_t index) { if ( this->NotValid("SetPosition") ) return false; // Position to specified index and return true if successful. if ( index < 0 ) return false; if ( index < fIndex ) this->Rewind(); while ( ! this->EOD() ) { T elem = this->Get(); if ( ! elem.IsValid() ) return false; if ( index == fIndex ) return true; } return false; } //_____________________________________________________________________________ template UInt_t COMET::IMidasItr::Size() const { if ( this->NotValid("Size") ) return 0; if ( fSize >= 0 ) return fSize; /// The size is unknown so must count every element in the list /// without disturbing the current position as this is a const /// method. Do this but casting away constness, rewinding, /// iterating and finally restoring current position. IMidasItr* nc_this = const_cast*>(this); UInt_t old_index = nc_this->GetIndex(); nc_this->Rewind(); while ( ! nc_this->EOD() ) nc_this->Get(); nc_this->fSize = nc_this->GetIndex(); nc_this->SetPosition(old_index); return fSize; }