/** * @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() { brokers[Session::State::NONAUTHENTICATED] = new Broker(); brokers[Session::State::AUTHENTICATED] = new Broker(); brokers[Session::State::SELECTED] = new Broker(); } BrokerFactory::~BrokerFactory() { for (auto &[_, second] : brokers) delete second; } BrokerFactory &BrokerFactory::getInstance() { 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(Session::State state, const string &name) const { if (brokers.find(state) == brokers.end()) return nullptr; else return brokers.find(state)->second->get(name); } Broker *BrokerFactory::getBroker(Session::State state) { auto it = brokers.find(state); if (it == brokers.end()) { setLastError("No appropriate broker for state."); return nullptr; } return it->second; } 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; } Parser::ParseResult Broker::parseStub(Request &command) { constexpr auto ACCEPT = Parser::ParseResult::ACCEPT; constexpr auto REJECT = Parser::ParseResult::REJECT; constexpr auto ERROR = Parser::ParseResult::ERROR; constexpr auto TIMEOUT = Parser::ParseResult::TIMEOUT; Session &session = Session::getInstance(); string tag; string cmd; switch (expectTag(tag)) { case ACCEPT: break; case REJECT: session.setLastError("Syntax error; first token must be a tag"); [[fallthrough]]; case ERROR: return ERROR; case TIMEOUT: return TIMEOUT; } switch (expectSPACE()) { case ACCEPT: break; case REJECT: session.setLastError("Syntax error; second token must be a SPACE"); [[fallthrough]]; case ERROR: return ERROR; case TIMEOUT: return TIMEOUT; } switch (expectAstring(cmd)) { case ACCEPT: break; case REJECT: session.setLastError("Syntax error; third token must be a command"); [[fallthrough]]; case ERROR: return ERROR; case TIMEOUT: return TIMEOUT; } uppercase(cmd); if (cmd == "UID") { command.setUidMode(); switch (expectSPACE()) { case ACCEPT: break; case REJECT: session.setLastError("Syntax error; after UID there must come a SPACE"); [[fallthrough]]; case ERROR: return ERROR; case TIMEOUT: return TIMEOUT; } switch (expectAstring(cmd)) { case ACCEPT: break; case REJECT: session.setLastError("Syntax error; after UID SPACE there must come a command"); [[fallthrough]]; case ERROR: return ERROR; case TIMEOUT: return TIMEOUT; } uppercase(cmd); } command.setTag(tag); command.setName(cmd); return ACCEPT; }