COMMS
Template library intended to help with implementation of communication protocols.
MessageBase.h
Go to the documentation of this file.
1 //
2 // Copyright 2014 - 2024 (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/MessageImplBuilder.h"
14 #include "comms/details/macro_common.h"
15 #include "comms/details/fields_access.h"
16 #include "comms/details/detect.h"
17 #include "comms/details/field_alias.h"
18 
19 namespace comms
20 {
21 
81 template <typename TMessage, typename... TOptions>
82 class MessageBase : public details::MessageImplBuilderT<TMessage, TOptions...>
83 {
84  using BaseImpl = details::MessageImplBuilderT<TMessage, TOptions...>;
85 public:
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  {
179  }
180 
184  static constexpr bool hasCustomName()
185  {
186  return ImplOptions::HasName;
187  }
188 
189 #ifdef FOR_DOXYGEN_DOC_ONLY
190 
194  using AllFields = FieldsProvidedWithOption;
195 
201 
206  const AllFields& fields() const;
207 
213  static constexpr bool areFieldsVersionDependent();
214 
219  static constexpr MsgIdParamType doGetId();
220 
238  template <typename TIter>
239  ErrorStatus doRead(TIter& iter, std::size_t size);
240 
259  template <typename TIter>
260  ErrorStatus doWrite(TIter& iter, std::size_t size) const;
261 
273  bool doValid() const;
274 
288  bool doRefresh() const;
289 
303  std::size_t doLength() const;
304 
311  template <std::size_t TFromIdx>
312  std::size_t doLengthFrom() const;
313 
322  template <std::size_t TUntilIdx>
323  std::size_t doLengthUntil() const;
324 
338  template <std::size_t TFromIdx, std::size_t TUntilIdx>
339  std::size_t doLengthFromUntil() const;
340 
350  static constexpr std::size_t doMinLength();
351 
358  template <std::size_t TFromIdx>
359  static constexpr std::size_t doMinLengthFrom();
360 
369  template <std::size_t TUntilIdx>
370  static constexpr std::size_t doMinLengthUntil();
371 
385  template <std::size_t TFromIdx, std::size_t TUntilIdx>
386  std::size_t doMinLengthFromUntil() const;
387 
397  static constexpr std::size_t doMaxLength();
398 
405  template <std::size_t TFromIdx>
406  static constexpr std::size_t doMaxLengthFrom();
407 
416  template <std::size_t TUntilIdx>
417  static constexpr std::size_t doMaxLengthUntil();
418 
432  template <std::size_t TFromIdx, std::size_t TUntilIdx>
433  std::size_t doMaxLengthFromUntil() const;
434 
446 
447 #endif // #ifdef FOR_DOXYGEN_DOC_ONLY
448 
449 protected:
450  ~MessageBase() noexcept = default;
451 
452 #ifdef FOR_DOXYGEN_DOC_ONLY
467  virtual MsgIdParamType getIdImpl() const override;
468 
535  virtual DispatchRetType dispatchImpl(Handler& handler) override;
536 
550  virtual ErrorStatus readImpl(ReadIterator& iter, std::size_t size) override;
551 
572  template <std::size_t TIdx, typename TIter>
573  ErrorStatus doReadUntil(TIter& iter, std::size_t& len);
574 
578  template <std::size_t TIdx, typename TIter>
579  ErrorStatus doReadUntilAndUpdateLen(TIter& iter, std::size_t& len);
580 
592  template <std::size_t TIdx, typename TIter>
593  void doReadNoStatusUntil(TIter& iter);
594 
616  template <std::size_t TIdx, typename TIter>
617  ErrorStatus doReadFrom(TIter& iter, std::size_t len);
618 
622  template <std::size_t TIdx, typename TIter>
623  ErrorStatus doReadFromAndUpdateLen(TIter& iter, std::size_t& len);
624 
636  template <std::size_t TIdx, typename TIter>
637  void doReadNoStatusFrom(TIter& iter);
638 
659  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
660  ErrorStatus doReadFromUntil(TIter& iter, std::size_t len);
661 
665  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
666  ErrorStatus doReadFromUntilAndUpdateLen(TIter& iter, std::size_t& len);
667 
680  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
681  void doReadNoStatusFromUntil(TIter& iter);
682 
696  virtual ErrorStatus writeImpl(WriteIterator& iter, std::size_t size) const override;
697 
713  template <std::size_t TIdx, typename TIter>
714  ErrorStatus doWriteUntil(TIter& iter, std::size_t len) const;
715 
717  template <std::size_t TIdx, typename TIter>
718  ErrorStatus doWriteUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
719 
731  template <std::size_t TIdx, typename TIter>
732  void doWriteNoStatusUntil(TIter& iter) const;
733 
748  template <std::size_t TIdx, typename TIter>
749  ErrorStatus doWriteFrom(TIter& iter, std::size_t len) const;
750 
752  template <std::size_t TIdx, typename TIter>
753  ErrorStatus doWriteFromAndUpdateLen(TIter& iter, std::size_t& len) const;
754 
764  template <std::size_t TIdx, typename TIter>
765  void doWriteNoStatusFrom(TIter& iter) const;
766 
783  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
784  ErrorStatus doWriteFromUntil(TIter& iter, std::size_t len) const;
785 
787  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
788  ErrorStatus doWriteFromUntilAndUpdateLen(TIter& iter, std::size_t& len) const;
789 
802  template <std::size_t TFromIdx, std::size_t TUntilIdx, typename TIter>
803  void doWriteNoStatusFromUntil(TIter& iter) const;
804 
815  virtual bool validImpl() const override;
816 
828  virtual std::size_t lengthImpl() const override;
829 
842  virtual bool refreshImpl() override;
843 
852  virtual const char* nameImpl() const override;
853 
854 #endif // #ifdef FOR_DOXYGEN_DOC_ONLY
855 };
856 
860 template <typename TMessage1, typename TMessage2, typename... TOptions>
862 {
863  return msg1.fields() == msg2.fields();
864 }
865 
869 template <typename TMessage1, typename TMessage2, typename... TOptions>
871 {
872  return !(msg1 == msg2);
873 }
874 
877 template <typename TMessage, typename... TOptions>
878 inline
880 {
881  return msg;
882 }
883 
886 template <typename TMessage, typename... TOptions>
887 inline
888 const MessageBase<TMessage, TOptions...>& toMessageBase(
890 {
891  return msg;
892 }
893 
898 template <typename T>
899 constexpr bool isMessageBase()
900 {
901  return details::hasImplOptions<T>();
902 }
903 
904 } // namespace comms
905 
914 #define COMMS_MSG_FIELDS_ACCESS(...) \
915  COMMS_EXPAND(COMMS_DEFINE_FIELD_ENUM(__VA_ARGS__)) \
916  COMMS_MSG_FIELDS_ACCESS_FUNC { \
917  auto& val = comms::toMessageBase(*this).fields(); \
918  using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
919  static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
920  "Invalid number of names for fields tuple"); \
921  return val; \
922  } \
923  COMMS_MSG_FIELDS_ACCESS_CONST_FUNC { \
924  auto& val = comms::toMessageBase(*this).fields(); \
925  using AllFieldsTuple = typename std::decay<decltype(val)>::type; \
926  static_assert(std::tuple_size<AllFieldsTuple>::value == FieldIdx_numOfValues, \
927  "Invalid number of names for fields tuple"); \
928  return val; \
929  } \
930  COMMS_EXPAND(COMMS_DO_FIELD_ACC_FUNC(AllFields, fields(), __VA_ARGS__))
931 
1066 #define COMMS_MSG_FIELDS_NAMES(...) \
1067  COMMS_EXPAND(COMMS_MSG_FIELDS_ACCESS(__VA_ARGS__)) \
1068  COMMS_EXPAND(COMMS_DO_FIELD_TYPEDEF(typename Base::AllFields, Field_, FieldIdx_, __VA_ARGS__))
1069 
1082 #define COMMS_MSG_FIELD_ALIAS_ACCESS(f_, ...) COMMS_DO_ALIAS(field_, f_, __VA_ARGS__)
1083 
1184 #define COMMS_MSG_FIELD_ALIAS(f_, ...) \
1185  COMMS_EXPAND(COMMS_MSG_FIELD_ALIAS_ACCESS(f_, __VA_ARGS__)) \
1186  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:870
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:194
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.
const AllFields & fields() const
Get an access to the fields of the message.
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.
virtual const char * nameImpl() const override
Implementation of polymorphic name retrieval 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.
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.
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:861
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.
AllFields & fields()
Get an access to the fields of the message.
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.
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
comms::option::def::HasName HasName
Same as comms::option::def::HasName.
Definition: options.h:1786
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition: options.h:1459
comms::option::def::HasCustomRefresh HasCustomRefresh
Same as comms::option::def::HasCustomRefresh.
Definition: options.h:1783
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:879
constexpr bool isMessageBase()
Compile time check of of whether the type is a message extending comms::MessageBase.
Definition: MessageBase.h:899