COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
Message.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2025 (C). Alex Robenko. All rights reserved.
3//
4// This Source Code Form is subject to the terms of the Mozilla Public
5// License, v. 2.0. If a copy of the MPL was not distributed with this
6// file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
11
12#pragma once
13
14#include "comms/Assert.h"
15#include "comms/details/detect.h"
16#include "comms/details/field_alias.h"
17#include "comms/details/MessageIdTypeRetriever.h"
18#include "comms/details/MessageInterfaceBuilder.h"
19#include "comms/details/transport_fields_access.h"
20#include "comms/ErrorStatus.h"
21#include "comms/Field.h"
23
24#include <cstdint>
25#include <memory>
26#include <type_traits>
27
28namespace comms
29{
30
77template <typename... TOptions>
78class Message : public details::MessageInterfaceBuilderT<TOptions...>
79{
80 using BaseImpl = details::MessageInterfaceBuilderT<TOptions...>;
81public:
82
85 using InterfaceOptions = details::MessageInterfaceOptionsParser<TOptions...>;
86
92 ~Message() noexcept = default;
93
96 static constexpr bool hasMsgIdType()
97 {
98 return InterfaceOptions::HasMsgIdType;
99 }
100
103 static constexpr bool hasEndian()
104 {
105 return InterfaceOptions::HasEndian;
106 }
107
110 static constexpr bool hasGetId()
111 {
112 return hasMsgIdType() && InterfaceOptions::HasMsgIdInfo;
113 }
114
118 static constexpr bool hasRead()
119 {
120 return InterfaceOptions::HasReadIterator;
121 }
122
126 static constexpr bool hasWrite()
127 {
128 return InterfaceOptions::HasWriteIterator;
129 }
130
133 static constexpr bool hasValid()
134 {
135 return InterfaceOptions::HasValid;
136 }
137
140 static constexpr bool hasLength()
141 {
142 return InterfaceOptions::HasLength;
143 }
144
147 static constexpr bool hasRefresh()
148 {
149 return InterfaceOptions::HasRefresh;
150 }
151
155 static constexpr bool hasDispatch()
156 {
157 return InterfaceOptions::HasHandler;
158 }
159
163 static constexpr bool hasTransportFields()
164 {
165 return InterfaceOptions::HasExtraTransportFields;
166 }
167
170 static constexpr bool hasVersionInTransportFields()
171 {
172 return InterfaceOptions::HasVersionInExtraTransportFields;
173 }
174
178 static constexpr std::size_t versionIdxInTransportFields()
179 {
180 return InterfaceOptions::VersionInExtraTransportFields;
181 }
182
185 static constexpr bool hasName()
186 {
187 return InterfaceOptions::HasName;
188 }
189
190#ifdef FOR_DOXYGEN_DOC_ONLY
195 using MsgIdType = typename BaseImpl::MsgIdType;
196
202 using MsgIdParamType = typename BaseImpl::MsgIdParamType;
203
208 using Endian = typename BaseImpl::Endian;
209
214 using Field = BaseImpl::Field;
215
223
229 using ReadIterator = TypeProvidedWithOption;
230
242 ErrorStatus read(ReadIterator& iter, std::size_t size);
243
249 using WriteIterator = TypeProvidedWithOption;
250
262 ErrorStatus write(WriteIterator& iter, std::size_t size) const;
263
269 bool valid() const;
270
276 std::size_t length() const;
277
294 bool refresh();
295
301 const char* name() const;
302
306 using Handler = TypeProvidedWithOption;
307
310 using DispatchRetType = typename Handler::RetType;
311
318
324 using TransportFields = FieldsProvidedWithOption;
325
339
345
349 using VersionType = typename BaseImpl::VersionType;
350
355
359 const VersionType& version() const;
360#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
361
362protected:
363
364#ifdef FOR_DOXYGEN_DOC_ONLY
372 virtual MsgIdParamType getIdImpl() const = 0;
373
383 virtual comms::ErrorStatus readImpl(ReadIterator& iter, std::size_t size);
384
394 virtual comms::ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const;
395
403 virtual bool validImpl() const;
404
414 virtual std::size_t lengthImpl() const;
415
425 virtual bool refreshImpl();
426
436
441 virtual const char* nameImpl() const = 0;
442
457 template <typename T, typename TIter>
458 static void writeData(T value, TIter& iter);
459
476 template <std::size_t TSize, typename T, typename TIter>
477 static void writeData(T value, TIter& iter);
478
494 template <typename T, typename TIter>
495 static T readData(TIter& iter);
496
513 template <typename T, std::size_t TSize, typename TIter>
514 static T readData(TIter& iter);
515
516#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
517};
518
521template <typename... TOptions>
522inline
524{
525 return msg;
526}
527
530template <typename... TOptions>
531inline
532const Message<TOptions...>& toMessage(const Message<TOptions...>& msg)
533{
534 return msg;
535}
536
541template <typename T>
542constexpr bool isMessage()
543{
544 return details::hasInterfaceOptions<T>();
545}
546
555template <typename TMsg, typename TDefaultType = std::intmax_t>
557 typename comms::util::LazyDeepConditional<
558 TMsg::InterfaceOptions::HasMsgIdType
559 >::template Type<
560 comms::details::MessageIdTypeRetriever,
561 comms::util::AliasType,
562 TDefaultType, TMsg
563 >;
564} // namespace comms
565
574#define COMMS_MSG_TRANSPORT_FIELDS_ACCESS(...) \
575 COMMS_EXPAND(COMMS_DEFINE_TRANSPORT_FIELD_ENUM(__VA_ARGS__)) \
576 COMMS_MSG_TRANSPORT_FIELDS_ACCESS_FUNC { \
577 auto& msgBase = comms::toMessage(*this); \
578 using MsgBase = typename std::decay<decltype(msgBase)>::type; \
579 static_assert(MsgBase::hasTransportFields(), \
580 "Message interface class doesn't define extra transport fields."); \
581 using TransportFieldsTuple = typename MsgBase::TransportFields; \
582 static_assert(std::tuple_size<TransportFieldsTuple>::value == TransportFieldIdx_numOfValues, \
583 "Invalid number of names for transport fields tuple"); \
584 return msgBase.transportFields(); \
585 } \
586 COMMS_MSG_TRANSPORT_FIELDS_ACCESS_CONST_FUNC { \
587 return comms::toMessage(*this).transportFields(); \
588 } \
589 COMMS_EXPAND(COMMS_DO_TRANSPORT_FIELD_ACC_FUNC(TransportFields, transportFields(), __VA_ARGS__))
590
715#define COMMS_MSG_TRANSPORT_FIELDS_NAMES(...) \
716 COMMS_EXPAND(COMMS_MSG_TRANSPORT_FIELDS_ACCESS(__VA_ARGS__)) \
717 COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::TransportFields, TransportField_, TransportFieldIdx_, __VA_ARGS__))
718
732#define COMMS_MSG_TRANSPORT_FIELD_ALIAS_ACCESS(f_, ...) COMMS_EXPAND(COMMS_DO_ALIAS(transportField_, f_, __VA_ARGS__))
733
741#define COMMS_MSG_TRANSPORT_FIELD_ALIAS_ACCESS_NOTEMPLATE(f_, ...) COMMS_EXPAND(COMMS_DO_ALIAS_NOTEMPLATE(transportField_, f_, __VA_ARGS__))
742
844#define COMMS_MSG_TRANSPORT_FIELD_ALIAS(f_, ...) \
845 COMMS_EXPAND(COMMS_MSG_TRANSPORT_FIELD_ALIAS_ACCESS(f_, __VA_ARGS__)) \
846 COMMS_EXPAND(COMMS_DO_ALIAS_TYPEDEF(TransportField_, f_, __VA_ARGS__))
847
855#define COMMS_MSG_TRANSPORT_FIELD_ALIAS_NOTEMPLATE(f_, ...) \
856 COMMS_EXPAND(COMMS_MSG_TRANSPORT_FIELD_ALIAS_ACCESS_NOTEMPLATE(f_, __VA_ARGS__)) \
857 COMMS_EXPAND(COMMS_DO_ALIAS_TYPEDEF(TransportField_, f_, __VA_ARGS__))
This file contains classes required for generic custom assertion functionality.
This file contain definition of error statuses used by comms module.
Contains definition of comms::Field class.
Main interface class for all the messages.
Definition Message.h:79
static constexpr bool hasValid()
Compile type inquiry whether message interface class defines valid() and validImpl() member functions...
Definition Message.h:133
static constexpr bool hasEndian()
Compile type inquiry whether message interface class defines Endian and Field types.
Definition Message.h:103
FieldsProvidedWithOption TransportFields
std::tuple of extra fields from transport layers that may affect the way the message fields get seria...
Definition Message.h:324
typename BaseImpl::Endian Endian
Serialisation endian type.
Definition Message.h:208
static constexpr bool hasRead()
Compile type inquiry whether message interface class defines read() and readImpl() member functions a...
Definition Message.h:118
static constexpr std::size_t versionIdxInTransportFields()
Compile type inquiry of version field index in transport field.
Definition Message.h:178
~Message() noexcept=default
Destructor.
TypeProvidedWithOption Handler
Type of the message handler object.
Definition Message.h:306
VersionType & version()
Access to version information.
static constexpr bool hasMsgIdType()
Compile type inquiry whether message interface class defines MsgIdType and MsgIdParamType types.
Definition Message.h:96
typename Handler::RetType DispatchRetType
Return type of the dispatch() member function.
Definition Message.h:310
TypeProvidedWithOption ReadIterator
Type of the iterator used for reading message contents from sequence of bytes stored somewhere.
Definition Message.h:229
BaseImpl::Field Field
Type of default base class for all the fields.
Definition Message.h:214
static T readData(TIter &iter)
Read partial data from input area.
static constexpr bool hasTransportFields()
Compile type inquiry whether message interface class defines transportFields() member functions as we...
Definition Message.h:163
static void writeData(T value, TIter &iter)
Write data into the output area.
details::MessageInterfaceOptionsParser< TOptions... > InterfaceOptions
All the options bundled into struct.
Definition Message.h:85
ErrorStatus read(ReadIterator &iter, std::size_t size)
Read message contents using provided iterator.
virtual bool validImpl() const
Pure virtual function used to implement contents validity check.
virtual comms::ErrorStatus readImpl(ReadIterator &iter, std::size_t size)
Virtual function used to implement read operation.
const VersionType & version() const
Const access to version information.
std::size_t length() const
Get number of bytes required to serialise this message.
const char * name() const
Get name of the message.
TransportFields & transportFields()
Get access to extra transport fields.
static constexpr bool hasGetId()
Compile type inquiry whether message interface class defines getId() and getIdImpl() member functions...
Definition Message.h:110
const TransportFields & transportFields() const
Const version of transportFields.
static constexpr bool hasWrite()
Compile type inquiry whether message interface class defines write() and writeImpl() member functions...
Definition Message.h:126
typename BaseImpl::MsgIdType MsgIdType
Type used for message ID.
Definition Message.h:195
virtual MsgIdParamType getIdImpl() const =0
Pure virtual function used to retrieve ID of the message.
typename BaseImpl::MsgIdParamType MsgIdParamType
Type used for message ID passed as parameter or returned from function.
Definition Message.h:202
MsgIdParamType getId() const
Retrieve ID of the message.
static constexpr bool hasLength()
Compile type inquiry whether message interface class defines length() and lengthImpl() member functio...
Definition Message.h:140
virtual const char * nameImpl() const =0
Pure virtual function used to retrieve actual message name.
virtual DispatchRetType dispatchImpl(Handler &handler)
Virtual function used to dispatch message to the handler object for processing.
static constexpr bool hasName()
Compile type inquiry whether message interface class defines name() and nameImpl() member functions.
Definition Message.h:185
static void writeData(T value, TIter &iter)
Write partial data into the output area.
static T readData(TIter &iter)
Read data from input area.
ErrorStatus write(WriteIterator &iter, std::size_t size) const
Write message contents using provided iterator.
virtual std::size_t lengthImpl() const
Virtual function used to retrieve number of bytes required to serialise this message.
typename BaseImpl::VersionType VersionType
Type used for version info.
Definition Message.h:349
bool refresh()
Refresh to contents of the message.
static constexpr bool hasRefresh()
Compile type inquiry whether message interface class defines refresh() and refreshImpl() member funct...
Definition Message.h:147
virtual comms::ErrorStatus writeImpl(WriteIterator &iter, std::size_t size) const
Virtual function used to implement write operation.
bool valid() const
Check validity of message contents.
static constexpr bool hasDispatch()
Compile type inquiry whether message interface class defines dispatch() and dispatchImpl() member fun...
Definition Message.h:155
TypeProvidedWithOption WriteIterator
Type of the iterator used for writing message contents into sequence of bytes stored somewhere.
Definition Message.h:249
DispatchRetType dispatch(Handler &handler)
Dispatch message to the handler for processing.
virtual bool refreshImpl()
Virtual function used to bring contents of the message into a consistent state.
static constexpr bool hasVersionInTransportFields()
Compile type inquiry whether there is version information inside transport fields.
Definition Message.h:170
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
constexpr bool isMessage()
Compile time check of of whether the type is a message.
Definition Message.h:542
typename comms::util::LazyDeepConditional< TMsg::InterfaceOptions::HasMsgIdType >::template Type< comms::details::MessageIdTypeRetriever, comms::util::AliasType, TDefaultType, TMsg > MessageIdType
Get type of message ID used by interface class.
Definition Message.h:563
Message< TOptions... > & toMessage(Message< TOptions... > &msg)
Upcast type of the message object to comms::Message in order to have access to its internal types.
Definition Message.h:523
Replacement to some types from standard type_traits.