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