GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Server.h
Date: 2024-12-15 04:08:34
Exec Total Coverage
Lines: 8 9 88.9%
Branches: 12 20 60.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
6 *
7 * This file is part of the pdserv library.
8 *
9 * The pdserv library is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation, either version 3 of the License, or (at
12 * your option) any later version.
13 *
14 * The pdserv library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 * License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *****************************************************************************/
23
24 #ifndef MSRSERVER_H
25 #define MSRSERVER_H
26
27 #include <atomic>
28 #include <condition_variable>
29 #include <set>
30 #include <list>
31 #include <mutex>
32 #include <memory>
33 #include <string>
34 #include <log4cplus/logger.h>
35
36 #include "../PThread.h"
37 #include "../SessionStatistics.h"
38 #include "../Config.h"
39 #include "../DataType.h"
40 #include "DirectoryNode.h"
41
42 namespace PdServ {
43 class Main;
44 class Task;
45 class Parameter;
46 class Signal;
47 class Variable;
48 }
49
50 namespace net {
51 class TCPServer;
52 }
53
54 namespace MsrProto {
55
56 class Session;
57 class Parameter;
58 class Channel;
59
60 class Server: public pthread::Thread {
61 public:
62 enum State
63 {
64 Init,
65 Running,
66 Stopped,
67 };
68
69 Server(const PdServ::Main *main, const PdServ::Config &config);
70 ~Server();
71
72 // return: string <IP><sep><port> of connection
73 std::string getAddr(char sep = ':') const;
74
75 void broadcast(Session *s, const struct timespec& ts,
76 const std::string& action, const std::string& text);
77
78 void setAic(const Parameter*);
79 void parameterChanged(const PdServ::Parameter*,
80 size_t startIndex, size_t n,
81 const char* data, const struct timespec* time);
82
83 void sessionClosed(Session *s);
84 void sessionReady(Session *s);
85
86 void getSessionStatistics(
87 std::list<PdServ::SessionStatistics>& stats) const;
88
89 const PdServ::Main * const main;
90 log4cplus::Logger log;
91 const log4cplus::Logger broadcastLog;
92 9925 bool active() const { return state_ == Running; }
93
94 typedef std::vector<const Channel*> Channels;
95 typedef std::vector<const Parameter*> Parameters;
96
97 const Channels& getChannels() const;
98 const Channel * getChannel(size_t) const;
99 void listDir(PdServ::Session *, XmlElement& xml,
100 const std::string& path, bool hex, bool noderived) const;
101
102 const Parameters& getParameters() const;
103 const Parameter * getParameter(size_t) const;
104 const Parameter * find(const PdServ::Parameter *p) const;
105 size_t getMaxInputBufferSize() const;
106
107 template <typename T>
108 const T * find(const std::string& path) const;
109
110 private:
111 std::set<Session*> sessions, pending_sessions;
112
113 std::string bindaddr;
114
115 bool itemize; // Split multidimensional variables to scalars
116 std::atomic_int state_;
117 bool m_broadcast;
118
119 DirectoryNode variableDirectory;
120 DirectoryNode* insertRoot;
121
122 size_t maxConnections;
123 size_t maxInputBufferSize;
124
125 Channels channels;
126 Parameters parameters;
127
128 typedef std::map<const PdServ::Parameter *, const Parameter*>
129 ParameterMap;
130 ParameterMap parameterMap;
131
132 mutable std::mutex mutex;
133 std::condition_variable startup_cv;
134
135 std::unique_ptr<net::TCPServer> server;
136 #ifdef GNUTLS_FOUND
137 std::unique_ptr<net::TCPServer> secure_server;
138 std::string tlsbindaddr;
139 #endif
140
141 // Reimplemented from pthread::Thread
142 void initial();
143 void run();
144 void final();
145
146 int listenTo(const std::string& interface, const std::string& port, net::TCPServer &server);
147
148 void createChannels(DirectoryNode* baseDir,
149 const PdServ::Task* task);
150 void createParameters(DirectoryNode* baseDir);
151
152 struct CreateVariable {
153 CreateVariable(Server* server, DirectoryNode* baseDir,
154 const PdServ::Variable* var);
155 CreateVariable(const CreateVariable& other);
156 6160 virtual ~CreateVariable() {}
157
158 void newDimension(
159 const PdServ::DataType& dtype,
160 const PdServ::DataType::DimType& dim,
161 size_t dimIdx, size_t elemIdx,
162 CreateVariable& c, size_t offset);
163 void newField(const PdServ::DataType::Field *field,
164 CreateVariable& c, size_t offset);
165 bool newVariable(
166 const PdServ::DataType& dtype,
167 const PdServ::DataType::DimType& dim,
168 size_t dimIdx, size_t elemIdx, size_t offset) const;
169 virtual bool createVariable(
170 const PdServ::DataType& dtype,
171 const PdServ::DataType::DimType& dim,
172 size_t offset) const = 0;
173
174 std::string path() const;
175
176 std::string name;
177
178 const CreateVariable* const parent;
179 Server* const server;
180 DirectoryNode* const baseDir;
181 const PdServ::Variable* const var;
182 };
183
184 4004 struct CreateChannel: CreateVariable {
185 CreateChannel(Server* server, DirectoryNode* baseDir,
186 const PdServ::Signal* s);
187
188 bool createVariable(
189 const PdServ::DataType& dtype,
190 const PdServ::DataType::DimType& dim,
191 size_t offset) const;
192 };
193
194 6468 struct CreateParameter: CreateVariable {
195 CreateParameter(Server* server, DirectoryNode* baseDir,
196 const PdServ::Parameter* p);
197
198 bool createVariable(
199 const PdServ::DataType& dtype,
200 const PdServ::DataType::DimType& dim,
201 size_t offset) const;
202
203 mutable Parameter* parentParameter;
204 };
205 };
206
207 /////////////////////////////////////////////////////////////////////////////
208 template <typename T>
209 182 const T *Server::find(const std::string &p) const
210 {
211
6/12
✓ Branch 2 taken 91 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 91 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 91 times.
✓ Branch 13 taken 91 times.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 91 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 91 times.
182 if (p.empty() or p[0] != '/')
212 return 0;
213
214 182 const DirectoryNode *node = variableDirectory.find(p, 1);
215
6/8
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 83 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 83 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 83 times.
✗ Branch 7 not taken.
182 return node ? dynamic_cast<const T*>(node) : 0;
216 }
217
218 }
219 #endif //MSRSERVER_H
220