CEventServer.C
//-----------------------------------------------------------------------------
// $Header: /tmp_mnt/asis/offline/ceres/cool/project/RCS/CEventServer.C,v 2.1 1996/10/04 08:43:03 voigt Exp $
//
// COOL Program Library
// Copyright (C) CERES collaboration, 1996
//
// Implementation of class CEventServer.
//
//-----------------------------------------------------------------------------
#include "CEventServer.h"
#include <unistd.h>
#include <iomanip.h>
#include <stdlib.h>
CEventServer::CEventServer()
{
currentEvent = 0;
sor = 0;
eor = 0;
sob = 0;
eob = 0;
oob = 0;
evt = 0;
evtCounter = 0;
sobCounter = 0;
eobCounter = 0;
sorCounter = 0;
eorCounter = 0;
oobCounter = 0;
}
CEventServer::CEventServer(const char* name)
{
currentEvent = 0;
sor = 0;
eor = 0;
sob = 0;
eob = 0;
oob = 0;
evt = 0;
evtCounter = 0;
sobCounter = 0;
eobCounter = 0;
sorCounter = 0;
eorCounter = 0;
oobCounter = 0;
setInput(name);
}
CEventServer::CEventServer(const CEventServer&)
{
cerr << "CEventServer::CEventServer(const CEventServer&):\n";
cerr << "\tFATAL ERROR\n";
cerr << "\tCopy constructor for class CEventServer is not implemented.\n";
cerr << "\tStopping current application to prevent unpredictable results.\n";
exit(1);
}
CEventServer& CEventServer::operator= (const CEventServer&)
{
cerr << "CEventServer::operator= (const CEventServer&):\n";
cerr << "\tFATAL ERROR\n";
cerr << "\tAssignement operator for class CEventServer is not implemented.\n";
cerr << "\tStopping current application to prevent unpredictable results.\n";
exit(1);
return *this;
}
CEventServer::~CEventServer()
{
delete sor;
delete eor;
delete sob;
delete eob;
delete oob;
delete evt;
ifs.close();
eventTable.clearAndDestroy();
}
CEventType CEventServer::getCurrentEventType() const
{
if (currentEvent)
return currentEvent->getEventType();
else
return NoRoot;
}
CBoolean CEventServer::loadEvent(unsigned event)
{
int currentEventNumber = evt != 0 ? evt->getEventNumber() : 0;
if (currentEventNumber == event) // event already loaded
return True;
//
// Check in the event table if an entry for
// the referring event number exist.
//
streampos newPos = 0;
for (int i=0; i<eventTable.length(); i++) {
if (eventTable[i]->evtNr <= event)
newPos = eventTable[i]->pos;
else
break;
}
//
// Event still to come and no entry in table found
//
if (newPos == 0 && event > currentEventNumber)
newPos = ifs.tellg();
ifs.seekg(newPos); // skip to new position
//
// Search the requested event.
// Stop if the event is found or if an event (type Evt) is encountered
// with an event number larger than the requested one. In the latter
// case a warning message is printed.
//
CBoolean rc;
while ((rc = loadNextEvent()) &&
(currentEvent->getEventType() == Evt ? evt->getEventNumber() < event : True));
if (!rc) {
cerr << "CEventServer::loadEvent():\n";
cerr << "\tERROR\n";
cerr << "\tError during search for requested event with number " << event << ".\n";
return False;
}
if (evt->getEventNumber() != event) {
cerr << "CEventServer::loadEvent():\n";
cerr << "\tWARNING\n";
cerr << "\tCannot find requested event with number " << event << ".\n";
cerr << "\tNext valid event with number " << evt->getEventNumber() << " loaded.\n";
}
return True;
}
CBoolean CEventServer::loadNextEvent()
{
//
// Check if stream is proper state
//
if (ifs.eof()) {
cerr << "CEventServer::loadNextEvent():\n";
cerr << "\tWARNING\n";
cerr << "\tEoF of file '" << filename << "' reached.\n";
cerr << "\tCannot load new events.\n";
return False;
}
if (ifs.fail()) {
cerr << "CEventServer::loadNextEvent():\n";
cerr << "\tERROR\n";
cerr << "\tFail bit set for file stream '" << filename << "'.\n";
cerr << "\tCannot load new events.";
return False;
}
//
// Read the first label (root label) to check its type.
// Position the stream back to the previous position.
// Break if the stream is corrupted or EoF is reached.
//
streampos currentPos = ifs.tellg();
CLabel *spyLabel = new CLabel;
spyLabel->read(ifs);
while (CGetEventType(spyLabel) == NoRoot && ifs.good() && !ifs.eof()) {
currentPos = ifs.tellg();
spyLabel->read(ifs);
}
if (ifs.fail() || ifs.eof()) {
delete spyLabel;
return False;
}
ifs.seekg(currentPos);
//
// Assign the new event according to its type.
// Each 10th event of type Evt is filled into
// the event table.
//
switch (CGetEventType(spyLabel)) {
case Evt:
delete evt;
evt = new CRawEvt;
evt->readEvent(ifs);
evt->unpackRootLabel();
currentEvent = evt;
evtCounter++;
if (evtCounter%10 == 0)
eventTable.insert(new CEventTableEntry(evt->getEventNumber(), currentPos));
break;
case SoR:
delete sor;
sor = new CRawSoR;
sor->readEvent(ifs);
sor->unpackRootLabel();
currentEvent = sor;
sorCounter++;
break;
case SoB:
delete sob;
sob = new CRawSoB;
sob->readEvent(ifs);
sob->unpackRootLabel();
currentEvent = sob;
sobCounter++;
break;
case EoR:
delete eor;
eor = new CRawEoR;
eor->readEvent(ifs);
eor->unpackRootLabel();
currentEvent = eor;
eorCounter++;
break;
case EoB:
delete eob;
eob = new CRawEoB;
eob->readEvent(ifs);
eob->unpackRootLabel();
currentEvent = eob;
eobCounter++;
break;
case OoB:
delete oob;
oob = new CRawOoB;
oob->readEvent(ifs);
oob->unpackRootLabel();
currentEvent = oob;
oobCounter++;
break;
default:
currentEvent = 0;
delete spyLabel;
return False;
}
delete spyLabel;
return (!ifs.fail() && !ifs.eof());
}
void CEventServer::setInput(const char* name)
{
//
// Check if file exist
//
if (access(name, F_OK) == -1) {
cerr << "CEventServer::CEventServer():\n";
cerr << "\tERROR\n";
cerr << "\tFile '" << name << "' doesn't exist.\n";
cerr << "\tNo valid input source connected to server.\n";
return;
};
//
// Check if file is readable
//
if (access(name, R_OK) == -1) {
cerr << "CEventServer::CEventServer():\n";
cerr << "\tERROR\n";
cerr << "\tFile '" << name << "' has no read permission.\n";
cerr << "\tNo valid input source connected to server.\n";
return;
};
//
// Open input stream, reset internal tables
//
eventTable.clearAndDestroy();
ifs.close();
filename = name;
ifs.open(name);
//
// Check status
//
if (!ifs) {
cerr << "CEventServer::CEventServer():\n";
cerr << "\tERROR\n";
cerr << "\tFailed to open file '" << name << "'.\n";
cerr << "\tifs.rdstate()=" << dec << ifs.rdstate() << endl;
cerr << "\tNo valid input source connected to server.\n";
filename = "";
}
}
void CEventServer::listLabels(ostream& ost)
{
ost << endl;
ost << setw(10) << "name"
<< setw(10) << "id"
<< setw(10) << "length"
<< setw(10) << "size" << endl;
CString line('=', 46);
ost << line << endl;
if(sor != 0) sor->listLabels(ost);
if(sob != 0) sob->listLabels(ost);
if(evt != 0) evt->listLabels(ost);
if(eob != 0) eob->listLabels(ost);
if(oob != 0) oob->listLabels(ost);
if(eor != 0) eor->listLabels(ost);
}
const CLabel* CEventServer::getLabel(CLabelId id)
{
CLabel *label = 0;
if (evt != 0)
if (label = (CLabel*) evt->getLabel(id)) return label;
if (sob != 0)
if (label = (CLabel*) sob->getLabel(id)) return label;
if (eob != 0)
if (label = (CLabel*) eob->getLabel(id)) return label;
if (sor != 0)
if (label = (CLabel*) sor->getLabel(id)) return label;
if (eor != 0)
if (label = (CLabel*) eor->getLabel(id)) return label;
if (oob != 0)
if (label = (CLabel*) oob->getLabel(id)) return label;
return label;
}
const CLabel* CEventServer::getLabel(CLabelId id, CEventType typ)
{
CLabel *label = 0;
if (evt != 0 && typ == Evt)
if (label = (CLabel*) evt->getLabel(id)) return label;
if (sob != 0 && typ == SoB)
if (label = (CLabel*) sob->getLabel(id)) return label;
if (eob != 0 && typ == EoB)
if (label = (CLabel*) eob->getLabel(id)) return label;
if (sor != 0 && typ == SoR)
if (label = (CLabel*) sor->getLabel(id)) return label;
if (eor != 0 && typ == EoR)
if (label = (CLabel*) eor->getLabel(id)) return label;
if (oob != 0 && typ == OoB)
if (label = (CLabel*) oob->getLabel(id)) return label;
return label;
}
void CEventServer::printSummary(ostream& ost)
{
int total = evtCounter+sobCounter+eobCounter+
sorCounter+eorCounter+oobCounter;
ost << "\nEvent Server Summary\n";
CString line('=', 46);
ost << line << endl;
ost << "Open file: " << filename << endl;
ost << "File offset: " << ifs.tellg() << endl;
ost << "Total events read: " << dec << total << endl;
ost << "Evt events read: " << dec << evtCounter << endl;
ost << "SoB events read: " << dec << sobCounter << endl;
ost << "EoB events read: " << dec << eobCounter << endl;
ost << "SoR events read: " << dec << sorCounter << endl;
ost << "EoR events read: " << dec << eorCounter << endl;
ost << "OoB events read: " << dec << oobCounter << endl;
ost << "Stream error state: " << ifs.rdstate() << endl;
}
void CEventServer::printIndex(ostream& ost)
{
switch (getCurrentEventType()) {
case Evt:
ost << "[Evt]";
ost << "\trun: " << evt->getRunNumber()
<< "\tburst: " << evt->getBurstNumber()
<< "\tevent: " << evt->getEventNumber()
<< endl;
break;
case SoB:
ost << "[SoB]";
ost << "\trun: " << sob->getRunNumber()
<< "\tburst: " << sob->getBurstNumber()
<< endl;
break;
case EoB:
ost << "[EoB]";
ost << "\trun: " << eob->getRunNumber()
<< "\tburst: " << eob->getBurstNumber()
<< endl;
break;
case SoR:
ost << "[SoR]";
ost << "\trun: " << sor->getRunNumber()
<< "\ttime: " << sor->getTime()
<< endl;
break;
case EoR:
ost << "[EoR]";
ost << "\trun: " << eor->getRunNumber()
<< "\ttime: " << eor->getTime()
<< endl;
break;
case OoB:
ost << "[OoB]";
ost << "\trun: " << oob->getRunNumber()
<< "\tburst: " << oob->getBurstNumber()
<< "\tevent: " << oob->getEventNumber()
<< endl;
break;
default:
ost << "[???]\n";
break;
}
}