GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Server.h
Date: 2023-11-12 04:06:57
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 6755 bool active() const { return state_ == Running; }
92
93 typedef std::vector<const Channel*> Channels;
94 typedef std::vector<const Parameter*> Parameters;
95
96 const Channels& getChannels() const;
97 const Channel * getChannel(size_t) const;
98 void listDir(PdServ::Session *, XmlElement& xml,
99 const std::string& path, bool hex, bool noderived) const;
100
101 const Parameters& getParameters() const;
102 const Parameter * getParameter(size_t) const;
103 const Parameter * find(const PdServ::Parameter *p) const;
104 size_t getMaxInputBufferSize() const;
105
106 template <typename T>
107 const T * find(const std::string& path) const;
108
109 private:
110 std::set<Session*> sessions, pending_sessions;
111
112 std::string bindaddr;
113
114 bool itemize; // Split multidimensional variables to scalars
115 std::atomic_int state_;
116 bool m_broadcast;
117
118 DirectoryNode variableDirectory;
119 DirectoryNode* insertRoot;
120
121 size_t maxConnections;
122 size_t maxInputBufferSize;
123
124 Channels channels;
125 Parameters parameters;
126
127 typedef std::map<const PdServ::Parameter *, const Parameter*>
128 ParameterMap;
129 ParameterMap parameterMap;
130
131 mutable std::mutex mutex;
132 std::condition_variable startup_cv;
133
134 std::unique_ptr<net::TCPServer> server;
135 #ifdef GNUTLS_FOUND
136 std::unique_ptr<net::TCPServer> secure_server;
137 std::string tlsbindaddr;
138 #endif
139
140 // Reimplemented from pthread::Thread
141 void initial();
142 void run();
143 void final();
144
145 int listenTo(const std::string& interface, const std::string& port, net::TCPServer &server);
146
147 void createChannels(DirectoryNode* baseDir,
148 const PdServ::Task* task);
149 void createParameters(DirectoryNode* baseDir);
150
151 struct CreateVariable {
152 CreateVariable(Server* server, DirectoryNode* baseDir,
153 const PdServ::Variable* var);
154 CreateVariable(const CreateVariable& other);
155 4680 virtual ~CreateVariable() {}
156
157 void newDimension(
158 const PdServ::DataType& dtype,
159 const PdServ::DataType::DimType& dim,
160 size_t dimIdx, size_t elemIdx,
161 CreateVariable& c, size_t offset);
162 void newField(const PdServ::DataType::Field *field,
163 CreateVariable& c, size_t offset);
164 bool newVariable(
165 const PdServ::DataType& dtype,
166 const PdServ::DataType::DimType& dim,
167 size_t dimIdx, size_t elemIdx, size_t offset) const;
168 virtual bool createVariable(
169 const PdServ::DataType& dtype,
170 const PdServ::DataType::DimType& dim,
171 size_t offset) const = 0;
172
173 std::string path() const;
174
175 std::string name;
176
177 const CreateVariable* const parent;
178 Server* const server;
179 DirectoryNode* const baseDir;
180 const PdServ::Variable* const var;
181 };
182
183 2600 struct CreateChannel: CreateVariable {
184 CreateChannel(Server* server, DirectoryNode* baseDir,
185 const PdServ::Signal* s);
186
187 bool createVariable(
188 const PdServ::DataType& dtype,
189 const PdServ::DataType::DimType& dim,
190 size_t offset) const;
191 };
192
193 5460 struct CreateParameter: CreateVariable {
194 CreateParameter(Server* server, DirectoryNode* baseDir,
195 const PdServ::Parameter* p);
196
197 bool createVariable(
198 const PdServ::DataType& dtype,
199 const PdServ::DataType::DimType& dim,
200 size_t offset) const;
201
202 mutable Parameter* parentParameter;
203 };
204 };
205
206 /////////////////////////////////////////////////////////////////////////////
207 template <typename T>
208 118 const T *Server::find(const std::string &p) const
209 {
210
6/12
✓ Branch 2 taken 59 times.
✗ Branch 3 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 59 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 59 times.
✓ Branch 13 taken 59 times.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 59 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 59 times.
118 if (p.empty() or p[0] != '/')
211 return 0;
212
213 118 const DirectoryNode *node = variableDirectory.find(p, 1);
214
6/8
✓ Branch 0 taken 51 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 51 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 51 times.
✓ Branch 5 taken 8 times.
✓ Branch 6 taken 51 times.
✗ Branch 7 not taken.
118 return node ? dynamic_cast<const T*>(node) : 0;
215 }
216
217 }
218 #endif //MSRSERVER_H
219