/** * @file broker.cc * @brief Implementation of the Broker class * @author Andreas Aardal Hanssen * @date 2002-2005 */ #include "broker.h" #include "convert.h" #include "operators.h" #include "recursivedescent.h" #include "session.h" #include #include using namespace Binc; using std::string; BrokerFactory::BrokerFactory(void) { brokers[Session::NONAUTHENTICATED] = new Broker(); brokers[Session::AUTHENTICATED] = new Broker(); brokers[Session::SELECTED] = new Broker(); } BrokerFactory::~BrokerFactory(void) { for (auto &[_, second] : brokers) delete second; } BrokerFactory &BrokerFactory::getInstance(void) { static BrokerFactory brokerfactory; return brokerfactory; } void BrokerFactory::addCapability(const std::string &c) { for (const auto &[_, second] : brokers) { auto o = dynamic_cast(second->get("CAPABILITY")); if (o != nullptr) { o->addCapability(c); break; } } } void BrokerFactory::assign(const string &fname, Operator *o) { int deletable = true; for (const auto &[first, second] : brokers) { if (first & o->getState()) { second->assign(fname, o, deletable); deletable = false; } } } Operator *BrokerFactory::getOperator(int state, const string &name) const { if (brokers.find(state) == brokers.end()) return nullptr; else return brokers.find(state)->second->get(name); } Broker *BrokerFactory::getBroker(int state) { if (brokers.find(state) == brokers.end()) { setLastError("No appropriate broker for state."); return nullptr; } return brokers[state]; } Broker::Broker(void) {} Broker::~Broker(void) {} void Broker::assign(const string &fname, Operator *o, bool deletable) { deletables[fname] = deletable; operators[fname] = o; } Operator *Broker::get(const string &name) const { if (operators.find(name) == operators.end()) return nullptr; return operators.find(name)->second; } Operator::ParseResult Broker::parseStub(Request &command) { Session &session = Session::getInstance(); string tag; string cmd; switch (expectTag(tag)) { case Operator::ACCEPT: break; case Operator::REJECT: session.setLastError("Syntax error; first token must be a tag"); [[fallthrough]]; case Operator::ERROR: return Operator::ERROR; case Operator::TIMEOUT: return Operator::TIMEOUT; } switch (expectSPACE()) { case Operator::ACCEPT: break; case Operator::REJECT: session.setLastError("Syntax error; second token must be a SPACE"); [[fallthrough]]; case Operator::ERROR: return Operator::ERROR; case Operator::TIMEOUT: return Operator::TIMEOUT; } switch (expectAstring(cmd)) { case Operator::ACCEPT: break; case Operator::REJECT: session.setLastError("Syntax error; third token must be a command"); [[fallthrough]]; case Operator::ERROR: return Operator::ERROR; case Operator::TIMEOUT: return Operator::TIMEOUT; } uppercase(cmd); if (cmd == "UID") { command.setUidMode(); switch (expectSPACE()) { case Operator::ACCEPT: break; case Operator::REJECT: session.setLastError("Syntax error; after UID there must come a SPACE"); [[fallthrough]]; case Operator::ERROR: return Operator::ERROR; case Operator::TIMEOUT: return Operator::TIMEOUT; } switch (expectAstring(cmd)) { case Operator::ACCEPT: break; case Operator::REJECT: session.setLastError("Syntax error; after UID SPACE there must come a command"); [[fallthrough]]; case Operator::ERROR: return Operator::ERROR; case Operator::TIMEOUT: return Operator::TIMEOUT; } uppercase(cmd); } command.setTag(tag); command.setName(cmd); return Operator::ACCEPT; }