COMMS
Template library intended to help with implementation of communication protocols.
Loading...
Searching...
No Matches
MessageBase.h
Go to the documentation of this file.
1//
2// Copyright 2014 - 2026 (C). Alex Robenko. All rights reserved.
3//
4// SPDX-License-Identifier: MPL-2.0
5//
6// This Source Code Form is subject to the terms of the Mozilla Public
7// License, v. 2.0. If a copy of the MPL was not distributed with this
8// file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
12
13#pragma once
14
15#include "comms/details/detect.h"
16#include "comms/details/field_alias.h"
17#include "comms/details/fields_access.h"
18#include "comms/details/macro_common.h"
19#include "comms/details/MessageImplBuilder.h"
20
21#include <cstddef>
22#include <type_traits>
23
24namespace comms
25{
26
86template <typename TMessage, typename... TOptions>
87class MessageBase : public details::MessageImplBuilderT<TMessage, TOptions...>
88{
89 using BaseImpl = details::MessageImplBuilderT<TMessage, TOptions...>;
90public:
93 using ImplOptions = details::MessageImplOptionsParser<TOptions...>;
94
99 using MsgType = typename ImplOptions::MsgType;
100
103 static constexpr bool hasStaticMsgId()
104 {
105 return ImplOptions::HasStaticMsgId;
106 }
107
112 static constexpr std::intmax_t staticMsgId()
113 {
114 return ImplOptions::MsgId;
115 }
116
119 static constexpr bool hasFields()
120 {
121 return ImplOptions::HasFieldsImpl;
122 }
123
126 static constexpr bool hasFailOnInvalid()
127 {
128 return ImplOptions::HasFailOnInvalid;
129 }
130
133 static constexpr bool hasMsgType()
134 {
135 return ImplOptions::HasMsgType;
136 }
137
141 static constexpr bool hasPolymorphicRead()
142 {
143 return BaseImpl::hasRead() && (!ImplOptions::HasNoReadImpl);
144 }
145
149 static constexpr bool hasPolymorphicWrite()
150 {
151 return BaseImpl::hasWrite() && (!ImplOptions::HasNoWriteImpl);
152 }
153
157 static constexpr bool hasPolymorphicValid()
158 {
159 return BaseImpl::hasValid() && (!ImplOptions::HasNoValidImpl);
160 }
161
165 static constexpr bool hasPolymorphicLength()
166 {
167 return BaseImpl::hasLength() && (!ImplOptions::HasNoLengthImpl);
168 }
169
173 static constexpr bool hasPolymorphicDispatch()
174 {
175 return BaseImpl::hasDispatch() && (!ImplOptions::HasNoDispatchImpl);
176 }
177
181 static constexpr bool hasCustomRefresh()
182 {
183 return ImplOptions::HasCustomRefresh;
184 }
185
189 static constexpr bool hasCustomName()
190 {
191 return ImplOptions::HasName;
192 }
193
195 static constexpr bool hasDoGetId()
196 {
197 return ImplOptions::HasStaticMsgId || ImplOptions::HasDoGetId;
198 }
199
200#ifdef FOR_DOXYGEN_DOC_ONLY
201
205 using AllFields = FieldsProvidedWithOption;
206
212
217 const AllFields& fields() const;
218
224 static constexpr bool areFieldsVersionDependent();
225
230 static constexpr MsgIdParamType doGetId();
231
249 template <typename TIter>
250 ErrorStatus doRead(TIter& iter, std::size_t size);
251
270 template <typename TIter>
271 ErrorStatus doWrite(TIter& iter, std::size_t size) const;
272
284 bool doValid() const;
285
299 bool doRefresh() const;
300
314 std::size_t doLength() const;
315
322 template <std::size_t TFromIdx>
323 std::size_t doLengthFrom() const;
324
333 template <std::size_t TUntilIdx>
334 std::size_t doLengthUntil() const;
335
349 template <std::size_t TFromIdx, std::size_t TUntilIdx>
350 std::size_t doLengthFromUntil() const;
351
361 static constexpr std::size_t doMinLength();
362
369 template <std::size_t TFromIdx>
370 static constexpr std::size_t doMinLengthFrom();
371
380 template <std::size_t TUntilIdx>
381 static constexpr std::size_t doMinLengthUntil();
382
396 template <std::size_t TFromIdx, std::size_t TUntilIdx>
397 std::size_t doMinLengthFromUntil() const;
398
408 static constexpr std::size_t doMaxLength();
409
416 template <std::size_t TFromIdx>
417 static constexpr std::size_t doMaxLengthFrom();
418
427 template <std::size_t TUntilIdx>
428 static constexpr std::size_t doMaxLengthUntil();
429
443 template <std::size_t TFromIdx, std::size_t TUntilIdx>
444 std::size_t doMaxLengthFromUntil() const;
445
457
458#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
459
460protected:
461 ~MessageBase() noexcept = default;
462
463#ifdef FOR_DOXYGEN_DOC_ONLY
478 virtual MsgIdParamType getIdImpl() const override;
479
546 virtual DispatchRetType dispatchImpl(Handler& handler) override;
547
561 virtual ErrorStatus readImpl(ReadIterator& iter, std::size_t size) override;
562
583 template <std::size_t TIdx, typename TIter>
584 ErrorStatus doReadUntil(TIter& iter, std::size_t& len);
585
589 template <std::size_t TIdx, typename TIter>
590 ErrorStatus doReadUntilAndUpdateLen(TIter& iter, std::size_t& len);
591
603 template <std::size_t TIdx, typename TIter>
604 void doReadNoStatusUntil(TIter& iter);
605
627 template <std::size_t TIdx, typename TIter>
628 ErrorStatus doReadFrom(TIter& iter, std::size_t len);
629
633 template <std::size_t TIdx, typename TIter>
634 ErrorStatus doReadFromAndUpdateLen(TIter& iter, std::size_t& len);
635
647 template <std::size_t TIdx, typename TIter>
648 void doReadNoStatusFrom(TIter& iter);
649
670 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
671 ErrorStatus doReadFromUntil(TIter& iter, std::size_t len);
672
676 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
677 ErrorStatus doReadFromUntilAndUpdateLen(TIter& iter, std::size_t& len);
678
691 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
692 void doReadNoStatusFromUntil(TIter& iter);
693
707 virtual ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const override;
708
724 template <std::size_t TIdx, typename TIter>
725 ErrorStatus doWriteUntil(TIter& iter, std::size_t len) const;
726
728 template <std::size_t TIdx, typename TIter>
729 ErrorStatus doWriteUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
730
742 template <std::size_t TIdx, typename TIter>
743 void doWriteNoStatusUntil(TIter& iter) const;
744
759 template <std::size_t TIdx, typename TIter>
760 ErrorStatus doWriteFrom(TIter& iter, std::size_t len) const;
761
763 template <std::size_t TIdx, typename TIter>
764 ErrorStatus doWriteFromAndUpdateLen(TIter& iter, std::size_t& len) const;
765
775 template <std::size_t TIdx, typename TIter>
776 void doWriteNoStatusFrom(TIter& iter) const;
777
794 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
795 ErrorStatus doWriteFromUntil(TIter& iter, std::size_t len) const;
796
798 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
799 ErrorStatus doWriteFromUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
800
813 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
814 void doWriteNoStatusFromUntil(TIter& iter) const;
815
826 virtual bool validImpl() const override;
827
839 virtual std::size_t lengthImpl() const override;
840
853 virtual bool refreshImpl() override;
854
863 virtual const char* nameImpl() const override;
864
865#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
866};
867
871template <typename TMessage1, typename TMessage2, typename... TOptions>
873{
874 return msg1.fields() == msg2.fields();
875}
876
880template <typename TMessage1, typename TMessage2, typename... TOptions>
882{
883 return !(msg1 == msg2);
884}
885
888template <typename TMessage, typename... TOptions>
889inline
891{
892 return msg;
893}
894
897template <typename TMessage, typename... TOptions>
898inline
899const MessageBase<TMessage, TOptions...>& toMessageBase(
901{
902 return msg;
903}
904
909template <typename T>
910constexpr bool isMessageBase()
911{
912 return details::hasImplOptions<T>();
913}
914
915} // namespace comms
916
925#define COMMS_MSG_FIELDS_ACCESS(...) \
926 COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
927 COMMS_MSG_FIELDS_ACCESS_FUNC { \
928 auto& val = comms::toMessageBase(*this).fields(); \
929 using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
930 static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
931 "Invalid number of names for fields tuple"); \
932 return val; \
933 } \
934 COMMS_MSG_FIELDS_ACCESS_CONST_FUNC { \
935 auto& val = comms::toMessageBase(*this).fields(); \
936 using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
937 static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
938 "Invalid number of names for fields tuple"); \
939 return val; \
940 } \
941 COMMS_EXPAND(COMMS_DO_FIELD_ACC_FUNC(AllFields, fields(), __VA_ARGS__))
942
1077#define COMMS_MSG_FIELDS_NAMES(...) \
1078 COMMS_EXPAND(COMMS_MSG_FIELDS_ACCESS(__VA_ARGS__)) \
1079 COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::AllFields, Field_, FieldIdx_, __VA_ARGS__))
1080
1093#define COMMS_MSG_FIELD_ALIAS_ACCESS(f_, ...) COMMS_DO_ALIAS(field_, f_, __VA_ARGS__)
1094
1195#define COMMS_MSG_FIELD_ALIAS(f_, ...) \
1196 COMMS_EXPAND(COMMS_MSG_FIELD_ALIAS_ACCESS(f_, __VA_ARGS__)) \
1197 COMMS_EXPAND(COMMS_DO_ALIAS_TYPEDEF(Field_, f_, __VA_ARGS__))
Base class for all the custom protocol messages.
Definition MessageBase.h:88
bool operator!=(const MessageBase< TMessage1, TOptions... > &msg1, const MessageBase< TMessage2, TOptions... > &msg2) noexcept
Message object inequality comparison operator.
Definition MessageBase.h:881
void doWriteNoStatusUntil(TIter &iter) const
Helper function that allows to write only limited number of fields.
FieldsProvidedWithOption AllFields
All field classes provided with comms::option::def::FieldsImpl option.
Definition MessageBase.h:205
ErrorStatus doReadFrom(TIter &iter, std::size_t len)
Helper function that allows to read only limited number of fields.
ErrorStatus doWriteUntilAndUpdateLen(TIter &iter, std::size_t &len) const
Same as doWriteUntil(), but modifies length parameter.
static constexpr std::size_t doMinLengthFrom()
Compile time constant of minimal partial serialisation length.
static constexpr std::intmax_t staticMsgId()
Compile time retrieval of the message id provided via comms::option::def::StaticNumIdImpl.
Definition MessageBase.h:112
static constexpr bool hasPolymorphicDispatch()
Compile time inquiry of whether polymoriphic dispatch has been requested via interface options and ha...
Definition MessageBase.h:173
virtual MsgIdParamType getIdImpl() const override
Implementation of ID retrieval functionality.
std::size_t doLengthFromUntil() const
Default implementation of partial length calculation functionality.
static constexpr bool hasCustomRefresh()
Compile time inquiry of whether comms::MessageBase has notified about custom refresh functionality in...
Definition MessageBase.h:181
ErrorStatus doWriteFromUntilAndUpdateLen(TIter &iter, std::size_t &len) const
Same as doWriteNoStatusFrom(), but updates length information.
void doReadNoStatusUntil(TIter &iter)
Helper function that allows to read only limited number of fields.
static constexpr bool hasDoGetId()
Compile type inquiry whether the class provides doGetId() member function.
Definition MessageBase.h:195
static constexpr bool hasPolymorphicWrite()
Compile time inquiry of whether polymoriphic write has been requested via interface options and hasn'...
Definition MessageBase.h:149
bool doRefresh() const
Default implementation of refreshing functionality.
ErrorStatus doWriteFromAndUpdateLen(TIter &iter, std::size_t &len) const
Same as doWriteFrom(), but modifies length parameter.
static constexpr bool areFieldsVersionDependent()
Compile time check of whether the message fields are version dependent.
std::size_t doMaxLengthFromUntil() const
Compile time constant of maximal partial serialisation length.
details::MessageImplOptionsParser< TOptions... > ImplOptions
All the options provided to this class bundled into struct.
Definition MessageBase.h:93
static constexpr bool hasCustomName()
Compile time inquiry of whether comms::MessageBase has notified about custom name retrieval function ...
Definition MessageBase.h:189
ErrorStatus doRead(TIter &iter, std::size_t size)
Default implementation of read functionality.
ErrorStatus doReadFromUntil(TIter &iter, std::size_t len)
Helper function that allows to read only limited number of fields.
virtual bool refreshImpl() override
Implementation of polymorphic refresh functionality.
void doWriteNoStatusFrom(TIter &iter) const
Helper function that allows to write only limited number of fields.
virtual ErrorStatus readImpl(ReadIterator &iter, std::size_t size) override
Implementation of polymorphic read functionality.
ErrorStatus doWriteFrom(TIter &iter, std::size_t len) const
Helper function that allows to write only limited number of fields.
static constexpr bool hasPolymorphicRead()
Compile time inquiry of whether polymoriphic read has been requested via interface options and hasn't...
Definition MessageBase.h:141
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether fail on invalid has been requested comms::option::def::FailOnInvalid ...
Definition MessageBase.h:126
void doReadNoStatusFrom(TIter &iter)
Helper function that allows to read only limited number of fields.
std::size_t doLengthFrom() const
Default implementation of partial length calculation functionality.
virtual DispatchRetType dispatchImpl(Handler &handler) override
Implementation of dispatch functionality.
std::size_t doLength() const
Default implementation of length calculation functionality.
static constexpr std::size_t doMinLength()
Compile time constant of minimal serialisation length.
ErrorStatus doWrite(TIter &iter, std::size_t size) const
Default implementation of write functionality.
AllFields & fields()
Get an access to the fields of the message.
typename ImplOptions::MsgType MsgType
Type of the actual message provided via comms::option::def::MsgType.
Definition MessageBase.h:99
virtual ErrorStatus writeImpl(WriteIterator &iter, std::size_t size) const override
Implementation of polymorphic write functionality.
static constexpr bool hasStaticMsgId()
Compile type inquiry whether static numeric id has been provided via comms::option::def::StaticNumIdI...
Definition MessageBase.h:103
std::size_t doLengthUntil() const
Default implementation of partial length calculation functionality.
bool doFieldsVersionUpdate()
Update version information of all the fields.
static constexpr bool hasPolymorphicLength()
Compile time inquiry of whether polymoriphic length has been requested via interface options and hasn...
Definition MessageBase.h:165
virtual std::size_t lengthImpl() const override
Implementation of polymorphic length calculation functionality.
ErrorStatus doWriteUntil(TIter &iter, std::size_t len) const
Helper function that allows to write only limited number of fields.
std::size_t doMinLengthFromUntil() const
Compile time constant of minimal partial serialisation length.
const AllFields & fields() const
Get an access to the fields of the message.
static constexpr std::size_t doMaxLengthFrom()
Compile time constant of maximal partial serialisation length.
static constexpr bool hasPolymorphicValid()
Compile time inquiry of whether polymoriphic validity check has been requested via interface options ...
Definition MessageBase.h:157
virtual bool validImpl() const override
Implementation of polymorphic validity check functionality.
ErrorStatus doReadFromAndUpdateLen(TIter &iter, std::size_t &len)
Same as doReadFrom(), but modifies length parameter.
static constexpr std::size_t doMaxLengthUntil()
Compile time constant of maximal partial serialisation length.
ErrorStatus doReadUntilAndUpdateLen(TIter &iter, std::size_t &len)
Same as doReadUntil(), but updating length parameter.
static constexpr bool hasMsgType()
Compile time inquiry of whether the actual message type has been provided via comms::option::def::Msg...
Definition MessageBase.h:133
bool operator==(const MessageBase< TMessage1, TOptions... > &msg1, const MessageBase< TMessage2, TOptions... > &msg2) noexcept
Message object equality comparison operator.
Definition MessageBase.h:872
static constexpr bool hasFields()
Compile type inquiry whether fields have been provided via comms::option::def::FieldsImpl.
Definition MessageBase.h:119
ErrorStatus doWriteFromUntil(TIter &iter, std::size_t len) const
Helper function that allows to write only limited number of fields.
void doWriteNoStatusFromUntil(TIter &iter) const
Helper function that allows to write only limited number of fields.
void doReadNoStatusFromUntil(TIter &iter)
Helper function that allows to read only limited number of fields.
ErrorStatus doReadUntil(TIter &iter, std::size_t &len)
Helper function that allows to read only limited number of fields.
static constexpr MsgIdParamType doGetId()
Default implementation of ID retrieval functionality.
bool doValid() const
Default implementation of validity check functionality.
ErrorStatus doReadFromUntilAndUpdateLen(TIter &iter, std::size_t &len)
Same as doReadFromUntil(), but modifies length parameter.
virtual const char * nameImpl() const override
Implementation of polymorphic name retrieval functionality.
static constexpr std::size_t doMinLengthUntil()
Compile time constant of minimal partial serialisation length.
static constexpr std::size_t doMaxLength()
Compile time constant of maximal serialisation length.
TypeProvidedWithOption Handler
Type of the message handler object.
Definition Message.h:307
typename Handler::RetType DispatchRetType
Return type of the dispatch() member function.
Definition Message.h:311
TypeProvidedWithOption ReadIterator
Type of the iterator used for reading message contents from sequence of bytes stored somewhere.
Definition Message.h:230
typename BaseImpl::MsgIdParamType MsgIdParamType
Type used for message ID passed as parameter or returned from function.
Definition Message.h:203
TypeProvidedWithOption WriteIterator
Type of the iterator used for writing message contents into sequence of bytes stored somewhere.
Definition Message.h:250
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:19
MessageBase< TMessage, TOptions... > & toMessageBase(MessageBase< TMessage, TOptions... > &msg)
Upcast type of the message object to comms::MessageBase in order to have access to its internal types...
Definition MessageBase.h:890
constexpr bool isMessageBase()
Compile time check of of whether the type is a message extending comms::MessageBase.
Definition MessageBase.h:910