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 - 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
10
11#pragma once
12
13#include "comms/details/detect.h"
14#include "comms/details/field_alias.h"
15#include "comms/details/fields_access.h"
16#include "comms/details/macro_common.h"
17#include "comms/details/MessageImplBuilder.h"
18
19namespace comms
20{
21
81template <typename TMessage, typename... TOptions>
82class MessageBase : public details::MessageImplBuilderT<TMessage, TOptions...>
83{
84 using BaseImpl = details::MessageImplBuilderT<TMessage, TOptions...>;
85public:
88 using ImplOptions = details::MessageImplOptionsParser<TOptions...>;
89
94 using MsgType = typename ImplOptions::MsgType;
95
98 static constexpr bool hasStaticMsgId()
99 {
100 return ImplOptions::HasStaticMsgId;
101 }
102
107 static constexpr std::intmax_t staticMsgId()
108 {
109 return ImplOptions::MsgId;
110 }
111
114 static constexpr bool hasFields()
115 {
116 return ImplOptions::HasFieldsImpl;
117 }
118
121 static constexpr bool hasFailOnInvalid()
122 {
123 return ImplOptions::HasFailOnInvalid;
124 }
125
128 static constexpr bool hasMsgType()
129 {
130 return ImplOptions::HasMsgType;
131 }
132
136 static constexpr bool hasPolymorphicRead()
137 {
138 return BaseImpl::hasRead() && (!ImplOptions::HasNoReadImpl);
139 }
140
144 static constexpr bool hasPolymorphicWrite()
145 {
146 return BaseImpl::hasWrite() && (!ImplOptions::HasNoWriteImpl);
147 }
148
152 static constexpr bool hasPolymorphicValid()
153 {
154 return BaseImpl::hasValid() && (!ImplOptions::HasNoValidImpl);
155 }
156
160 static constexpr bool hasPolymorphicLength()
161 {
162 return BaseImpl::hasLength() && (!ImplOptions::HasNoLengthImpl);
163 }
164
168 static constexpr bool hasPolymorphicDispatch()
169 {
170 return BaseImpl::hasDispatch() && (!ImplOptions::HasNoDispatchImpl);
171 }
172
176 static constexpr bool hasCustomRefresh()
177 {
178 return ImplOptions::HasCustomRefresh;
179 }
180
184 static constexpr bool hasCustomName()
185 {
186 return ImplOptions::HasName;
187 }
188
190 static constexpr bool hasDoGetId()
191 {
192 return ImplOptions::HasStaticMsgId || ImplOptions::HasDoGetId;
193 }
194
195#ifdef FOR_DOXYGEN_DOC_ONLY
196
200 using AllFields = FieldsProvidedWithOption;
201
207
212 const AllFields& fields() const;
213
219 static constexpr bool areFieldsVersionDependent();
220
225 static constexpr MsgIdParamType doGetId();
226
244 template <typename TIter>
245 ErrorStatus doRead(TIter& iter, std::size_t size);
246
265 template <typename TIter>
266 ErrorStatus doWrite(TIter& iter, std::size_t size) const;
267
279 bool doValid() const;
280
294 bool doRefresh() const;
295
309 std::size_t doLength() const;
310
317 template <std::size_t TFromIdx>
318 std::size_t doLengthFrom() const;
319
328 template <std::size_t TUntilIdx>
329 std::size_t doLengthUntil() const;
330
344 template <std::size_t TFromIdx, std::size_t TUntilIdx>
345 std::size_t doLengthFromUntil() const;
346
356 static constexpr std::size_t doMinLength();
357
364 template <std::size_t TFromIdx>
365 static constexpr std::size_t doMinLengthFrom();
366
375 template <std::size_t TUntilIdx>
376 static constexpr std::size_t doMinLengthUntil();
377
391 template <std::size_t TFromIdx, std::size_t TUntilIdx>
392 std::size_t doMinLengthFromUntil() const;
393
403 static constexpr std::size_t doMaxLength();
404
411 template <std::size_t TFromIdx>
412 static constexpr std::size_t doMaxLengthFrom();
413
422 template <std::size_t TUntilIdx>
423 static constexpr std::size_t doMaxLengthUntil();
424
438 template <std::size_t TFromIdx, std::size_t TUntilIdx>
439 std::size_t doMaxLengthFromUntil() const;
440
452
453#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
454
455protected:
456 ~MessageBase() noexcept = default;
457
458#ifdef FOR_DOXYGEN_DOC_ONLY
473 virtual MsgIdParamType getIdImpl() const override;
474
541 virtual DispatchRetType dispatchImpl(Handler& handler) override;
542
556 virtual ErrorStatus readImpl(ReadIterator& iter, std::size_t size) override;
557
578 template <std::size_t TIdx, typename TIter>
579 ErrorStatus doReadUntil(TIter& iter, std::size_t& len);
580
584 template <std::size_t TIdx, typename TIter>
585 ErrorStatus doReadUntilAndUpdateLen(TIter& iter, std::size_t& len);
586
598 template <std::size_t TIdx, typename TIter>
599 void doReadNoStatusUntil(TIter& iter);
600
622 template <std::size_t TIdx, typename TIter>
623 ErrorStatus doReadFrom(TIter& iter, std::size_t len);
624
628 template <std::size_t TIdx, typename TIter>
629 ErrorStatus doReadFromAndUpdateLen(TIter& iter, std::size_t& len);
630
642 template <std::size_t TIdx, typename TIter>
643 void doReadNoStatusFrom(TIter& iter);
644
665 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
666 ErrorStatus doReadFromUntil(TIter& iter, std::size_t len);
667
671 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
672 ErrorStatus doReadFromUntilAndUpdateLen(TIter& iter, std::size_t& len);
673
686 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
687 void doReadNoStatusFromUntil(TIter& iter);
688
702 virtual ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const override;
703
719 template <std::size_t TIdx, typename TIter>
720 ErrorStatus doWriteUntil(TIter& iter, std::size_t len) const;
721
723 template <std::size_t TIdx, typename TIter>
724 ErrorStatus doWriteUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
725
737 template <std::size_t TIdx, typename TIter>
738 void doWriteNoStatusUntil(TIter& iter) const;
739
754 template <std::size_t TIdx, typename TIter>
755 ErrorStatus doWriteFrom(TIter& iter, std::size_t len) const;
756
758 template <std::size_t TIdx, typename TIter>
759 ErrorStatus doWriteFromAndUpdateLen(TIter& iter, std::size_t& len) const;
760
770 template <std::size_t TIdx, typename TIter>
771 void doWriteNoStatusFrom(TIter& iter) const;
772
789 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
790 ErrorStatus doWriteFromUntil(TIter& iter, std::size_t len) const;
791
793 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
794 ErrorStatus doWriteFromUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
795
808 template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
809 void doWriteNoStatusFromUntil(TIter& iter) const;
810
821 virtual bool validImpl() const override;
822
834 virtual std::size_t lengthImpl() const override;
835
848 virtual bool refreshImpl() override;
849
858 virtual const char* nameImpl() const override;
859
860#endif // #ifdef FOR_DOXYGEN_DOC_ONLY
861};
862
866template <typename TMessage1, typename TMessage2, typename... TOptions>
868{
869 return msg1.fields() == msg2.fields();
870}
871
875template <typename TMessage1, typename TMessage2, typename... TOptions>
877{
878 return !(msg1 == msg2);
879}
880
883template <typename TMessage, typename... TOptions>
884inline
886{
887 return msg;
888}
889
892template <typename TMessage, typename... TOptions>
893inline
894const MessageBase<TMessage, TOptions...>& toMessageBase(
896{
897 return msg;
898}
899
904template <typename T>
905constexpr bool isMessageBase()
906{
907 return details::hasImplOptions<T>();
908}
909
910} // namespace comms
911
920#define COMMS_MSG_FIELDS_ACCESS(...) \
921 COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
922 COMMS_MSG_FIELDS_ACCESS_FUNC { \
923 auto& val = comms::toMessageBase(*this).fields(); \
924 using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
925 static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
926 "Invalid number of names for fields tuple"); \
927 return val; \
928 } \
929 COMMS_MSG_FIELDS_ACCESS_CONST_FUNC { \
930 auto& val = comms::toMessageBase(*this).fields(); \
931 using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
932 static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
933 "Invalid number of names for fields tuple"); \
934 return val; \
935 } \
936 COMMS_EXPAND(COMMS_DO_FIELD_ACC_FUNC(AllFields, fields(), __VA_ARGS__))
937
1072#define COMMS_MSG_FIELDS_NAMES(...) \
1073 COMMS_EXPAND(COMMS_MSG_FIELDS_ACCESS(__VA_ARGS__)) \
1074 COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::AllFields, Field_, FieldIdx_, __VA_ARGS__))
1075
1088#define COMMS_MSG_FIELD_ALIAS_ACCESS(f_, ...) COMMS_DO_ALIAS(field_, f_, __VA_ARGS__)
1089
1190#define COMMS_MSG_FIELD_ALIAS(f_, ...) \
1191 COMMS_EXPAND(COMMS_MSG_FIELD_ALIAS_ACCESS(f_, __VA_ARGS__)) \
1192 COMMS_EXPAND(COMMS_DO_ALIAS_TYPEDEF(Field_, f_, __VA_ARGS__))
Base class for all the custom protocol messages.
Definition MessageBase.h:83
bool operator!=(const MessageBase< TMessage1, TOptions... > &msg1, const MessageBase< TMessage2, TOptions... > &msg2) noexcept
Message object inequality comparison operator.
Definition MessageBase.h:876
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:200
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:107
static constexpr bool hasPolymorphicDispatch()
Compile time inquiry of whether polymoriphic dispatch has been requested via interface options and ha...
Definition MessageBase.h:168
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:176
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:190
static constexpr bool hasPolymorphicWrite()
Compile time inquiry of whether polymoriphic write has been requested via interface options and hasn'...
Definition MessageBase.h:144
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:88
static constexpr bool hasCustomName()
Compile time inquiry of whether comms::MessageBase has notified about custom name retrieval function ...
Definition MessageBase.h:184
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:136
static constexpr bool hasFailOnInvalid()
Compile time inquiry of whether fail on invalid has been requested comms::option::def::FailOnInvalid ...
Definition MessageBase.h:121
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:94
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:98
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:160
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:152
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:128
bool operator==(const MessageBase< TMessage1, TOptions... > &msg1, const MessageBase< TMessage2, TOptions... > &msg2) noexcept
Message object equality comparison operator.
Definition MessageBase.h:867
static constexpr bool hasFields()
Compile type inquiry whether fields have been provided via comms::option::def::FieldsImpl.
Definition MessageBase.h:114
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:306
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
typename BaseImpl::MsgIdParamType MsgIdParamType
Type used for message ID passed as parameter or returned from function.
Definition Message.h:202
TypeProvidedWithOption WriteIterator
Type of the iterator used for writing message contents into sequence of bytes stored somewhere.
Definition Message.h:249
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
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:885
constexpr bool isMessageBase()
Compile time check of of whether the type is a message extending comms::MessageBase.
Definition MessageBase.h:905