source: trunk/FACT++/src/DimServerList.cc@ 12105

Last change on this file since 12105 was 11730, checked in by tbretz, 13 years ago
When removing something from a list we have to pass a copy instead of a reference otherwise the removal might remove the source of the reference.
File size: 4.3 KB
Line 
1// **************************************************************************
2/** @class DimServerList
3
4@brief Maintains a list of all servers based on DIS_DNS/SERVER_LIST
5
6This class describes to the service DIS_DNS/SERVER_LIST of the name server.
7Thus it always contains an up-to-date list of all servers connected
8to the dns server.
9
10Whenever a server is added or removed, or all servers are removed from the
11#list (the dns itself went offline), the follwoing virtual functions are
12called:
13
14- virtual void AddServer(const std::string &)
15- virtual void RemoveServer(const std::string)
16- virtual void RemoveAllServers()
17
18If overwritten the implementations of the base class doesn't need to be
19called, because it's empty.
20
21@Bugs When a server silently disappears and reappears the service has
22not correctly been deleted from the list and an exception is thrown.
23It is not clear what a better handling here is. Maybe a server is
24first removed from the list before it gets re-added if already in the list?
25
26*/
27// **************************************************************************
28#include "DimServerList.h"
29
30#include <sstream>
31#include <algorithm>
32#include <stdexcept>
33
34using namespace std;
35
36// --------------------------------------------------------------------------
37//
38//! Constructs the DimServerList. Subscribes a DimInfo to
39//! DIS_DNS/SERVER_LIST.
40//
41DimServerList::DimServerList() :
42 fDimServers("DIS_DNS/SERVER_LIST", const_cast<char*>(""), this)
43{
44}
45
46// --------------------------------------------------------------------------
47//
48//! Whenever the service with the server list is updated this functions
49//! changes the contents of the list and calls RemoveAllServers(),
50//! RemoveServer() and AddServer() where appropriate.
51//
52void DimServerList::infoHandler()
53{
54 if (getInfo()!=&fDimServers)
55 return;
56
57 // Get the received string from the handler
58 const string str = fDimServers.getString();
59
60 // Check if it starts with + or -
61 if (str[0]!='-' && str[0]!='+')
62 {
63 RemoveAllServers();
64 fServerList.clear();
65 }
66
67 // Create a stringstream to tokenize the received string
68 stringstream stream(str);
69
70 // Loop over the seperating tokens
71 string buffer;
72 while (getline(stream, buffer, '|'))
73 {
74 // The first part before the first @ is the server name
75 const string server = buffer.substr(0, buffer.find_first_of('@'));
76 if (server.empty())
77 continue;
78
79 // If it starts with a - we have to remove an entry
80 if (server[0]=='-')
81 {
82 const string trunc = server.substr(1);
83
84 // Check if this server is not found in the list.
85 // This should never happen if Dim works reliable
86 const ServerList::iterator v = find(fServerList.begin(), fServerList.end(), trunc);
87 if (v==fServerList.end())
88 {
89 stringstream err;
90 err << "Server '" << trunc << "' not in list as it ought to be.";
91 throw runtime_error(err.str());
92 }
93
94 RemoveServer(trunc);
95 fServerList.erase(v);
96
97 continue;
98 }
99
100 // If it starts with a + we have to add an entry
101 if (server[0]=='+')
102 {
103 const string trunc = server.substr(1);
104
105 // Check if this server is already in the list.
106 // This should never happen if Dim works reliable
107 const ServerList::iterator v = find(fServerList.begin(), fServerList.end(), trunc);
108 if (v!=fServerList.end())
109 {
110 stringstream err;
111 err << "Server '" << trunc << "' in list not as it ought to be.";
112 throw runtime_error(err.str());
113 }
114
115 fServerList.push_back(trunc);
116 AddServer(trunc);
117
118 continue;
119 }
120
121 // In any other case we just add the entry to the list
122 fServerList.push_back(server);
123 AddServer(server);
124 }
125}
126
127// --------------------------------------------------------------------------
128//
129//! @param server
130//! server-name to check for
131//!
132//! @returns
133//! whether the server with the given name is online or not
134//!
135bool DimServerList::HasServer(const std::string &server) const
136{
137 return find(fServerList.begin(), fServerList.end(), server)!=fServerList.end();
138}
Note: See TracBrowser for help on using the repository browser.