#include #include "ICOMETEvent.hxx" #include "IEventFolder.hxx" #include "IOADatabase.hxx" #include "IDigitManager.hxx" #include "ICOMETLog.hxx" COMET::IDigitManager::IDigitManager() : fPersistentDigits(false) {} COMET::IDigitManager::~IDigitManager() {} void COMET::IDigitManager::RegisterFactory(COMET::IDigitFactory* factory) { std::string name = factory->GetName(); if (fFactories.find(name) != fFactories.end()) { throw COMET::EMultipleDigitFact(); } fFactories[name] = factory; } bool COMET::IDigitManager::FactoryAvailable(std::string type) const { return (fFactories.find(type) != fFactories.end()); } COMET::IHandle COMET::IDigitManager::CacheDigits(std::string type) { // Check to see if the digits already exist in the current event. COMET::ICOMETEvent* event = IEventFolder::GetCurrentEvent(); if (!event) { throw EDigitEventMissing(); } return CacheDigits(*event,type); } COMET::IHandle COMET::IDigitManager::CacheDigits(COMET::ICOMETEvent& event, std::string type) { COMET::IHandle digits = event.Get("~/digits/"+type); if (digits) return digits; // The digits don't exist in the event, so try to generate them using the // IDigitFactory. COMET::IDigitFactory* factory = fFactories[type]; if (!factory) return COMET::IHandle(); digits = COMET::IHandle(factory->MakeDigits()); if (!digits) { COMETWarn("The " << factory->GetName() << " digit factory failed"); return COMET::IHandle(); } digits->SetName(type.c_str()); // Save the digits in the current event. COMET::IHandle d = event.Get("~/digits"); if (!fPersistentDigits) d->AddTemporary(digits); else d->AddDatum(digits); return digits; } COMET::IHandle COMET::IDigitManager::FindDigits(const IDigitProxy& proxy) { std::string name = IDigitProxy::ConvertType(proxy.GetProxyType()); // Check to see if the IDigitContainer is already part of the event. COMET::IHandle digits = CacheDigits(name); return digits; } COMET::IDigit* COMET::IDigitManager::GetDigit(const IDigitProxy& proxy) { std::string name; // Check to see if the proxy has already cached the pointer. IDigit* pointer = proxy.GetProxyCache(); if (pointer) return pointer; // Find the digits in the event. This will regenerate the IDigitContainer // if necessary (and possible). COMET::IHandle digits = FindDigits(proxy); if (!digits) throw EDigitNotAvailable(); // Get the offset of the digit inside of the container and throw an // exception if the offset is invalid. unsigned int offset = proxy.GetProxyOffset(); if (!(offsetsize())) throw EDigitNotFound(); pointer = digits->at(offset); // Check that the proxy salt matches the container and digit. Throw an // exception if the salt doesn't match. if (!proxy.CheckSalt(digits->GetSignature(),pointer)) throw EDigitMismatch(); /// Cache the container and digit for future lookup. proxy.SetProxyCache(pointer,COMET::GetPointer(digits)); return pointer; } COMET::IDigitFactory::IDigitFactory(std::string name) : fName(name) {} COMET::IDigitFactory::~IDigitFactory() {} std::string COMET::IDigitFactory::GetName() { return fName; }