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/ToolsFrame.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 return frame.writeProtMsg(&m_msg);
220 }
221
222 virtual FieldsList transportFieldsImpl() override
223 {
224 FieldsList fields;
225 using Tag =
226 std::conditional_t<
227 ProtMsg::hasTransportFields(),
228 HasTransportFields,
229 NoTransportFields
230 >;
231
232 updateTransportFieldsInternal(fields, Tag());
233 return fields;
234 }
235
236 virtual FieldsList payloadFieldsImpl() override
237 {
238 FieldsList fields;
239 fields.reserve(std::tuple_size<typename ProtMsg::AllFields>::value);
240 comms::util::tupleForEach(m_msg.fields(), details::ToolsFieldCreator(fields));
241 return fields;
242 }
243
244private:
245 struct HasIdTag {};
246 struct NoIdTag {};
247 struct HasNameTag {};
248 struct NoNameTag {};
249 struct HasTransportFields {};
250 struct NoTransportFields {};
251
252 qlonglong numericIdInternal(HasIdTag) const
253 {
254 static const bool IsNumeric =
255 std::is_enum<typename ProtMsg::MsgIdType>::value ||
256 std::is_integral<typename ProtMsg::MsgIdType>::value;
257
258 static_assert(IsNumeric, "Only numeric message IDs are supported");
259 return static_cast<qlonglong>(m_msg.doGetId());
260 }
261
262 qlonglong numericIdInternal(NoIdTag) const
263 {
264 [[maybe_unused]] static constexpr bool Must_not_be_called = false;
265 assert(Must_not_be_called);
266 return static_cast<qlonglong>(0);
267 }
268
269 const char* nameInternal(HasNameTag) const
270 {
271 static_assert(comms::isMessageBase<ProtMsg>(), "ProtMsg is expected to be proper message");
272 static_assert(ProtMsg::hasCustomName(), "ProtMsg is expected to define message name");
273
274 return m_msg.doName();
275 }
276
277 const char* nameInternal(NoNameTag) const
278 {
279 assert(false); // Should not be called
280 static const char* NoName = "NO-NAME";
281 return NoName;
282 }
283
284 void updateTransportFieldsInternal(FieldsList& fields, HasTransportFields)
285 {
286 fields.reserve(std::tuple_size<typename ProtMsg::TransportFields>::value);
287 comms::util::tupleForEach(m_msg.transportFields(), details::ToolsFieldCreator(fields));
288 }
289
290 void updateTransportFieldsInternal([[maybe_unused]] FieldsList& fields, NoTransportFields)
291 {
292 }
293
294 ProtMsg m_msg;
295};
296
297} // namespace cc_tools_qt
298
299
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.