// ************************************************************************** /** @class DimServerList @brief Maintains a list of all servers based on DIS_DNS/SERVER_LIST This class describes to the service DIS_DNS/SERVER_LIST of the name server. Thus it always contains an up-to-date list of all servers connected to the dns server. Whenever a server is added or removed, or all servers are removed from the #list (the dns itself went offline), the follwoing virtual functions are called: - virtual void AddServer(const std::string &) - virtual void RemoveServer(const std::string &) - virtual void RemoveAllServers() If overwritten the implementations of the base class doesn't need to be called, because it's empty. @Bugs When a server silently disappears and reappears the service has not correctly been deleted from the list and an exception is thrown. It is not clear what a better handling here is. Maybe a server is first removed from the list before it gets re-added if already in the list? */ // ************************************************************************** #include "DimServerList.h" #include #include #include using namespace std; // -------------------------------------------------------------------------- // //! Constructs the DimServerList. Subscribes a DimInfo to //! DIS_DNS/SERVER_LIST. // DimServerList::DimServerList() : fDimServers("DIS_DNS/SERVER_LIST", const_cast(""), this) { } // -------------------------------------------------------------------------- // //! Whenever the service with the server list is updated this functions //! changes the contents of the list and calls RemoveAllServers(), //! RemoveServer() and AddServer() where appropriate. // void DimServerList::infoHandler() { if (getInfo()!=&fDimServers) return; // Get the received string from the handler const string str = fDimServers.getString(); // Check if it starts with + or - if (str[0]!='-' && str[0]!='+') { RemoveAllServers(); fServerList.clear(); } // Create a stringstream to tokenize the received string stringstream stream(str); // Loop over the seperating tokens string buffer; while (getline(stream, buffer, '|')) { // The first part before the first @ is the server name const string server = buffer.substr(0, buffer.find_first_of('@')); if (server.empty()) continue; // If it starts with a - we have to remove an entry if (server[0]=='-') { const string trunc = server.substr(1); // Check if this server is not found in the list. // This should never happen if Dim works reliable const ServerList::iterator v = find(fServerList.begin(), fServerList.end(), trunc); if (v==fServerList.end()) { stringstream err; err << "Server '" << trunc << "' not in list as it ought to be."; throw runtime_error(err.str()); } RemoveServer(trunc); fServerList.erase(v); continue; } // If it starts with a + we have to add an entry if (server[0]=='+') { const string trunc = server.substr(1); // Check if this server is already in the list. // This should never happen if Dim works reliable const ServerList::iterator v = find(fServerList.begin(), fServerList.end(), trunc); if (v!=fServerList.end()) { stringstream err; err << "Server '" << trunc << "' in list not as it ought to be."; throw runtime_error(err.str()); } fServerList.push_back(trunc); AddServer(trunc); continue; } // In any other case we just add the entry to the list fServerList.push_back(server); AddServer(server); } } // -------------------------------------------------------------------------- // //! @param server //! server-name to check for //! //! @returns //! whether the server with the given name is online or not //! bool DimServerList::HasServer(const std::string &server) const { return find(fServerList.begin(), fServerList.end(), server)!=fServerList.end(); }