cc_tools_qt
Common Environment for Protocol Analysis.
Loading...
Searching...
No Matches
ToolsMessageBase.h
1//
2// Copyright 2014 - 2025 (C). Alex Robenko. All rights reserved.
3//
4
5// This file is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
20#include "cc_tools_qt/ToolsField.h"
21#include "cc_tools_qt/ToolsFrame.h"
22#include "cc_tools_qt/ToolsMessage.h"
23#include "cc_tools_qt/ToolsProtMsgInterface.h"
24#include "cc_tools_qt/details/ToolsFieldCreator.h"
25
26#include "comms/util/Tuple.h"
27
28#include <algorithm>
29#include <cassert>
30#include <iterator>
31#include <type_traits>
32#include <vector>
33
34namespace cc_tools_qt
35{
36
43template <typename TBase, template<typename...> class TProtMsg, typename TActualMsg>
44class ToolsMessageBase : public TBase
45{
46 using Base = TBase;
47
48public:
50 using DataSeq = typename TBase::DataSeq;
51
52 using ProtInterface = typename TBase::ProtInterface;
53
54 using ProtOptions = typename TBase::ProtOptions;
55
57 using ProtMsg = TProtMsg<ProtInterface, ProtOptions>;
58
59 using FieldsList = typename Base::FieldsList;
60
62 // using Handler = typename CommsBase::Handler;
63
65 ToolsMessageBase() = default;
66
67 ToolsMessageBase(const ProtMsg& msg) :
68 m_msg(msg)
69 {
70 }
71
73 m_msg(std::move(msg))
74 {
75 }
76
79 m_msg(other.m_msg)
80 {
81 }
82
85 m_msg(std::move(other.m_msg))
86 {
87 }
88
90 ~ToolsMessageBase() noexcept = default;
91
93 ToolsMessageBase& operator=(const ToolsMessageBase& other)
94 {
95 m_msg = other.m_msg;
96 return *this;
97 }
98
101 {
102 m_msg = std::move(other.m_msg);
103 return *this;
104 }
105
106 ProtMsg& msg()
107 {
108 return m_msg;
109 }
110
111 const ProtMsg& msg() const
112 {
113 return m_msg;
114 }
115
116protected:
117
119 virtual const char* nameImpl() const override
120 {
121 using Tag =
122 std::conditional_t<
123 ProtMsg::hasCustomName(),
124 HasNameTag,
125 NoNameTag
126 >;
127
128 return nameInternal(Tag());
129 }
130
134 virtual bool refreshMsgImpl() override
135 {
136 return m_msg.doRefresh();
137 }
138
140 virtual qlonglong numericIdImpl() const override
141 {
142 using Tag =
143 std::conditional_t<
144 ProtMsg::hasStaticMsgId(),
145 HasIdTag,
146 NoIdTag
147 >;
148
149 return numericIdInternal(Tag());
150 }
151
153 virtual void resetImpl() override
154 {
155 auto& actObj = static_cast<TActualMsg&>(*this);
156 actObj = TActualMsg();
157 }
158
160 virtual bool assignImpl(const cc_tools_qt::ToolsMessage& other) override
161 {
162 auto* castedOther = dynamic_cast<const TActualMsg*>(&other);
163 if (castedOther == nullptr) {
164 return false;
165 }
166
167 assert(other.idAsString() == Base::idAsString());
168 auto& actObj = static_cast<TActualMsg&>(*this);
169 actObj = *castedOther;
170 return true;
171 }
172
176 virtual bool isValidImpl() const override
177 {
178 return m_msg.doValid();
179 }
180
184 virtual DataSeq encodeDataImpl() const override
185 {
186 DataSeq data;
187 data.reserve(m_msg.doLength());
188 auto iter = std::back_inserter(data);
189 [[maybe_unused]] auto es = m_msg.doWrite(iter, data.max_size());
190 assert(es == comms::ErrorStatus::Success);
191 return data;
192 }
193
197 virtual bool decodeDataImpl(const DataSeq& data) override
198 {
199 auto iter = data.data();
200 auto es = m_msg.doRead(iter, data.size());
201 return es == comms::ErrorStatus::Success;
202 }
203
204 virtual typename Base::Ptr cloneImpl() const override
205 {
206 return typename Base::Ptr(new TActualMsg(static_cast<const TActualMsg&>(*this)));
207 }
208
209 virtual void assignProtMessageImpl(void* protMsg) override
210 {
211 auto* protMsgBase = reinterpret_cast<ProtInterface*>(protMsg);
212 auto* actProtMsg = static_cast<ProtMsg*>(protMsgBase);
213 m_msg = std::move(*actProtMsg);
214 }
215
216 virtual DataSeq encodeFramedImpl(ToolsFrame& frame) const override
217 {
218 return frame.writeProtMsg(&m_msg);
219 }
220
221 virtual FieldsList transportFieldsImpl() override
222 {
223 FieldsList fields;
224 using Tag =
225 std::conditional_t<
226 ProtMsg::hasTransportFields(),
227 HasTransportFields,
228 NoTransportFields
229 >;
230
231 updateTransportFieldsInternal(fields, Tag());
232 return fields;
233 }
234
235 virtual FieldsList payloadFieldsImpl() override
236 {
237 FieldsList fields;
238 fields.reserve(std::tuple_size<typename ProtMsg::AllFields>::value);
239 comms::util::tupleForEach(m_msg.fields(), details::ToolsFieldCreator(fields));
240 return fields;
241 }
242
243private:
244 struct HasIdTag {};
245 struct NoIdTag {};
246 struct HasNameTag {};
247 struct NoNameTag {};
248 struct HasTransportFields {};
249 struct NoTransportFields {};
250
251 qlonglong numericIdInternal(HasIdTag) const
252 {
253 static const bool IsNumeric =
254 std::is_enum<typename ProtMsg::MsgIdType>::value ||
255 std::is_integral<typename ProtMsg::MsgIdType>::value;
256
257 static_assert(IsNumeric, "Only numeric message IDs are supported");
258 return static_cast<qlonglong>(m_msg.doGetId());
259 }
260
261 qlonglong numericIdInternal(NoIdTag) const
262 {
263 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
264 assert(Must_not_be_called);
265 return static_cast<qlonglong>(0);
266 }
267
268 const char* nameInternal(HasNameTag) const
269 {
270 static_assert(comms::isMessageBase<ProtMsg>(), "ProtMsg is expected to be proper message");
271 static_assert(ProtMsg::hasCustomName(), "ProtMsg is expected to define message name");
272
273 return m_msg.doName();
274 }
275
276 const char* nameInternal(NoNameTag) const
277 {
278 assert(false); // Should not be called
279 static const char* NoName = "NO-NAME";
280 return NoName;
281 }
282
283 void updateTransportFieldsInternal(FieldsList& fields, HasTransportFields)
284 {
285 fields.reserve(std::tuple_size<typename ProtMsg::TransportFields>::value);
286 comms::util::tupleForEach(m_msg.transportFields(), details::ToolsFieldCreator(fields));
287 }
288
289 void updateTransportFieldsInternal([[maybe_unused]] FieldsList& fields, NoTransportFields)
290 {
291 }
292
293 ProtMsg m_msg;
294};
295
296} // namespace cc_tools_qt
297
Helper class used to define protocol message class in CommsChampion Tools plugin environment.
Definition ToolsMessageBase.h:45
virtual void resetImpl() override
Overriding implementation to cc_tools_qt::ToolsMessage::resetImpl()
Definition ToolsMessageBase.h:153
virtual DataSeq encodeDataImpl() const override
Overriding polymorphic serialisation functionaly.
Definition ToolsMessageBase.h:184
ToolsMessageBase(ToolsMessageBase &&other)
Move Constructor.
Definition ToolsMessageBase.h:84
typename TBase::DataSeq DataSeq
Data sequence type.
Definition ToolsMessageBase.h:50
virtual const char * nameImpl() const override
Overriding polymorphic name retrieval functionality.
Definition ToolsMessageBase.h:119
ToolsMessageBase()=default
Handler class.
virtual bool assignImpl(const cc_tools_qt::ToolsMessage &other) override
Overriding polymorphic assignment.
Definition ToolsMessageBase.h:160
virtual bool isValidImpl() const override
Overriding polymorphic validity check.
Definition ToolsMessageBase.h:176
virtual bool refreshMsgImpl() override
Overriding polymorphic refresh functionality.
Definition ToolsMessageBase.h:134
ToolsMessageBase(const ToolsMessageBase &other)
Copy Constructor.
Definition ToolsMessageBase.h:78
virtual bool decodeDataImpl(const DataSeq &data) override
Overriding polymorphic deserialisation functionaly.
Definition ToolsMessageBase.h:197
TProtMsg< ProtInterface, ProtOptions > ProtMsg
Protocol definition message type.
Definition ToolsMessageBase.h:57
virtual qlonglong numericIdImpl() const override
Overriding polymorphic retrieval of the numeric id.
Definition ToolsMessageBase.h:140
ToolsMessageBase & operator=(ToolsMessageBase &&other)
Move assignment operator.
Definition ToolsMessageBase.h:100
~ToolsMessageBase() noexcept=default
Destructor.
Main interface class used by CommsChampion Tools to display and manipulate messages.
Definition ToolsMessage.h:44
QString idAsString() const
Get string representation of message ID.
Definition ToolsMessage.cpp:62
Main namespace for all classes / functions of the shared library.