GCC Code Coverage Report


Directory: ./
File: pdserv/src/msrproto/Server.h
Date: 2025-08-17 04:10:43
Exec Total Coverage
Lines: 8 9 88.9%
Branches: 12 20 60.0%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * Copyright 2010 Richard Hacker (lerichi at gmx dot net)
4 *
5 * This file is part of the pdserv library.
6 *
7 * The pdserv library is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation, either version 3 of the License, or (at
10 * your option) any later version.
11 *
12 * The pdserv library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with the pdserv library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ****************************************************************************/
21
22 #ifndef MSRSERVER_H
23 #define MSRSERVER_H
24
25 #include <atomic>
26 #include <condition_variable>
27 #include <set>
28 #include <list>
29 #include <mutex>
30 #include <memory>
31 #include <string>
32 #include <log4cplus/logger.h>
33
34 #include "../PThread.h"
35 #include "../SessionStatistics.h"
36 #include "../Config.h"
37 #include "../DataType.h"
38 #include "DirectoryNode.h"
39
40 namespace PdServ {
41 class Main;
42 class Task;
43 class Parameter;
44 class Signal;
45 class Variable;
46 }
47
48 namespace net {
49 class TCPServer;
50 }
51
52 namespace MsrProto {
53
54 class Session;
55 class Parameter;
56 class Channel;
57
58 class Server: public pthread::Thread {
59 public:
60 enum State
61 {
62 Init,
63 Running,
64 Stopped,
65 };
66
67 Server(const PdServ::Main *main, const PdServ::Config &config);
68 ~Server();
69
70 // return: string <IP><sep><port> of connection
71 std::string getAddr(char sep = ':') const;
72
73 void broadcast(Session *s, const struct timespec& ts,
74 const std::string& action, const std::string& text);
75
76 void setAic(const Parameter*);
77 void parameterChanged(const PdServ::Parameter*,
78 size_t startIndex, size_t n,
79 const char* data, const struct timespec* time);
80
81 void sessionClosed(Session *s);
82 void sessionReady(Session *s);
83
84 void getSessionStatistics(
85 std::list<PdServ::SessionStatistics>& stats) const;
86
87 const PdServ::Main * const main;
88 log4cplus::Logger log;
89 const log4cplus::Logger broadcastLog;
90 10021 bool active() const { return state_ == Running; }
91
92 typedef std::vector<const Channel*> Channels;
93 typedef std::vector<const Parameter*> Parameters;
94
95 const Channels& getChannels() const;
96 const Channel * getChannel(size_t) const;
97 void listDir(PdServ::Session *, XmlElement& xml,
98 const std::string& path, bool hex, bool noderived) const;
99
100 const Parameters& getParameters() const;
101 const Parameter * getParameter(size_t) const;
102 const Parameter * find(const PdServ::Parameter *p) const;
103 size_t getMaxInputBufferSize() const;
104
105 template <typename T>
106 const T * find(const std::string& path) const;
107
108 private:
109 std::set<Session*> sessions, pending_sessions;
110
111 std::string bindaddr;
112
113 bool itemize; // Split multidimensional variables to scalars
114 std::atomic_int state_;
115 bool m_broadcast;
116
117 DirectoryNode variableDirectory;
118 DirectoryNode* insertRoot;
119
120 size_t maxConnections;
121 size_t maxInputBufferSize;
122
123 Channels channels;
124 Parameters parameters;
125
126 typedef std::map<const PdServ::Parameter *, const Parameter*>
127 ParameterMap;
128 ParameterMap parameterMap;
129
130 mutable std::mutex mutex;
131 std::condition_variable startup_cv;
132
133 std::unique_ptr<net::TCPServer> server;
134 #ifdef GNUTLS_FOUND
135 std::unique_ptr<net::TCPServer> secure_server;
136 std::string tlsbindaddr;
137 #endif
138
139 // Reimplemented from pthread::Thread
140 void initial();
141 void run();
142 void final();
143
144 int listenTo(const std::string& interface, const std::string& port,
145 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 6160 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 4004 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 6468 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 182 const T *Server::find(const std::string &p) const
209 {
210
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] != '/')
211 return 0;
212
213 182 const DirectoryNode *node = variableDirectory.find(p, 1);
214
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;
215 }
216
217 }
218 #endif //MSRSERVER_H
219