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
19#pragma once
20
21#include "cc_tools_qt/ToolsField.h"
22#include "cc_tools_qt/ToolsFrameCommon.h"
23#include "cc_tools_qt/ToolsMessage.h"
24#include "cc_tools_qt/ToolsProtMsgInterface.h"
25#include "cc_tools_qt/details/ToolsFieldCreator.h"
26
27#include "comms/util/Tuple.h"
28
29#include <algorithm>
30#include <cassert>
31#include <iterator>
32#include <type_traits>
33#include <vector>
34
35namespace cc_tools_qt
36{
37
44template <typename TBase, template<typename...> class TProtMsg, typename TActualMsg>
45class ToolsMessageBase : public TBase
46{
47 using Base = TBase;
48
49public:
51 using DataSeq = typename TBase::DataSeq;
52
53 using ProtInterface = typename TBase::ProtInterface;
54
55 using ProtOptions = typename TBase::ProtOptions;
56
58 using ProtMsg = TProtMsg<ProtInterface, ProtOptions>;
59
60 using FieldsList = typename Base::FieldsList;
61
63 // using Handler = typename CommsBase::Handler;
64
66 ToolsMessageBase() = default;
67
68 ToolsMessageBase(const ProtMsg& msg) :
69 m_msg(msg)
70 {
71 }
72
74 m_msg(std::move(msg))
75 {
76 }
77
80 m_msg(other.m_msg)
81 {
82 }
83
86 m_msg(std::move(other.m_msg))
87 {
88 }
89
91 ~ToolsMessageBase() noexcept = default;
92
94 ToolsMessageBase& operator=(const ToolsMessageBase& other)
95 {
96 m_msg = other.m_msg;
97 return *this;
98 }
99
102 {
103 m_msg = std::move(other.m_msg);
104 return *this;
105 }
106
107 ProtMsg& msg()
108 {
109 return m_msg;
110 }
111
112 const ProtMsg& msg() const
113 {
114 return m_msg;
115 }
116
117protected:
118
120 virtual const char* nameImpl() const override
121 {
122 using Tag =
123 std::conditional_t<
124 ProtMsg::hasCustomName(),
125 HasNameTag,
126 NoNameTag
127 >;
128
129 return nameInternal(Tag());
130 }
131
135 virtual bool refreshMsgImpl() override
136 {
137 return m_msg.doRefresh();
138 }
139
141 virtual qlonglong numericIdImpl() const override
142 {
143 using Tag =
144 std::conditional_t<
145 ProtMsg::hasStaticMsgId(),
146 HasIdTag,
147 NoIdTag
148 >;
149
150 return numericIdInternal(Tag());
151 }
152
154 virtual void resetImpl() override
155 {
156 auto& actObj = static_cast<TActualMsg&>(*this);
157 actObj = TActualMsg();
158 }
159
161 virtual bool assignImpl(const cc_tools_qt::ToolsMessage& other) override
162 {
163 auto* castedOther = dynamic_cast<const TActualMsg*>(&other);
164 if (castedOther == nullptr) {
165 return false;
166 }
167
168 assert(other.idAsString() == Base::idAsString());
169 auto& actObj = static_cast<TActualMsg&>(*this);
170 actObj = *castedOther;
171 return true;
172 }
173
177 virtual bool isValidImpl() const override
178 {
179 return m_msg.doValid();
180 }
181
185 virtual DataSeq encodeDataImpl() const override
186 {
187 DataSeq data;
188 data.reserve(m_msg.doLength());
189 auto iter = std::back_inserter(data);
190 [[maybe_unused]] auto es = m_msg.doWrite(iter, data.max_size());
191 assert(es == comms::ErrorStatus::Success);
192 return data;
193 }
194
198 virtual bool decodeDataImpl(const DataSeq& data) override
199 {
200 auto iter = data.data();
201 auto es = m_msg.doRead(iter, data.size());
202 return es == comms::ErrorStatus::Success;
203 }
204
205 virtual typename Base::Ptr cloneImpl() const override
206 {
207 return typename Base::Ptr(new TActualMsg(static_cast<const TActualMsg&>(*this)));
208 }
209
210 virtual void assignProtMessageImpl(void* protMsg) override
211 {
212 auto* protMsgBase = reinterpret_cast<ProtInterface*>(protMsg);
213 auto* actProtMsg = static_cast<ProtMsg*>(protMsgBase);
214 m_msg = std::move(*actProtMsg);
215 }
216
217 virtual DataSeq encodeFramedImpl(ToolsFrame& frame) const override
218 {
219 auto& castedFrame = static_cast<ToolsFrameCommon<TBase>&>(frame);
220 return castedFrame.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
300
Helper class used to define protocol message class in CommsChampion Tools plugin environment.
Definition ToolsMessageBase.h:46
virtual void resetImpl() override
Overriding implementation to cc_tools_qt::ToolsMessage::resetImpl()
Definition ToolsMessageBase.h:154
virtual DataSeq encodeDataImpl() const override
Overriding polymorphic serialisation functionaly.
Definition ToolsMessageBase.h:185
ToolsMessageBase(ToolsMessageBase &&other)
Move Constructor.
Definition ToolsMessageBase.h:85
typename TBase::DataSeq DataSeq
Data sequence type.
Definition ToolsMessageBase.h:51
virtual const char * nameImpl() const override
Overriding polymorphic name retrieval functionality.
Definition ToolsMessageBase.h:120
ToolsMessageBase()=default
Handler class.
virtual bool assignImpl(const cc_tools_qt::ToolsMessage &other) override
Overriding polymorphic assignment.
Definition ToolsMessageBase.h:161
virtual bool isValidImpl() const override
Overriding polymorphic validity check.
Definition ToolsMessageBase.h:177
virtual bool refreshMsgImpl() override
Overriding polymorphic refresh functionality.
Definition ToolsMessageBase.h:135
ToolsMessageBase(const ToolsMessageBase &other)
Copy Constructor.
Definition ToolsMessageBase.h:79
virtual bool decodeDataImpl(const DataSeq &data) override
Overriding polymorphic deserialisation functionaly.
Definition ToolsMessageBase.h:198
TProtMsg< ProtInterface, ProtOptions > ProtMsg
Protocol definition message type.
Definition ToolsMessageBase.h:58
virtual qlonglong numericIdImpl() const override
Overriding polymorphic retrieval of the numeric id.
Definition ToolsMessageBase.h:141
ToolsMessageBase & operator=(ToolsMessageBase &&other)
Move assignment operator.
Definition ToolsMessageBase.h:101
~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:64
Main namespace for all classes / functions of the shared library.