20#include "comms/details/detect.h"
21#include "comms/details/tag.h"
40template <
typename... TExtraOpts>
128 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
133 TExtraValues... extraValues)
135 using MsgType =
typename std::decay<
decltype(msg)>::type;
138 comms::isMessageBase<MsgType>()
142 comms::isMessage<MsgType>()
145 typename comms::util::LazyShallowConditional<
146 std::is_pointer<MsgType>::value
154 if (setPayloadRequiredInternal(extraValues...)) {
155 auto fromIter = iter;
156 auto es = readInternal(msg, iter, size, Tag(), extraValues...);
157 setMsgPayloadInternal(fromIter,
static_cast<std::size_t
>(std::distance(fromIter, iter)), extraValues...);
161 return readInternal(msg, iter, size, Tag(), extraValues...);
167 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
174 static_cast<void>(msg);
175 static_cast<void>(iter);
176 static_cast<void>(size);
184 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
189 TExtraValues... extraValues)
191 return read(msg, iter, size, extraValues...);
218 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
220 TAllFields& allFields,
224 TExtraValues... extraValues)
228 "Expected TAllFields to be tuple.");
230 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
231 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
232 static const std::size_t Idx =
233 std::tuple_size<AllFieldsDecayed>::value -
234 std::tuple_size<AllFields>::value;
236 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
237 "All fields must be read when MsgDataLayer is reached");
239 using IterType =
typename std::decay<
decltype(iter)>::type;
240 using IterTag =
typename std::iterator_traits<IterType>::iterator_category;
241 static_assert(std::is_base_of<std::random_access_iterator_tag, IterTag>::value,
242 "Caching read from non random access iterators are not supported at this moment.");
244 auto& dataField = std::get<Idx>(allFields);
246 using FieldType =
typename std::decay<
decltype(dataField)>::type;
248 std::is_same<Field, FieldType>::value,
249 "Field has wrong type");
251 auto dataIter = iter;
252 auto es =
read(msg, iter, size, extraValues...);
257 auto dataSize =
static_cast<std::size_t
>(std::distance(dataIter, iter));
258 setMsgPayloadInternal(dataIter, dataSize, extraValues...);
260 auto dataEs = dataField.read(dataIter, dataSize);
261 static_cast<void>(dataEs);
269 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
271 TAllFields& allFields,
277 static_cast<void>(allFields);
278 static_cast<void>(msg);
279 static_cast<void>(iter);
280 static_cast<void>(size);
288 template <
typename TAllFields,
typename TMsg,
typename TIter,
typename... TExtraValues>
290 TAllFields& allFields,
294 TExtraValues... extraValues)
316 template <
typename TMsg,
typename TIter>
322 using MsgType =
typename std::decay<
decltype(msg)>::type;
325 comms::isMessage<MsgType>(),
326 "The provided message object must inherit from comms::Message");
330 comms::isMessageBase<MsgType>()
334 comms::isMessage<MsgType>()
337 typename comms::util::LazyShallowConditional<
338 std::is_pointer<MsgType>::value
346 return writeInternal(msg, iter, size, Tag());
364 template <
typename TAllFields,
typename TMsg,
typename TIter>
366 TAllFields& allFields,
372 "Expected TAllFields to be tuple.");
374 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
375 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
376 static const std::size_t Idx =
377 std::tuple_size<AllFieldsDecayed>::value -
378 std::tuple_size<AllFields>::value;
380 static_assert((Idx + 1) == std::tuple_size<TAllFields>::value,
381 "All fields must be written when MsgDataLayer is reached");
383 auto& dataField = std::get<Idx>(allFields);
384 using FieldType =
typename std::decay<
decltype(dataField)>::type;
386 std::is_same<Field, FieldType>::value,
387 "Field has wrong type");
389 using IterType =
typename std::decay<
decltype(iter)>::type;
390 using IterTag =
typename std::iterator_traits<IterType>::iterator_category;
391 return writeWithFieldCachedInternal(dataField, msg, iter, size, IterTag());
407 template <
typename TIter>
410 std::advance(iter, size);
420 template <
typename TMsg,
typename TIter>
423 static_cast<void>(msg);
424 return update(iter, size);
440 template <
typename TAllFields,
typename TIter>
442 TAllFields& allFields,
446 static_cast<void>(allFields);
447 std::advance(iter, size);
466 template <
typename TAllFields,
typename TMsg,
typename TIter>
468 TAllFields& allFields,
473 static_cast<void>(allFields);
474 static_cast<void>(msg);
475 std::advance(iter, size);
497 template <
typename TMsg>
498 static constexpr std::size_t
length(
const TMsg& msg)
500 using MsgType =
typename std::decay<
decltype(msg)>::type;
503 comms::isMessage<MsgType>(),
504 "The provided message object must inherit from comms::Message");
507 typename comms::util::LazyShallowConditional<
508 details::ProtocolLayerHasFieldsImpl<MsgType>::Value
513 return getMsgLength(msg, Tag());
520 template <
typename TAllFields>
522 decltype(std::get<std::tuple_size<typename std::decay<TAllFields>::type>::value - std::tuple_size<AllFields>::value>(allFields))
524 using AllFieldsDecayed =
typename std::decay<TAllFields>::type;
525 static_assert(util::tupleIsTailOf<AllFields, AllFieldsDecayed>(),
"Passed tuple is wrong.");
526 static const std::size_t Idx =
527 std::tuple_size<AllFieldsDecayed>::value -
528 std::tuple_size<AllFields>::value;
530 return std::get<Idx>(allFields);
534 template <
typename... TParams>
535 using MsgHasLengthTag = comms::details::tag::Tag1<>;
537 template <
typename... TParams>
538 using MsgNoLengthTag = comms::details::tag::Tag2<>;
540 template <
typename... TParams>
541 using MsgDirectLengthTag = comms::details::tag::Tag3<>;
543 template <
typename... TParams>
544 using DirectOpTag = comms::details::tag::Tag4<>;
546 template <
typename... TParams>
547 using InterfaceOpTag = comms::details::tag::Tag5<>;
549 template <
typename... TParams>
550 using PointerOpTag = comms::details::tag::Tag6<>;
552 template <
typename... TParams>
553 using OtherOpTag = comms::details::tag::Tag7<>;
555 template <
typename TMsg,
typename TIter>
561 std::random_access_iterator_tag)
563 return writeWithFieldCachedRandomAccess(field, msg, iter, size);
566 template <
typename TMsg,
typename TIter>
572 std::output_iterator_tag)
574 return writeWithFieldCachedOutput(field, msg, iter, size);
577 template <
typename TMsg,
typename TIter>
578 static ErrorStatus writeWithFieldCachedRandomAccess(
584 auto dataReadIter = iter;
585 auto es =
write(msg, iter, size);
590 auto writtenCount =
static_cast<std::size_t
>(std::distance(dataReadIter, iter));
591 auto dataEs = field.read(dataReadIter, writtenCount);
593 static_cast<void>(dataEs);
597 template <
typename TMsg,
typename TCollection>
601 std::back_insert_iterator<TCollection>& iter,
604 auto es =
write(msg, iter, size);
610 auto dataWriteIter = std::back_inserter(col);
611 auto dataWriteEs =
write(msg, dataWriteIter, size);
613 static_cast<void>(dataWriteEs);
615 auto dataReadIter = col.cbegin();
616 auto dataReadEs = field.read(dataReadIter, col.size());
618 static_cast<void>(dataReadEs);
623 template <
typename TMsg,
typename... TParams>
624 static std::size_t getMsgLength(
const TMsg& msg, MsgHasLengthTag<TParams...>)
626 using MsgType =
typename std::decay<
decltype(msg)>::type;
627 static_assert(MsgType::hasLength(),
"Message interface must define length()");
631 template <
typename TMsg,
typename... TParams>
632 static constexpr std::size_t getMsgLength(
const TMsg& msg, MsgDirectLengthTag<TParams...>)
634 using MsgType =
typename std::decay<
decltype(msg)>::type;
635 static_assert(MsgType::hasFields(),
"FieldsImpl option hasn't been used");
636 return msg.doLength();
639 template <
typename TMsg,
typename... TParams>
640 static constexpr std::size_t getMsgLength(
const TMsg&, MsgNoLengthTag<TParams...>)
645 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
650 TExtraValues... extraValues)
652 using MsgType =
typename std::decay<
decltype(msg)>::type;
655 comms::isMessage<MsgType>(),
656 "The provided message object must inherit from comms::Message");
658 static_assert(MsgType::hasRead(),
659 "Message interface must support polymorphic read operation");
661 using IterType =
typename std::decay<
decltype(iter)>::type;
663 static_assert(std::is_convertible<IterType, typename MsgType::ReadIterator>::value,
664 "The provided iterator is not convertible to ReadIterator defined by Message class");
666 using ReadIter =
typename std::add_lvalue_reference<typename MsgType::ReadIterator>::type;
668 auto result = msg.read(
static_cast<ReadIter
>(iter), size);
670 missingSizeRequiredInternal(extraValues...)) {
672 typename comms::util::LazyShallowConditional<
680 auto msgLen = getMsgLength(msg, Tag());
684 updateMissingSizeInternal(
missingSize, extraValues...);
689 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
694 TExtraValues... extraValues)
696 using MsgType =
typename std::decay<
decltype(msg)>::type;
699 comms::isMessageBase<MsgType>(),
700 "The provided message object must inherit from comms::MessageBase");
702 static_assert(details::protocolLayerHasFieldsImpl<MsgType>(),
703 "Message class must use FieldsImpl option");
705 auto result = msg.doRead(iter, size);
707 (missingSizeRequiredInternal(extraValues...))) {
709 auto msgLen = getMsgLength(msg, MsgDirectLengthTag<>());
713 updateMissingSizeInternal(
missingSize, extraValues...);
718 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
724 TExtraValues... extraValues)
726 return readInternalDirect(msg, iter, size, extraValues...);
729 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
735 TExtraValues... extraValues)
737 static_assert(comms::isMessage<TMsg>(),
"Must be interface class");
738 static_assert(TMsg::hasRead(),
739 "Message interface must support polymorphic read operation");
741 return readInternalPolymorphic(msg, iter, size, extraValues...);
744 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
750 TExtraValues... extraValues)
752 return read(*msg, iter, size, extraValues...);
755 template <
typename TMsg,
typename TIter,
typename... TExtraValues>
761 TExtraValues... extraValues)
763 using MsgType =
typename std::decay<
decltype(msg)>::type;
764 static_assert(comms::details::hasElementType<MsgType>(),
765 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
766 return read(*msg, iter, size, extraValues...);
769 template <
typename TMsg,
typename TIter,
typename... TParams>
774 DirectOpTag<TParams...>)
776 return msg.doWrite(iter, size);
779 template <
typename TMsg,
typename TIter,
typename... TParams>
784 InterfaceOpTag<TParams...>)
786 using MsgType =
typename std::decay<
decltype(msg)>::type;
788 static_assert(MsgType::hasWrite(),
789 "Message interface must support polymorphic write operation");
791 using IterType =
typename std::decay<
decltype(iter)>::type;
793 static_assert(std::is_convertible<IterType, typename MsgType::WriteIterator>::value,
794 "The provided iterator is not convertible to WriteIterator defined by Message class");
796 using WriteIter =
typename std::add_lvalue_reference<typename MsgType::WriteIterator>::type;
798 return msg.write(
static_cast<WriteIter
>(iter), size);
801 template <
typename TMsg,
typename TIter,
typename... TParams>
806 PointerOpTag<TParams...>)
808 return write(*msg, iter, size);
811 template <
typename TMsg,
typename TIter,
typename... TParams>
816 OtherOpTag<TParams...>)
818 using MsgType =
typename std::decay<
decltype(msg)>::type;
819 static_assert(comms::details::hasElementType<MsgType>(),
820 "Unsupported type of message object, expected to be either message itself, raw pointer or smart pointer");
822 return write(*msg, iter, size);
825 static constexpr bool missingSizeRequiredInternal()
830 template <
typename... TExtraValues>
831 static bool missingSizeRequiredInternal(details::MissingSizeRetriever<>, TExtraValues...)
836 template <
typename T,
typename... TExtraValues>
837 static bool missingSizeRequiredInternal(T, TExtraValues... extraValues)
840 !details::isMissingSizeRetriever<T>(),
841 "Mustn't be missing size retriever");
842 return missingSizeRequiredInternal(extraValues...);
845 static void updateMissingSizeInternal(std::size_t val)
847 static_cast<void>(val);
850 template <
typename... TExtraValues>
851 static void updateMissingSizeInternal(
853 details::MissingSizeRetriever<> retriever,
854 TExtraValues... extraValues)
856 retriever.setValue(val);
857 updateMissingSizeInternal(val, extraValues...);
860 template <
typename T,
typename... TExtraValues>
861 static void updateMissingSizeInternal(std::size_t val, T retriever, TExtraValues... extraValues)
863 static_cast<void>(retriever);
865 !details::isMissingSizeRetriever<
typename std::decay<
decltype(retriever)>::type>(),
866 "Mustn't be missing size retriever");
867 updateMissingSizeInternal(val, extraValues...);
870 static constexpr bool setPayloadRequiredInternal()
875 template <
typename TIter,
typename... TExtraValues>
876 static bool setPayloadRequiredInternal(details::MsgPayloadRetriever<TIter>, TExtraValues...)
881 template <
typename T,
typename... TExtraValues>
882 static bool setPayloadRequiredInternal(T, TExtraValues... extraValues)
885 !details::isMsgPayloadRetriever<T>(),
886 "Mustn't be message payload retriever");
887 return setPayloadRequiredInternal(extraValues...);
890 template <
typename TIter>
891 static void setMsgPayloadInternal(TIter iter, std::size_t len)
893 static_cast<void>(iter);
894 static_cast<void>(len);
897 template <
typename TIter,
typename TOtherIter,
typename... TExtraValues>
898 static void setMsgPayloadInternal(
901 details::MsgPayloadRetriever<TOtherIter> retriever,
902 TExtraValues... extraValues)
904 retriever.setValue(iter, len);
905 setMsgPayloadInternal(iter, len, extraValues...);
908 template <
typename TIter,
typename T,
typename... TExtraValues>
909 static void setMsgPayloadInternal(
913 TExtraValues... extraValues)
915 static_cast<void>(retriever);
917 !details::isMsgPayloadRetriever<
typename std::decay<
decltype(retriever)>::type>(),
918 "Mustn't be message payload retriever");
919 setMsgPayloadInternal(iter, len, extraValues...);
926struct MsgDataLayerCheckHelper
928 static const bool Value =
false;
931template <
typename... TExtraOpts>
932struct MsgDataLayerCheckHelper<MsgDataLayer<TExtraOpts...> >
934 static const bool Value =
true;
945 return details::MsgDataLayerCheckHelper<T>::Value;
948template <
typename... TExtraOpts>
956template <
typename... TExtraOpts>
958const MsgDataLayer<TExtraOpts...>&
959toProtocolLayerBase(
const MsgDataLayer<TExtraOpts...>& layer)
Contains definition of comms::field::ArrayList.
This file contains classes required for generic custom assertion functionality.
#define COMMS_ASSERT(expr)
Generic assert macro.
Definition Assert.h:170
Contains definition of comms::Field class.
Contains definition of comms::field::IntValue.
Provides common base class for the custom messages with default implementation.
Contains definition of Message object interface and various base classes for custom messages.
Contains definition of comms::protocol::ProtocolLayerBase.
Contains various tuple type manipulation classes and functions.
Base class to all the field classes.
Definition Field.h:33
Field that represents a sequential collection of fields.
Definition ArrayList.h:192
Message data layer.
Definition MsgDataLayer.h:42
static comms::ErrorStatus update(TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:408
constexpr bool isMsgDataLayer()
Compile time check of whether the provided type is a variant of MsgDataLayer.
Definition MsgDataLayer.h:943
static auto accessCachedField(TAllFields &allFields) -> decltype(std::get< std::tuple_size< typename std::decay< TAllFields >::type >::value - std::tuple_size< AllFields >::value >(allFields))
Access appropriate field from "cached" bundle of all the protocol stack fields.
Definition MsgDataLayer.h:521
static ErrorStatus readFromDataFeildsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as readFieldsCached().
Definition MsgDataLayer.h:289
static ErrorStatus readFromData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Same as read().
Definition MsgDataLayer.h:185
ThisLayer & thisLayer()
Get access to this layer object.
Definition MsgDataLayer.h:48
MsgDataLayer(MsgDataLayer &&)=default
Move constructor.
static constexpr std::size_t length(const TMsg &msg)
Get remaining length of wrapping transport information + length of the provided message.
Definition MsgDataLayer.h:498
static ErrorStatus updateFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:467
const ThisLayer & thisLayer() const
Get "const" access to this layer object.
Definition MsgDataLayer.h:54
void AllMessages
Default value of AllMessages type.
Definition MsgDataLayer.h:74
static const std::size_t NumOfLayers
Static constant indicating amount of transport layers used.
Definition MsgDataLayer.h:81
void MsgFactory
Default value of MsgFactory type.
Definition MsgDataLayer.h:78
static ErrorStatus read(TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents.
Definition MsgDataLayer.h:129
std::tuple< Field > AllFields
All fields of the remaining transport layers, contains only Field.
Definition MsgDataLayer.h:70
static constexpr bool canSplitRead()
Compile time check whether split read "until" and "from" data layer is allowed.
Definition MsgDataLayer.h:104
static ErrorStatus write(const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents.
Definition MsgDataLayer.h:317
static ErrorStatus readUntilData(TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields until data layer.
Definition MsgDataLayer.h:168
MsgDataLayer()=default
Default constructor.
comms::field::ArrayList< comms::Field< comms::option::def::BigEndian >, std::uint8_t, TExtraOpts... > Field
Raw data field type.
Definition MsgDataLayer.h:67
static comms::ErrorStatus update(const TMsg &msg, TIter &iter, std::size_t size)
Update recently written (using write()) message contents data.
Definition MsgDataLayer.h:421
static ErrorStatus readFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues... extraValues)
Read the message contents while caching the read transport information fields.
Definition MsgDataLayer.h:219
static ErrorStatus updateFieldsCached(TAllFields &allFields, TIter &iter, std::size_t size)
Update recently written (using writeFieldsCached()) message data as well as cached transport informat...
Definition MsgDataLayer.h:441
static ErrorStatus writeFieldsCached(TAllFields &allFields, const TMsg &msg, TIter &iter, std::size_t size)
Write the message contents while caching the written transport information fields.
Definition MsgDataLayer.h:365
static ErrorStatus readUntilDataFieldsCached(TAllFields &allFields, TMsg &msg, TIter &iter, std::size_t size, TExtraValues...)
Read transport fields with caching until data layer.
Definition MsgDataLayer.h:270
static constexpr std::size_t length()
Get remaining length of wrapping transport information.
Definition MsgDataLayer.h:484
~MsgDataLayer() noexcept=default
Destructor.
MsgDataLayer(const MsgDataLayer &)=default
Copy constructor.
comms::option::def::MsgType< TMsg > MsgType
Same as comms::option::def::MsgType.
Definition options.h:1459
details::MissingSizeRetriever missingSize(std::size_t &val)
Add "missing size" output parameter to protocol stack's (frame's) "read" operation.
Definition ProtocolLayerBase.h:1561
Main namespace for all classes / functions of COMMS library.
ErrorStatus
Error statuses reported by the Communication module.
Definition ErrorStatus.h:17
@ Success
Used to indicate successful outcome of the operation.
Replacement to std::conditional.
Definition type_traits.h:28
Check whether provided type is a variant of std::tuple.
Definition Tuple.h:36
Replacement to some types from standard type_traits.